aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r--activerecord/test/cases/adapter_test.rb12
-rw-r--r--activerecord/test/cases/adapters/mysql/connection_test.rb26
-rw-r--r--activerecord/test/cases/adapters/mysql/reserved_word_test.rb6
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb18
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb4
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb29
-rw-r--r--activerecord/test/cases/associations/association_proxy_test.rb52
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb234
-rw-r--r--activerecord/test/cases/associations/callbacks_test.rb9
-rw-r--r--activerecord/test/cases/associations/cascaded_eager_loading_test.rb31
-rw-r--r--activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb2
-rw-r--r--activerecord/test/cases/associations/eager_load_nested_include_test.rb1
-rw-r--r--activerecord/test/cases/associations/eager_test.rb142
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb115
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb84
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb126
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb138
-rw-r--r--activerecord/test/cases/associations/has_one_through_associations_test.rb88
-rw-r--r--activerecord/test/cases/associations/inner_join_association_test.rb8
-rw-r--r--activerecord/test/cases/associations/inverse_associations_test.rb77
-rw-r--r--activerecord/test/cases/associations/join_model_test.rb71
-rw-r--r--activerecord/test/cases/associations_test.rb10
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb19
-rw-r--r--activerecord/test/cases/autosave_association_test.rb142
-rw-r--r--activerecord/test/cases/base_test.rb137
-rw-r--r--activerecord/test/cases/batches_test.rb1
-rw-r--r--activerecord/test/cases/calculations_test.rb18
-rw-r--r--activerecord/test/cases/clone_test.rb33
-rw-r--r--activerecord/test/cases/connection_pool_test.rb4
-rw-r--r--activerecord/test/cases/dirty_test.rb22
-rw-r--r--activerecord/test/cases/dup_test.rb103
-rw-r--r--activerecord/test/cases/finder_test.rb56
-rw-r--r--activerecord/test/cases/fixtures_test.rb13
-rw-r--r--activerecord/test/cases/helper.rb35
-rw-r--r--activerecord/test/cases/inheritance_test.rb10
-rw-r--r--activerecord/test/cases/invertible_migration_test.rb57
-rw-r--r--activerecord/test/cases/lifecycle_test.rb23
-rw-r--r--activerecord/test/cases/locking_test.rb53
-rw-r--r--activerecord/test/cases/method_scoping_test.rb14
-rw-r--r--activerecord/test/cases/migration/command_recorder_test.rb108
-rw-r--r--activerecord/test/cases/migration_test.rb165
-rw-r--r--activerecord/test/cases/modules_test.rb1
-rw-r--r--activerecord/test/cases/named_scope_test.rb44
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb46
-rw-r--r--activerecord/test/cases/persistence_test.rb12
-rw-r--r--activerecord/test/cases/pooled_connections_test.rb2
-rw-r--r--activerecord/test/cases/query_cache_test.rb3
-rw-r--r--activerecord/test/cases/quoting_test.rb4
-rw-r--r--activerecord/test/cases/readonly_test.rb38
-rw-r--r--activerecord/test/cases/reflection_test.rb54
-rw-r--r--activerecord/test/cases/relation_scoping_test.rb42
-rw-r--r--activerecord/test/cases/relation_test.rb139
-rw-r--r--activerecord/test/cases/relations_test.rb113
-rw-r--r--activerecord/test/cases/session_store/session_test.rb2
-rw-r--r--activerecord/test/cases/session_store/sql_bypass.rb4
-rw-r--r--activerecord/test/cases/timestamp_test.rb2
-rw-r--r--activerecord/test/cases/transactions_test.rb22
-rw-r--r--activerecord/test/cases/unconnected_test.rb3
-rw-r--r--activerecord/test/cases/validations/association_validation_test.rb4
-rw-r--r--activerecord/test/cases/validations/uniqueness_validation_test.rb17
-rw-r--r--activerecord/test/cases/xml_serialization_test.rb27
-rw-r--r--activerecord/test/cases/yaml_serialization_test.rb35
62 files changed, 2114 insertions, 796 deletions
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 646aa88d80..49b2e945c3 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -141,16 +141,4 @@ class AdapterTest < ActiveRecord::TestCase
end
end
end
-
- 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))
- 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))
- end
end
diff --git a/activerecord/test/cases/adapters/mysql/connection_test.rb b/activerecord/test/cases/adapters/mysql/connection_test.rb
index 67bd8ec7e0..62ffde558f 100644
--- a/activerecord/test/cases/adapters/mysql/connection_test.rb
+++ b/activerecord/test/cases/adapters/mysql/connection_test.rb
@@ -49,18 +49,18 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_no_binds
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- result = @connection.exec('SELECT id, data FROM ex')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @connection.exec('SELECT id, data FROM ex')
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
@@ -68,13 +68,13 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_with_binds
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @connection.exec(
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -84,15 +84,15 @@ class MysqlConnectionTest < ActiveRecord::TestCase
end
def test_exec_typecasts_bind_vals
- @connection.exec('drop table if exists ex')
- @connection.exec(<<-eosql)
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
- @connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ @connection.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
column = @connection.columns('ex').find { |col| col.name == 'id' }
- result = @connection.exec(
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/adapters/mysql/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql/reserved_word_test.rb
index 90d8b0d923..b5c938b14a 100644
--- a/activerecord/test/cases/adapters/mysql/reserved_word_test.rb
+++ b/activerecord/test/cases/adapters/mysql/reserved_word_test.rb
@@ -105,9 +105,9 @@ class MysqlReservedWordTest < ActiveRecord::TestCase
assert_nothing_raised { x.save }
x.order = 'y'
assert_nothing_raised { x.save }
- assert_nothing_raised { y = Group.find_by_order('y') }
- assert_nothing_raised { y = Group.find(1) }
- x = Group.find(1)
+ assert_nothing_raised { Group.find_by_order('y') }
+ assert_nothing_raised { Group.find(1) }
+ Group.find(1)
end
# has_one association with reserved-word table name
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index b0fd2273df..b0a4a4e39d 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -5,8 +5,8 @@ module ActiveRecord
class PostgreSQLAdapterTest < ActiveRecord::TestCase
def setup
@connection = ActiveRecord::Base.connection
- @connection.exec('drop table if exists ex')
- @connection.exec('create table ex(id serial primary key, data character varying(255))')
+ @connection.exec_query('drop table if exists ex')
+ @connection.exec_query('create table ex(id serial primary key, data character varying(255))')
end
def test_table_alias_length
@@ -16,14 +16,14 @@ module ActiveRecord
end
def test_exec_no_binds
- result = @connection.exec('SELECT id, data FROM ex')
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
- result = @connection.exec('SELECT id, data FROM ex')
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ result = @connection.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
@@ -32,8 +32,8 @@ module ActiveRecord
def test_exec_with_binds
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
- result = @connection.exec(
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = $1', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -44,10 +44,10 @@ module ActiveRecord
def test_exec_typecasts_bind_vals
string = @connection.quote('foo')
- @connection.exec("INSERT INTO ex (id, data) VALUES (1, #{string})")
+ @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
column = @connection.columns('ex').find { |col| col.name == 'id' }
- result = @connection.exec(
+ result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = $1', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
index 881631fb19..d5e1838543 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
@@ -55,7 +55,7 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase
set_session_auth
USERS.each do |u|
set_session_auth u
- assert_equal u, @connection.exec("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
+ assert_equal u, @connection.exec_query("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
set_session_auth
end
end
@@ -67,7 +67,7 @@ class SchemaAuthorizationTest < ActiveRecord::TestCase
USERS.each do |u|
@connection.clear_cache!
set_session_auth u
- assert_equal u, @connection.exec("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
+ assert_equal u, @connection.exec_query("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [[nil, 1]]).first['name']
set_session_auth
end
end
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index 973c51f3d7..b8abdface4 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -9,6 +9,11 @@ module ActiveRecord
:timeout => 100
end
+ def test_primary_key_returns_nil_for_no_pk
+ @conn.exec_query('create table ex(id int, data string)')
+ assert_nil @conn.primary_key('ex')
+ end
+
def test_connection_no_db
assert_raises(ArgumentError) do
Base.sqlite3_connection {}
@@ -58,24 +63,24 @@ module ActiveRecord
end
def test_exec_no_binds
- @conn.exec('create table ex(id int, data string)')
- result = @conn.exec('SELECT id, data FROM ex')
+ @conn.exec_query('create table ex(id int, data string)')
+ result = @conn.exec_query('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @conn.exec('SELECT id, data FROM ex')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @conn.exec_query('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
assert_equal [[1, 'foo']], result.rows
end
- def test_exec_with_binds
- @conn.exec('create table ex(id int, data string)')
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
- result = @conn.exec(
+ def test_exec_query_with_binds
+ @conn.exec_query('create table ex(id int, data string)')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ result = @conn.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]])
assert_equal 1, result.rows.length
@@ -84,12 +89,12 @@ module ActiveRecord
assert_equal [[1, 'foo']], result.rows
end
- def test_exec_typecasts_bind_vals
- @conn.exec('create table ex(id int, data string)')
- @conn.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
+ def test_exec_query_typecasts_bind_vals
+ @conn.exec_query('create table ex(id int, data string)')
+ @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")')
column = @conn.columns('ex').find { |col| col.name == 'id' }
- result = @conn.exec(
+ result = @conn.exec_query(
'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
diff --git a/activerecord/test/cases/associations/association_proxy_test.rb b/activerecord/test/cases/associations/association_proxy_test.rb
new file mode 100644
index 0000000000..55d8da4c4e
--- /dev/null
+++ b/activerecord/test/cases/associations/association_proxy_test.rb
@@ -0,0 +1,52 @@
+require "cases/helper"
+
+module ActiveRecord
+ module Associations
+ class AsssociationProxyTest < ActiveRecord::TestCase
+ class FakeOwner
+ attr_accessor :new_record
+ alias :new_record? :new_record
+
+ def initialize
+ @new_record = false
+ end
+ end
+
+ class FakeReflection < Struct.new(:options, :klass)
+ def initialize options = {}, klass = nil
+ super
+ end
+
+ def check_validity!
+ true
+ end
+ end
+
+ class FakeTarget
+ end
+
+ class FakeTargetProxy < AssociationProxy
+ def association_scope
+ true
+ end
+
+ def find_target
+ FakeTarget.new
+ end
+ end
+
+ def test_method_missing_error
+ reflection = FakeReflection.new({}, Object.new)
+ owner = FakeOwner.new
+ proxy = FakeTargetProxy.new(owner, reflection)
+
+ exception = assert_raises(NoMethodError) do
+ proxy.omg
+ end
+
+ assert_match('omg', exception.message)
+ assert_match(FakeTarget.name, exception.message)
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index cbaa4990f7..01073bca3d 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -17,7 +17,7 @@ require 'models/essay'
class BelongsToAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :topics,
:developers_projects, :computers, :authors, :author_addresses,
- :posts, :tags, :taggings, :comments
+ :posts, :tags, :taggings, :comments, :sponsors, :members
def test_belongs_to
Client.find(3).firm.name
@@ -78,20 +78,14 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
Firm.create("name" => "Apple")
Client.create("name" => "Citibank", :firm_name => "Apple")
citibank_result = Client.find(:first, :conditions => {:name => "Citibank"}, :include => :firm_with_primary_key)
- assert_not_nil citibank_result.instance_variable_get("@firm_with_primary_key")
+ assert citibank_result.association_cache.key?(:firm_with_primary_key)
end
- def test_no_unexpected_aliasing
- first_firm = companies(:first_firm)
- another_firm = companies(:another_firm)
-
- citibank = Account.create("credit_limit" => 10)
- citibank.firm = first_firm
- original_proxy = citibank.firm
- citibank.firm = another_firm
-
- assert_equal first_firm.object_id, original_proxy.target.object_id
- assert_equal another_firm.object_id, citibank.firm.target.object_id
+ def test_eager_loading_with_primary_key_as_symbol
+ Firm.create("name" => "Apple")
+ Client.create("name" => "Citibank", :firm_name => "Apple")
+ citibank_result = Client.find(:first, :conditions => {:name => "Citibank"}, :include => :firm_with_primary_key_symbols)
+ assert citibank_result.association_cache.key?(:firm_with_primary_key_symbols)
end
def test_creating_the_belonging_object
@@ -126,6 +120,23 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal apple.name, client.firm_name
end
+ def test_create!
+ client = Client.create!(:name => "Jimmy")
+ account = client.create_account!(:credit_limit => 10)
+ assert_equal account, client.account
+ assert account.persisted?
+ client.save
+ client.reload
+ assert_equal account, client.account
+ end
+
+ def test_failing_create!
+ client = Client.create!(:name => "Jimmy")
+ assert_raise(ActiveRecord::RecordInvalid) { client.create_account! }
+ assert_not_nil client.account
+ assert client.account.new_record?
+ end
+
def test_natural_assignment_to_nil
client = Client.find(3)
client.firm = nil
@@ -152,6 +163,15 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
end
+ def test_with_polymorphic_and_condition
+ sponsor = Sponsor.create
+ member = Member.create :name => "Bert"
+ sponsor.sponsorable = member
+
+ assert_equal member, sponsor.sponsorable
+ assert_nil sponsor.sponsorable_with_conditions
+ end
+
def test_with_select
assert_equal Company.find(2).firm_with_select.attributes.size, 1
assert_equal Company.find(2, :include => :firm_with_select ).firm_with_select.attributes.size, 1
@@ -168,17 +188,6 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
end
- def test_belongs_to_with_primary_key_counter
- debate = Topic.create("title" => "debate")
- assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
-
- trash = debate.replies_with_primary_key.create("title" => "blah!", "content" => "world around!")
- assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"
-
- trash.destroy
- assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
- end
-
def test_belongs_to_counter_with_assigning_nil
p = Post.find(1)
c = Comment.find(1)
@@ -191,16 +200,23 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal 1, Post.find(p.id).comments.size
end
- def test_belongs_to_with_primary_key_counter_with_assigning_nil
- debate = Topic.create("title" => "debate")
- reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate")
+ def test_belongs_to_with_primary_key_counter
+ debate = Topic.create("title" => "debate")
+ debate2 = Topic.create("title" => "debate2")
+ reply = Reply.create("title" => "blah!", "content" => "world around!", "parent_title" => "debate")
+
+ assert_equal 1, debate.reload.replies_count
+ assert_equal 0, debate2.reload.replies_count
+
+ reply.topic_with_primary_key = debate2
- assert_equal debate.title, reply.parent_title
- assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count")
+ assert_equal 0, debate.reload.replies_count
+ assert_equal 1, debate2.reload.replies_count
reply.topic_with_primary_key = nil
- assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count")
+ assert_equal 0, debate.reload.replies_count
+ assert_equal 0, debate2.reload.replies_count
end
def test_belongs_to_counter_with_reassigning
@@ -278,10 +294,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
final_cut = Client.new("name" => "Final Cut")
firm = Firm.find(1)
final_cut.firm = firm
- assert final_cut.new_record?
+ assert !final_cut.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !firm.new_record?
+ assert final_cut.persisted?
+ assert firm.persisted?
assert_equal firm, final_cut.firm
assert_equal firm, final_cut.firm(true)
end
@@ -290,10 +306,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
final_cut = Client.new("name" => "Final Cut")
firm = Firm.find(1)
final_cut.firm_with_primary_key = firm
- assert final_cut.new_record?
+ assert !final_cut.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !firm.new_record?
+ assert final_cut.persisted?
+ assert firm.persisted?
assert_equal firm, final_cut.firm_with_primary_key
assert_equal firm, final_cut.firm_with_primary_key(true)
end
@@ -304,13 +320,21 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_equal Firm.find(:first, :order => "id"), c.firm_with_basic_id
end
- def test_forgetting_the_load_when_foreign_key_enters_late
- c = Client.new
- assert_nil c.firm_with_basic_id
+ def test_setting_foreign_key_after_nil_target_loaded
+ client = Client.new
+ client.firm_with_basic_id
+ client.firm_id = 1
- c.firm_id = 1
- # sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first
- assert_equal Firm.find(:first, :order => "id"), c.firm_with_basic_id
+ assert_equal companies(:first_firm), client.firm_with_basic_id
+ end
+
+ def test_polymorphic_setting_foreign_key_after_nil_target_loaded
+ sponsor = Sponsor.new
+ sponsor.sponsorable
+ sponsor.sponsorable_id = 1
+ sponsor.sponsorable_type = "Member"
+
+ assert_equal members(:groucho), sponsor.sponsorable
end
def test_field_name_same_as_foreign_key
@@ -412,6 +436,18 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_nil sponsor.sponsorable_id
end
+ def test_assignment_updates_foreign_id_field_for_new_and_saved_records
+ client = Client.new
+ saved_firm = Firm.create :name => "Saved"
+ new_firm = Firm.new
+
+ client.firm = saved_firm
+ assert_equal saved_firm.id, client.client_of
+
+ client.firm = new_firm
+ assert_nil client.client_of
+ end
+
def test_polymorphic_assignment_with_primary_key_updates_foreign_id_field_for_new_and_saved_records
essay = Essay.new
saved_writer = Author.create(:name => "David")
@@ -479,4 +515,118 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
new_firm = accounts(:signals37).build_firm(:name => 'Apple')
assert_equal new_firm.name, "Apple"
end
+
+ def test_reassigning_the_parent_id_updates_the_object
+ client = companies(:second_client)
+
+ client.firm
+ client.firm_with_condition
+ firm_proxy = client.send(:association_instance_get, :firm)
+ firm_with_condition_proxy = client.send(:association_instance_get, :firm_with_condition)
+
+ assert !firm_proxy.stale_target?
+ assert !firm_with_condition_proxy.stale_target?
+ assert_equal companies(:first_firm), client.firm
+ assert_equal companies(:first_firm), client.firm_with_condition
+
+ client.client_of = companies(:another_firm).id
+
+ assert firm_proxy.stale_target?
+ assert firm_with_condition_proxy.stale_target?
+ assert_equal companies(:another_firm), client.firm
+ assert_equal companies(:another_firm), client.firm_with_condition
+ end
+
+ def test_polymorphic_reassignment_of_associated_id_updates_the_object
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
+
+ sponsor.sponsorable
+ proxy = sponsor.send(:association_instance_get, :sponsorable)
+
+ assert !proxy.stale_target?
+ assert_equal members(:groucho), sponsor.sponsorable
+
+ sponsor.sponsorable_id = members(:some_other_guy).id
+
+ assert proxy.stale_target?
+ assert_equal members(:some_other_guy), sponsor.sponsorable
+ end
+
+ def test_polymorphic_reassignment_of_associated_type_updates_the_object
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
+
+ sponsor.sponsorable
+ proxy = sponsor.send(:association_instance_get, :sponsorable)
+
+ assert !proxy.stale_target?
+ assert_equal members(:groucho), sponsor.sponsorable
+
+ sponsor.sponsorable_type = 'Firm'
+
+ assert proxy.stale_target?
+ assert_equal companies(:first_firm), sponsor.sponsorable
+ end
+
+ def test_reloading_association_with_key_change
+ client = companies(:second_client)
+ firm = client.firm # note this is a proxy object
+
+ client.firm = companies(:another_firm)
+ assert_equal companies(:another_firm), firm.reload
+
+ client.client_of = companies(:first_firm).id
+ assert_equal companies(:first_firm), firm.reload
+ end
+
+ def test_polymorphic_counter_cache
+ tagging = taggings(:welcome_general)
+ post = posts(:welcome)
+ comment = comments(:greetings)
+
+ assert_difference 'post.reload.taggings_count', -1 do
+ assert_difference 'comment.reload.taggings_count', +1 do
+ tagging.taggable = comment
+ end
+ end
+ end
+
+ def test_polymorphic_with_custom_foreign_type
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
+ groucho = members(:groucho)
+ other = members(:some_other_guy)
+
+ assert_equal groucho, sponsor.sponsorable
+ assert_equal groucho, sponsor.thing
+
+ sponsor.thing = other
+
+ assert_equal other, sponsor.sponsorable
+ assert_equal other, sponsor.thing
+
+ sponsor.sponsorable = groucho
+
+ assert_equal groucho, sponsor.sponsorable
+ assert_equal groucho, sponsor.thing
+ end
+
+ def test_build_with_conditions
+ client = companies(:second_client)
+ firm = client.build_bob_firm
+
+ assert_equal "Bob", firm.name
+ end
+
+ def test_create_with_conditions
+ client = companies(:second_client)
+ firm = client.create_bob_firm
+
+ assert_equal "Bob", firm.name
+ end
+
+ def test_create_bang_with_conditions
+ client = companies(:second_client)
+ firm = client.create_bob_firm!
+
+ assert_equal "Bob", firm.name
+ end
end
diff --git a/activerecord/test/cases/associations/callbacks_test.rb b/activerecord/test/cases/associations/callbacks_test.rb
index 6a30e2905b..2d0d4541b4 100644
--- a/activerecord/test/cases/associations/callbacks_test.rb
+++ b/activerecord/test/cases/associations/callbacks_test.rb
@@ -3,6 +3,7 @@ require 'models/post'
require 'models/author'
require 'models/project'
require 'models/developer'
+require 'models/company'
class AssociationCallbacksTest < ActiveRecord::TestCase
fixtures :posts, :authors, :projects, :developers
@@ -81,6 +82,14 @@ class AssociationCallbacksTest < ActiveRecord::TestCase
assert_equal callback_log, jack.post_log
end
+ def test_has_many_callbacks_for_destroy_on_parent
+ firm = Firm.create! :name => "Firm"
+ client = firm.clients.create! :name => "Client"
+ firm.destroy
+
+ assert_equal ["before_remove#{client.id}", "after_remove#{client.id}"], firm.log
+ end
+
def test_has_and_belongs_to_many_add_callback
david = developers(:david)
ar = projects(:active_record)
diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
index c7c32da9f3..0742e311d9 100644
--- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
+++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
@@ -3,13 +3,15 @@ require 'models/post'
require 'models/comment'
require 'models/author'
require 'models/categorization'
+require 'models/category'
require 'models/company'
require 'models/topic'
require 'models/reply'
require 'models/person'
class CascadedEagerLoadingTest < ActiveRecord::TestCase
- fixtures :authors, :mixins, :companies, :posts, :topics, :accounts, :comments, :categorizations, :people
+ fixtures :authors, :mixins, :companies, :posts, :topics, :accounts, :comments,
+ :categorizations, :people, :categories
def test_eager_association_loading_with_cascaded_two_levels
authors = Author.find(:all, :include=>{:posts=>:comments}, :order=>"authors.id")
@@ -45,6 +47,31 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
assert_equal people(:michael), Person.eager_load(:primary_contact => :primary_contact).where('primary_contacts_people_2.first_name = ?', 'Susan').order('people.id').first
end
+ def test_cascaded_eager_association_loading_with_join_for_count
+ categories = Category.joins(:categorizations).includes([{:posts=>:comments}, :authors])
+
+ assert_nothing_raised do
+ assert_equal 2, categories.count
+ assert_equal 2, categories.all.uniq.size # Must uniq since instantiating with inner joins will get dupes
+ end
+ end
+
+ def test_cascaded_eager_association_loading_with_duplicated_includes
+ categories = Category.includes(:categorizations).includes(:categorizations => :author).where("categorizations.id is not null")
+ assert_nothing_raised do
+ assert_equal 2, categories.count
+ assert_equal 2, categories.all.size
+ end
+ end
+
+ def test_cascaded_eager_association_loading_with_twice_includes_edge_cases
+ categories = Category.includes(:categorizations => :author).includes(:categorizations => :post).where("posts.id is not null")
+ assert_nothing_raised do
+ assert_equal 2, categories.count
+ assert_equal 2, categories.all.size
+ end
+ end
+
def test_eager_association_loading_with_join_for_count
authors = Author.joins(:special_posts).includes([:posts, :categorizations])
@@ -111,7 +138,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
end
def test_eager_association_loading_with_multiple_stis_and_order
- author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => 'authors.name, comments.body, very_special_comments_posts.body', :conditions => 'posts.id = 4')
+ author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => ['authors.name', 'comments.body', 'very_special_comments_posts.body'], :conditions => 'posts.id = 4')
assert_equal authors(:david), author
assert_no_queries do
author.posts.first.special_comments
diff --git a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
index b124a2bfc3..fb59f63f91 100644
--- a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
+++ b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb
@@ -17,7 +17,7 @@ class EagerLoadIncludeFullStiClassNamesTest < ActiveRecord::TestCase
def generate_test_objects
post = Namespaced::Post.create( :title => 'Great stuff', :body => 'This is not', :author_id => 1 )
- tagging = Tagging.create( :taggable => post )
+ Tagging.create( :taggable => post )
end
def test_class_names
diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb
index c7671a8c22..8957586189 100644
--- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb
+++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb
@@ -4,6 +4,7 @@ require 'models/author'
require 'models/comment'
require 'models/category'
require 'models/categorization'
+require 'models/tagging'
require 'active_support/core_ext/array/random_access'
module Remembered
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 2d8e02e398..e11f1009dc 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -17,12 +17,27 @@ require 'models/subscription'
require 'models/book'
require 'models/developer'
require 'models/project'
+require 'models/member'
+require 'models/membership'
+require 'models/club'
+require 'models/categorization'
+require 'models/sponsor'
class EagerAssociationTest < ActiveRecord::TestCase
fixtures :posts, :comments, :authors, :author_addresses, :categories, :categories_posts,
- :companies, :accounts, :tags, :taggings, :people, :readers,
+ :companies, :accounts, :tags, :taggings, :people, :readers, :categorizations,
:owners, :pets, :author_favorites, :jobs, :references, :subscribers, :subscriptions, :books,
- :developers, :projects, :developers_projects
+ :developers, :projects, :developers_projects, :members, :memberships, :clubs, :sponsors
+
+ def setup
+ # preheat table existence caches
+ Comment.find_by_id(1)
+ end
+
+ def test_eager_with_has_one_through_join_model_with_conditions_on_the_through
+ member = Member.find(members(:some_other_guy).id, :include => :favourite_club)
+ assert_nil member.favourite_club
+ end
def test_loading_with_one_association
posts = Post.find(:all, :include => :comments)
@@ -79,6 +94,58 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
end
+ def test_preloading_has_many_in_multiple_queries_with_more_ids_than_database_can_handle
+ Post.connection.expects(:in_clause_length).at_least_once.returns(5)
+ posts = Post.find(:all, :include=>:comments)
+ assert_equal 7, posts.size
+ end
+
+ def test_preloading_has_many_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle
+ Post.connection.expects(:in_clause_length).at_least_once.returns(nil)
+ posts = Post.find(:all, :include=>:comments)
+ assert_equal 7, posts.size
+ end
+
+ def test_preloading_habtm_in_multiple_queries_with_more_ids_than_database_can_handle
+ Post.connection.expects(:in_clause_length).at_least_once.returns(5)
+ posts = Post.find(:all, :include=>:categories)
+ assert_equal 7, posts.size
+ end
+
+ def test_preloading_habtm_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle
+ Post.connection.expects(:in_clause_length).at_least_once.returns(nil)
+ posts = Post.find(:all, :include=>:categories)
+ assert_equal 7, posts.size
+ end
+
+ def test_load_associated_records_in_one_query_when_adapter_has_no_limit
+ Post.connection.expects(:in_clause_length).at_least_once.returns(nil)
+ Post.expects(:i_was_called).with([1,2,3,4,5,6,7]).returns([1])
+ associated_records = Post.send(:associated_records, [1,2,3,4,5,6,7]) do |some_ids|
+ Post.i_was_called(some_ids)
+ end
+ assert_equal [1], associated_records
+ end
+
+ def test_load_associated_records_in_several_queries_when_many_ids_passed
+ Post.connection.expects(:in_clause_length).at_least_once.returns(5)
+ Post.expects(:i_was_called).with([1,2,3,4,5]).returns([1])
+ Post.expects(:i_was_called).with([6,7]).returns([6])
+ associated_records = Post.send(:associated_records, [1,2,3,4,5,6,7]) do |some_ids|
+ Post.i_was_called(some_ids)
+ end
+ assert_equal [1,6], associated_records
+ end
+
+ def test_load_associated_records_in_one_query_when_a_few_ids_passed
+ Post.connection.expects(:in_clause_length).at_least_once.returns(5)
+ Post.expects(:i_was_called).with([1,2,3]).returns([1])
+ associated_records = Post.send(:associated_records, [1,2,3]) do |some_ids|
+ Post.i_was_called(some_ids)
+ end
+ assert_equal [1], associated_records
+ end
+
def test_including_duplicate_objects_from_belongs_to
popular_post = Post.create!(:title => 'foo', :body => "I like cars!")
comment = popular_post.comments.create!(:body => "lol")
@@ -145,6 +212,15 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
end
+ def test_finding_with_includes_on_null_belongs_to_polymorphic_association
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
+ sponsor.update_attributes!(:sponsorable => nil)
+ sponsor = assert_queries(1) { Sponsor.find(sponsor.id, :include => :sponsorable) }
+ assert_no_queries do
+ assert_equal nil, sponsor.sponsorable
+ end
+ end
+
def test_loading_from_an_association
posts = authors(:david).posts.find(:all, :include => :comments, :order => "posts.id")
assert_equal 2, posts.first.comments.size
@@ -323,7 +399,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
def test_eager_with_has_many_through_a_belongs_to_association
author = authors(:mary)
- post = Post.create!(:author => author, :title => "TITLE", :body => "BODY")
+ Post.create!(:author => author, :title => "TITLE", :body => "BODY")
author.author_favorites.create(:favorite_author_id => 1)
author.author_favorites.create(:favorite_author_id => 2)
posts_with_author_favorites = author.posts.find(:all, :include => :author_favorites)
@@ -521,7 +597,7 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
def test_eager_with_inheritance
- posts = SpecialPost.find(:all, :include => [ :comments ])
+ SpecialPost.find(:all, :include => [ :comments ])
end
def test_eager_has_one_with_association_inheritance
@@ -561,16 +637,16 @@ class EagerAssociationTest < ActiveRecord::TestCase
def test_eager_with_invalid_association_reference
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
- post = Post.find(6, :include=> :monkeys )
+ Post.find(6, :include=> :monkeys )
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
- post = Post.find(6, :include=>[ :monkeys ])
+ Post.find(6, :include=>[ :monkeys ])
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
- post = Post.find(6, :include=>[ 'monkeys' ])
+ Post.find(6, :include=>[ 'monkeys' ])
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
- post = Post.find(6, :include=>[ :monkeys, :elephants ])
+ Post.find(6, :include=>[ :monkeys, :elephants ])
}
end
@@ -584,18 +660,14 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
def test_limited_eager_with_multiple_order_columns
- assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title), posts.id', :limit => 2, :offset => 1)
- assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
+ assert_equal posts(:thinking, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => ['UPPER(posts.title)', 'posts.id'], :limit => 2, :offset => 1)
+ assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => ['UPPER(posts.title) DESC', 'posts.id'], :limit => 2, :offset => 1)
end
def test_limited_eager_with_numeric_in_association
assert_equal people(:david, :susan), Person.find(:all, :include => [:readers, :primary_contact, :number1_fan], :conditions => "number1_fans_people.first_name like 'M%'", :order => 'people.id', :limit => 2, :offset => 0)
end
- def test_preload_with_interpolation
- assert_equal [comments(:greetings)], Post.find(posts(:welcome).id, :include => :comments_with_interpolated_conditions).comments_with_interpolated_conditions
- end
-
def test_polymorphic_type_condition
post = Post.find(posts(:thinking).id, :include => :taggings)
assert post.taggings.include?(taggings(:thinking_general))
@@ -824,25 +896,55 @@ class EagerAssociationTest < ActiveRecord::TestCase
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
+ expected = accounts(:signals37)
+ firm = Firm.find :first, :include => :account_using_primary_key, :order => 'companies.id'
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
+ expected = accounts(:signals37)
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
- def test_preloading_empty_polymorphic_parent
+ def test_preloading_empty_belongs_to
+ c = Client.create!(:name => 'Foo', :client_of => Company.maximum(:id) + 1)
+
+ client = assert_queries(2) { Client.preload(:firm).find(c.id) }
+ assert_no_queries { assert_nil client.firm }
+ end
+
+ def test_preloading_empty_belongs_to_polymorphic
t = Tagging.create!(:taggable_type => 'Post', :taggable_id => Post.maximum(:id) + 1, :tag => tags(:general))
- assert_queries(2) { @tagging = Tagging.preload(:taggable).find(t.id) }
- assert_no_queries { assert ! @tagging.taggable }
+ tagging = assert_queries(2) { Tagging.preload(:taggable).find(t.id) }
+ assert_no_queries { assert_nil tagging.taggable }
+ end
+
+ def test_preloading_through_empty_belongs_to
+ c = Client.create!(:name => 'Foo', :client_of => Company.maximum(:id) + 1)
+
+ client = assert_queries(2) { Client.preload(:accounts).find(c.id) }
+ assert_no_queries { assert client.accounts.empty? }
+ end
+
+ def test_preloading_has_many_through_with_uniq
+ mary = Author.includes(:unique_categorized_posts).where(:id => authors(:mary).id).first
+ assert_equal 1, mary.unique_categorized_posts.length
+ assert_equal 1, mary.unique_categorized_post_ids.length
+ end
+
+ def test_preloading_polymorphic_with_custom_foreign_type
+ sponsor = sponsors(:moustache_club_sponsor_for_groucho)
+ groucho = members(:groucho)
+
+ sponsor = assert_queries(2) {
+ Sponsor.includes(:thing).where(:id => sponsor.id).first
+ }
+ assert_no_queries { assert_equal groucho, sponsor.thing }
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 7e070e1746..30730c7094 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
@@ -101,38 +101,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal 't1', record[1]
end
- def test_should_record_timestamp_for_join_table
- setup_data_for_habtm_case
-
- con = ActiveRecord::Base.connection
- sql = 'select * from countries_treaties'
- record = con.select_rows(sql).last
- assert_not_nil record[2]
- assert_not_nil record[3]
- if current_adapter?(:Mysql2Adapter, :OracleAdapter)
- assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2].to_s(:db)
- assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3].to_s(:db)
- else
- assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2]
- assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3]
- end
- end
-
- def test_should_record_timestamp_for_join_table_only_if_timestamp_should_be_recorded
- begin
- Treaty.record_timestamps = false
- setup_data_for_habtm_case
-
- con = ActiveRecord::Base.connection
- sql = 'select * from countries_treaties'
- record = con.select_rows(sql).last
- assert_nil record[2]
- assert_nil record[3]
- ensure
- Treaty.record_timestamps = true
- end
- end
-
def test_has_and_belongs_to_many
david = Developer.find(1)
@@ -218,43 +186,15 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal 2, aredridel.projects(true).size
end
- def test_adding_uses_default_values_on_join_table
- ac = projects(:action_controller)
- assert !developers(:jamis).projects.include?(ac)
- developers(:jamis).projects << ac
-
- assert developers(:jamis, :reload).projects.include?(ac)
- project = developers(:jamis).projects.detect { |p| p == ac }
- assert_equal 1, project.access_level.to_i
- end
-
- def test_habtm_attribute_access_and_respond_to
- project = developers(:jamis).projects[0]
- assert project.has_attribute?("name")
- assert project.has_attribute?("joined_on")
- assert project.has_attribute?("access_level")
- assert project.respond_to?("name")
- assert project.respond_to?("name=")
- assert project.respond_to?("name?")
- assert project.respond_to?("joined_on")
- # given that the 'join attribute' won't be persisted, I don't
- # think we should define the mutators
- #assert project.respond_to?("joined_on=")
- assert project.respond_to?("joined_on?")
- assert project.respond_to?("access_level")
- #assert project.respond_to?("access_level=")
- assert project.respond_to?("access_level?")
- end
-
def test_habtm_adding_before_save
no_of_devels = Developer.count
no_of_projects = Project.count
aredridel = Developer.new("name" => "Aredridel")
aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
- assert aredridel.new_record?
- assert p.new_record?
+ assert !aredridel.persisted?
+ assert !p.persisted?
assert aredridel.save
- assert !aredridel.new_record?
+ assert aredridel.persisted?
assert_equal no_of_devels+1, Developer.count
assert_equal no_of_projects+1, Project.count
assert_equal 2, aredridel.projects.size
@@ -288,22 +228,22 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal devel.projects.last, proj
assert devel.projects.loaded?
- assert proj.new_record?
+ assert !proj.persisted?
devel.save
- assert !proj.new_record?
+ assert proj.persisted?
assert_equal devel.projects.last, proj
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
end
def test_build_by_new_record
devel = Developer.new(:name => "Marcel", :salary => 75000)
- proj1 = devel.projects.build(:name => "Make bed")
+ devel.projects.build(:name => "Make bed")
proj2 = devel.projects.build(:name => "Lie in it")
assert_equal devel.projects.last, proj2
- assert proj2.new_record?
+ assert !proj2.persisted?
devel.save
- assert !devel.new_record?
- assert !proj2.new_record?
+ assert devel.persisted?
+ assert proj2.persisted?
assert_equal devel.projects.last, proj2
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
end
@@ -316,19 +256,19 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal devel.projects.last, proj
assert !devel.projects.loaded?
- assert !proj.new_record?
+ assert proj.persisted?
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
end
def test_create_by_new_record
devel = Developer.new(:name => "Marcel", :salary => 75000)
- proj1 = devel.projects.build(:name => "Make bed")
+ devel.projects.build(:name => "Make bed")
proj2 = devel.projects.build(:name => "Lie in it")
assert_equal devel.projects.last, proj2
- assert proj2.new_record?
+ assert !proj2.persisted?
devel.save
- assert !devel.new_record?
- assert !proj2.new_record?
+ assert devel.persisted?
+ assert proj2.persisted?
assert_equal devel.projects.last, proj2
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
end
@@ -343,7 +283,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
# in Oracle '' is saved as null therefore need to save ' ' in not null column
another_post = categories(:general).post_with_conditions.create(:body => ' ')
- assert !another_post.new_record?
+ assert another_post.persisted?
assert_equal 'Yet Another Testing Title', another_post.title
end
@@ -430,10 +370,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
end
- def test_additional_columns_from_join_table
- assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date
- end
-
def test_destroying
david = Developer.find(1)
active_record = Project.find(1)
@@ -559,8 +495,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
def test_dynamic_find_should_respect_association_order
# Developers are ordered 'name DESC, id DESC'
- low_id_jamis = developers(:jamis)
- middle_id_jamis = developers(:poor_jamis)
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
@@ -677,25 +611,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
end
- def test_updating_attributes_on_rich_associations
- david = projects(:action_controller).developers.first
- david.name = "DHH"
- assert_raise(ActiveRecord::ReadOnlyRecord) { david.save! }
- end
-
- def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection
- david = projects(:action_controller).selected_developers.first
- david.name = "DHH"
- assert_nothing_raised { david.save! }
- end
-
-
- def test_updating_attributes_on_rich_associations_with_limited_find
- david = projects(:action_controller).developers.find(:all, :select => "developers.*").first
- david.name = "DHH"
- assert david.save!
- end
-
def test_join_table_alias
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index c9f00fd737..1ce91d7211 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -66,6 +66,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 'exotic', bulb.name
end
+ def test_no_sql_should_be_fired_if_association_already_loaded
+ Car.create(:name => 'honda')
+ bulbs = Car.first.bulbs
+ bulbs.inspect # to load all instances of bulbs
+ assert_no_queries do
+ bulbs.first()
+ bulbs.first({})
+ end
+ end
+
def test_create_resets_cached_counters
person = Person.create!(:first_name => 'tenderlove')
post = Post.first
@@ -73,7 +83,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal [], person.readers
assert_nil person.readers.find_by_post_id(post.id)
- reader = person.readers.create(:post_id => post.id)
+ person.readers.create(:post_id => post.id)
assert_equal 1, person.readers.count
assert_equal 1, person.readers.length
@@ -88,7 +98,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal [], person.readers
assert_nil person.readers.find_by_post_id(post.id)
- reader = person.readers.find_or_create_by_post_id(post.id)
+ person.readers.find_or_create_by_post_id(post.id)
assert_equal 1, person.readers.count
assert_equal 1, person.readers.length
@@ -187,7 +197,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
another = author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body")
assert_equal number_of_posts + 1, Post.count
assert_equal another, author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body")
- assert !another.new_record?
+ assert another.persisted?
end
def test_cant_save_has_many_readonly_association
@@ -402,7 +412,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_adding_using_create
first_firm = companies(:first_firm)
assert_equal 2, first_firm.plain_clients.size
- natural = first_firm.plain_clients.create(:name => "Natural Company")
+ first_firm.plain_clients.create(:name => "Natural Company")
assert_equal 3, first_firm.plain_clients.length
assert_equal 3, first_firm.plain_clients.size
end
@@ -453,7 +463,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal new_client, company.clients_of_firm.last
end
@@ -483,7 +493,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_build_followed_by_save_does_not_load_target
- new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client")
+ companies(:first_firm).clients_of_firm.build("name" => "Another Client")
assert companies(:first_firm).save
assert !companies(:first_firm).clients_of_firm.loaded?
end
@@ -508,7 +518,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !company.clients_of_firm.loaded?
assert_equal "Another Client", new_client.name
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal new_client, company.clients_of_firm.last
end
@@ -543,7 +553,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_create
force_signal37_to_load_all_clients_of_firm
new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal new_client, companies(:first_firm).clients_of_firm.last
assert_equal new_client, companies(:first_firm).clients_of_firm(true).last
end
@@ -554,7 +564,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
def test_create_followed_by_save_does_not_load_target
- new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client")
+ companies(:first_firm).clients_of_firm.create("name" => "Another Client")
assert companies(:first_firm).save
assert !companies(:first_firm).clients_of_firm.loaded?
end
@@ -563,7 +573,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client")
assert_equal companies(:first_firm).id, the_client.firm_id
assert_equal "Yet another client", the_client.name
- assert the_client.new_record?
+ assert !the_client.persisted?
end
def test_find_or_create_updates_size
@@ -606,6 +616,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
end
+ def test_deleting_updates_counter_cache_with_dependent_delete_all
+ post = posts(:welcome)
+
+ # Manually update the count as the tagging will have been added to the taggings association,
+ # rather than to the taggings_with_delete_all one (which is just a 'shadow' of the former)
+ post.update_attribute(:taggings_with_delete_all_count, post.taggings_with_delete_all.to_a.count)
+
+ assert_difference "post.reload.taggings_with_delete_all_count", -1 do
+ post.taggings_with_delete_all.delete(post.taggings_with_delete_all.first)
+ end
+ end
+
def test_deleting_a_collection
force_signal37_to_load_all_clients_of_firm
companies(:first_firm).clients_of_firm.create("name" => "Another Client")
@@ -752,7 +774,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create
- assert !another_ms_client.new_record?
+ assert another_ms_client.persisted?
assert_equal 'Microsoft', another_ms_client.name
end
@@ -852,7 +874,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_dependence_for_associations_with_hash_condition
david = authors(:david)
- post = posts(:thinking).id
assert_difference('Post.count', -1) { assert david.destroy }
end
@@ -872,7 +893,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_three_levels_of_dependence
topic = Topic.create "title" => "neat and simple"
reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it"
- silly_reply = reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
+ reply.replies.create "title" => "neat and simple", "content" => "ain't complaining"
assert_nothing_raised { topic.destroy }
end
@@ -897,7 +918,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_depends_and_nullify
num_accounts = Account.count
- num_companies = Company.count
core = companies(:rails_core)
assert_equal accounts(:rails_core_account), core.account
@@ -914,7 +934,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_restrict
firm = RestrictedFirm.new(:name => 'restrict')
firm.save!
- child_firm = firm.companies.create(:name => 'child')
+ firm.companies.create(:name => 'child')
assert !firm.companies.empty?
assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
end
@@ -955,6 +975,19 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !firm.clients.include?(:first_client)
end
+ def test_replace_failure
+ firm = companies(:first_firm)
+ account = Account.new
+ orig_accounts = firm.accounts.to_a
+
+ assert !account.valid?
+ assert !orig_accounts.empty?
+ assert_raise ActiveRecord::RecordNotSaved do
+ firm.accounts = [account]
+ end
+ assert_equal orig_accounts, firm.accounts
+ end
+
def test_get_ids
assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
end
@@ -1273,4 +1306,25 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
comment = post.comments.build
assert post.comments.include?(comment)
end
+
+ def test_load_target_respects_protected_attributes
+ topic = Topic.create!
+ reply = topic.replies.create(:title => "reply 1")
+ reply.approved = false
+ reply.save!
+
+ # Save with a different object instance, so the instance that's still held
+ # in topic.relies doesn't know about the changed attribute.
+ reply2 = Reply.find(reply.id)
+ reply2.approved = true
+ reply2.save!
+
+ # Force loading the collection from the db. This will merge the existing
+ # object (reply) with what gets loaded from the db (which includes the
+ # changed approved attribute). approved is a protected attribute, so if mass
+ # assignment is used, it won't get updated and will still be false.
+ first = topic.replies.to_a.first
+ assert_equal reply.id, first.id
+ assert_equal true, first.approved?
+ end
end
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 4b9f49f1ec..7235631b5a 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -17,11 +17,14 @@ require 'models/developer'
require 'models/subscriber'
require 'models/book'
require 'models/subscription'
+require 'models/categorization'
+require 'models/category'
+require 'models/essay'
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
- fixtures :posts, :readers, :people, :comments, :authors,
+ fixtures :posts, :readers, :people, :comments, :authors, :categories,
:owners, :pets, :toys, :jobs, :references, :companies,
- :subscribers, :books, :subscriptions, :developers
+ :subscribers, :books, :subscriptions, :developers, :categorizations
# Dummies to force column loads so query counts are clean.
def setup
@@ -29,6 +32,13 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
Reader.create :person_id => 0, :post_id => 0
end
+ def test_include?
+ person = Person.new
+ post = Post.new
+ person.posts << post
+ assert person.posts.include?(post)
+ end
+
def test_associate_existing
assert_queries(2) { posts(:thinking); people(:david) }
@@ -43,6 +53,16 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert posts(:thinking).reload.people(true).include?(people(:david))
end
+ def test_associate_existing_record_twice_should_add_to_target_twice
+ post = posts(:thinking)
+ person = people(:david)
+
+ assert_difference 'post.people.to_a.count', 2 do
+ post.people << person
+ post.people << person
+ end
+ end
+
def test_associating_new
assert_queries(1) { posts(:thinking) }
new_person = nil # so block binding catches it
@@ -322,12 +342,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_equal 2, people(:michael).jobs.size
end
- def test_get_ids_for_belongs_to_source
- assert_sql(/DISTINCT/) { assert_equal [posts(:welcome).id, posts(:authorless).id].sort, people(:michael).post_ids.sort }
- end
-
- def test_get_ids_for_has_many_source
- assert_equal [comments(:eager_other_comment1).id], authors(:mary).comment_ids
+ def test_get_ids
+ assert_equal [posts(:welcome).id, posts(:authorless).id].sort, people(:michael).post_ids.sort
end
def test_get_ids_for_loaded_associations
@@ -354,7 +370,6 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
end
def test_has_many_association_through_a_belongs_to_association_where_the_association_doesnt_exist
- author = authors(:mary)
post = Post.create!(:title => "TITLE", :body => "BODY")
assert_equal [], post.author_favorites
end
@@ -389,6 +404,41 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) }
end
+ def test_has_many_association_through_a_has_many_association_to_self
+ sarah = Person.create!(:first_name => 'Sarah', :primary_contact_id => people(:susan).id, :gender => 'F', :number1_fan_id => 1)
+ john = Person.create!(:first_name => 'John', :primary_contact_id => sarah.id, :gender => 'M', :number1_fan_id => 1)
+ assert_equal sarah.agents, [john]
+ assert_equal people(:susan).agents.map(&:agents).flatten, people(:susan).agents_of_agents
+ end
+
+ def test_associate_existing_with_nonstandard_primary_key_on_belongs_to
+ Categorization.create(:author => authors(:mary), :named_category_name => categories(:general).name)
+ assert_equal categories(:general), authors(:mary).named_categories.first
+ end
+
+ def test_collection_build_with_nonstandard_primary_key_on_belongs_to
+ author = authors(:mary)
+ category = author.named_categories.build(:name => "Primary")
+ author.save
+ assert Categorization.exists?(:author_id => author.id, :named_category_name => category.name)
+ assert author.named_categories(true).include?(category)
+ end
+
+ def test_collection_create_with_nonstandard_primary_key_on_belongs_to
+ author = authors(:mary)
+ category = author.named_categories.create(:name => "Primary")
+ assert Categorization.exists?(:author_id => author.id, :named_category_name => category.name)
+ assert author.named_categories(true).include?(category)
+ end
+
+ def test_collection_delete_with_nonstandard_primary_key_on_belongs_to
+ author = authors(:mary)
+ category = author.named_categories.create(:name => "Primary")
+ author.named_categories.delete(category)
+ assert !Categorization.exists?(:author_id => author.id, :named_category_name => category.name)
+ assert author.named_categories(true).empty?
+ end
+
def test_collection_singular_ids_getter_with_string_primary_keys
book = books(:awdr)
assert_equal 2, book.subscriber_ids.size
@@ -449,4 +499,62 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
comment = post.comments.build
assert author.comments.include?(comment)
end
+
+ def test_size_of_through_association_should_increase_correctly_when_has_many_association_is_added
+ post = posts(:thinking)
+ readers = post.readers.size
+ post.people << people(:michael)
+ assert_equal readers + 1, post.readers.size
+ end
+
+ def test_has_many_through_with_default_scope_on_join_model
+ assert_equal posts(:welcome).comments.order('id').all, authors(:david).comments_on_first_posts
+ end
+
+ def test_create_has_many_through_with_default_scope_on_join_model
+ category = authors(:david).special_categories.create(:name => "Foo")
+ assert_equal 1, category.categorizations.where(:special => true).count
+ end
+
+ def test_joining_has_many_through_with_uniq
+ mary = Author.joins(:unique_categorized_posts).where(:id => authors(:mary).id).first
+ assert_equal 1, mary.unique_categorized_posts.length
+ assert_equal 1, mary.unique_categorized_post_ids.length
+ end
+
+ def test_joining_has_many_through_belongs_to
+ posts = Post.joins(:author_categorizations).
+ where('categorizations.id' => categorizations(:mary_thinking_sti).id)
+
+ assert_equal [posts(:eager_other)], posts
+ end
+
+ def test_select_chosen_fields_only
+ author = authors(:david)
+ assert_equal ['body'], author.comments.select('comments.body').first.attributes.keys
+ end
+
+ def test_get_has_many_through_belongs_to_ids_with_conditions
+ assert_equal [categories(:general).id], authors(:mary).categories_like_general_ids
+ end
+
+ def test_count_has_many_through_with_named_scope
+ assert_equal 2, authors(:mary).categories.count
+ assert_equal 1, authors(:mary).categories.general.count
+ end
+
+ def test_has_many_through_belongs_to_should_update_when_the_through_foreign_key_changes
+ post = posts(:eager_other)
+
+ post.author_categorizations
+ proxy = post.send(:association_instance_get, :author_categorizations)
+
+ assert !proxy.stale_target?
+ assert_equal authors(:mary).categorizations.sort_by(&:id), post.author_categorizations.sort_by(&:id)
+
+ post.author_id = authors(:david).id
+
+ assert proxy.stale_target?
+ assert_equal authors(:david).categorizations.sort_by(&:id), post.author_categorizations.sort_by(&:id)
+ end
end
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index b522be3fe0..d9b6694dd8 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -2,9 +2,12 @@ require "cases/helper"
require 'models/developer'
require 'models/project'
require 'models/company'
+require 'models/ship'
+require 'models/pirate'
class HasOneAssociationsTest < ActiveRecord::TestCase
- fixtures :accounts, :companies, :developers, :projects, :developers_projects
+ self.use_transactional_fixtures = false unless supports_savepoints?
+ fixtures :accounts, :companies, :developers, :projects, :developers_projects, :ships, :pirates
def setup
Account.destroyed_account_ids.clear
@@ -91,18 +94,18 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_nullification_on_association_change
firm = companies(:rails_core)
old_account_id = firm.account.id
- firm.account = Account.new
+ firm.account = Account.new(:credit_limit => 5)
# account is dependent with nullify, therefore its firm_id should be nil
assert_nil Account.find(old_account_id).firm_id
end
def test_association_change_calls_delete
- companies(:first_firm).deletable_account = Account.new
+ companies(:first_firm).deletable_account = Account.new(:credit_limit => 5)
assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id]
end
def test_association_change_calls_destroy
- companies(:first_firm).account = Account.new
+ companies(:first_firm).account = Account.new(:credit_limit => 5)
assert_equal [companies(:first_firm).id], Account.destroyed_account_ids[companies(:first_firm).id]
end
@@ -116,35 +119,6 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal company.account, account
end
- def test_assignment_without_replacement
- apple = Firm.create("name" => "Apple")
- citibank = Account.create("credit_limit" => 10)
- apple.account = citibank
- assert_equal apple.id, citibank.firm_id
-
- hsbc = apple.build_account({ :credit_limit => 20}, false)
- assert_equal apple.id, hsbc.firm_id
- hsbc.save
- assert_equal apple.id, citibank.firm_id
-
- nykredit = apple.create_account({ :credit_limit => 30}, false)
- assert_equal apple.id, nykredit.firm_id
- assert_equal apple.id, citibank.firm_id
- assert_equal apple.id, hsbc.firm_id
- end
-
- def test_assignment_without_replacement_on_create
- apple = Firm.create("name" => "Apple")
- citibank = Account.create("credit_limit" => 10)
- apple.account = citibank
- assert_equal apple.id, citibank.firm_id
-
- hsbc = apple.create_account({:credit_limit => 10}, false)
- assert_equal apple.id, hsbc.firm_id
- hsbc.save
- assert_equal apple.id, citibank.firm_id
- end
-
def test_dependence
num_accounts = Account.count
@@ -163,7 +137,6 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
firm = ExclusivelyDependentFirm.find(9)
assert_not_nil firm.account
- account_id = firm.account.id
assert_equal [], Account.destroyed_account_ids[firm.id]
firm.destroy
@@ -180,7 +153,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_dependence_with_restrict
firm = RestrictedFirm.new(:name => 'restrict')
firm.save!
- account = firm.create_account(:credit_limit => 10)
+ firm.create_account(:credit_limit => 10)
assert_not_nil firm.account
assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy }
end
@@ -194,18 +167,27 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal account, firm.account
end
- def test_build_association_twice_without_saving_affects_nothing
- count_of_account = Account.count
- firm = Firm.find(:first)
- account1 = firm.build_account("credit_limit" => 1000)
- account2 = firm.build_account("credit_limit" => 2000)
+ def test_create_association
+ firm = Firm.create(:name => "GlobalMegaCorp")
+ account = firm.create_account(:credit_limit => 1000)
+ assert_equal account, firm.reload.account
+ end
- assert_equal count_of_account, Account.count
+ def test_create_association_with_bang
+ firm = Firm.create(:name => "GlobalMegaCorp")
+ account = firm.create_account!(:credit_limit => 1000)
+ assert_equal account, firm.reload.account
end
- def test_create_association
+ def test_create_association_with_bang_failing
firm = Firm.create(:name => "GlobalMegaCorp")
- account = firm.create_account(:credit_limit => 1000)
+ assert_raise ActiveRecord::RecordInvalid do
+ firm.create_account!
+ end
+ account = firm.account
+ assert_not_nil account
+ account.credit_limit = 5
+ account.save
assert_equal account, firm.reload.account
end
@@ -219,17 +201,6 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal account, firm.account
end
- def test_failing_build_association
- firm = Firm.new("name" => "GlobalMegaCorp")
- firm.save
-
- firm.account = account = Account.new
- assert_equal account, firm.account
- assert !account.save
- assert_equal account, firm.account
- assert_equal ["can't be empty"], account.errors["credit_limit"]
- end
-
def test_create
firm = Firm.new("name" => "GlobalMegaCorp")
firm.save
@@ -257,18 +228,10 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
firm.destroy
end
- def test_finding_with_interpolated_condition
- firm = Firm.find(:first)
- superior = firm.clients.create(:name => 'SuperiorCo')
- superior.rating = 10
- superior.save
- assert_equal 10, firm.clients_with_interpolated_conditions.first.rating
- end
-
def test_assignment_before_child_saved
firm = Firm.find(1)
firm.account = a = Account.new("credit_limit" => 1000)
- assert !a.new_record?
+ assert a.persisted?
assert_equal a, firm.account
assert_equal a, firm.account
assert_equal a, firm.account(true)
@@ -323,7 +286,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_create_respects_hash_condition
account = companies(:first_firm).create_account_limit_500_with_hash_conditions
- assert !account.new_record?
+ assert account.persisted?
assert_equal 500, account.credit_limit
end
@@ -331,4 +294,51 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
new_account = companies(:first_firm).build_account(:firm_name => 'Account')
assert_equal new_account.firm_name, "Account"
end
+
+ def test_creation_failure_without_dependent_option
+ pirate = pirates(:blackbeard)
+ orig_ship = pirate.ship.target
+
+ assert_equal ships(:black_pearl), orig_ship
+ new_ship = pirate.create_ship
+ assert_not_equal ships(:black_pearl), new_ship
+ assert_equal new_ship, pirate.ship
+ assert new_ship.new_record?
+ assert_nil orig_ship.pirate_id
+ assert !orig_ship.changed? # check it was saved
+ end
+
+ def test_creation_failure_with_dependent_option
+ pirate = pirates(:blackbeard).becomes(DestructivePirate)
+ orig_ship = pirate.dependent_ship.target
+
+ new_ship = pirate.create_dependent_ship
+ assert new_ship.new_record?
+ assert orig_ship.destroyed?
+ end
+
+ def test_replacement_failure_due_to_existing_record_should_raise_error
+ pirate = pirates(:blackbeard)
+ pirate.ship.name = nil
+
+ assert !pirate.ship.valid?
+ assert_raise(ActiveRecord::RecordNotSaved) do
+ pirate.ship = ships(:interceptor)
+ end
+ assert_equal ships(:black_pearl), pirate.ship
+ assert_equal pirate.id, pirate.ship.pirate_id
+ end
+
+ def test_replacement_failure_due_to_new_record_should_raise_error
+ pirate = pirates(:blackbeard)
+ new_ship = Ship.new
+
+ assert_raise(ActiveRecord::RecordNotSaved) do
+ pirate.ship = new_ship
+ end
+ assert_equal ships(:black_pearl), pirate.ship
+ assert_equal pirate.id, pirate.ship.pirate_id
+ assert_equal pirate.id, ships(:black_pearl).reload.pirate_id
+ assert_nil new_ship.pirate_id
+ end
end
diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb
index 5d153147f5..91d3025468 100644
--- a/activerecord/test/cases/associations/has_one_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb
@@ -9,9 +9,13 @@ require 'models/member_detail'
require 'models/minivan'
require 'models/dashboard'
require 'models/speedometer'
+require 'models/author'
+require 'models/post'
+require 'models/comment'
class HasOneThroughAssociationsTest < ActiveRecord::TestCase
- fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations, :minivans, :dashboards, :speedometers
+ fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations, :minivans,
+ :dashboards, :speedometers, :authors, :posts, :comments
def setup
@member = members(:groucho)
@@ -21,10 +25,6 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
assert_equal clubs(:boring_club), @member.club
end
- def test_has_one_through_with_has_many
- assert_equal clubs(:moustache_club), @member.favourite_club
- end
-
def test_creating_association_creates_through_record
new_member = Member.create(:name => "Chris")
new_member.club = Club.create(:name => "LRUG")
@@ -84,6 +84,18 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
assert_not_nil assert_no_queries {members[0].sponsor_club}
end
+ def test_has_one_through_with_conditions_eager_loading
+ # conditions on the through table
+ assert_equal clubs(:moustache_club), Member.find(@member.id, :include => :favourite_club).favourite_club
+ memberships(:membership_of_favourite_club).update_attribute(:favourite, false)
+ assert_equal nil, Member.find(@member.id, :include => :favourite_club).favourite_club
+
+ # conditions on the source table
+ assert_equal clubs(:moustache_club), Member.find(@member.id, :include => :hairy_club).hairy_club
+ clubs(:moustache_club).update_attribute(:name, "Association of Clean-Shaven Persons")
+ assert_equal nil, Member.find(@member.id, :include => :hairy_club).hairy_club
+ end
+
def test_has_one_through_polymorphic_with_source_type
assert_equal members(:groucho), clubs(:moustache_club).sponsored_member
end
@@ -185,7 +197,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
MemberDetail.find(:all, :include => :member_type)
end
@new_detail = @member_details[0]
- assert @new_detail.loaded_member_type?
+ assert @new_detail.send(:association_proxy, :member_type).loaded?
assert_not_nil assert_no_queries { @new_detail.member_type }
end
@@ -206,10 +218,74 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
end
end
+ def test_through_belongs_to_after_destroy
+ @member_detail = MemberDetail.new(:extra_data => 'Extra')
+ @member.member_detail = @member_detail
+ @member.save!
+
+ assert_not_nil @member_detail.member_type
+ @member_detail.destroy
+ assert_queries(1) do
+ assert_not_nil @member_detail.member_type(true)
+ end
+
+ @member_detail.member.destroy
+ assert_queries(1) do
+ assert_nil @member_detail.member_type(true)
+ end
+ end
+
def test_value_is_properly_quoted
minivan = Minivan.find('m1')
assert_nothing_raised do
minivan.dashboard
end
end
+
+ def test_has_one_through_with_default_scope_on_join_model
+ assert_equal posts(:welcome).comments.order('id').first, authors(:david).comment_on_first_post
+ end
+
+ def test_has_one_through_many_raises_exception
+ assert_raise(ActiveRecord::HasOneThroughCantAssociateThroughCollection) do
+ members(:groucho).club_through_many
+ end
+ end
+
+ def test_has_one_through_belongs_to_should_update_when_the_through_foreign_key_changes
+ minivan = minivans(:cool_first)
+
+ minivan.dashboard
+ proxy = minivan.send(:association_instance_get, :dashboard)
+
+ assert !proxy.stale_target?
+ assert_equal dashboards(:cool_first), minivan.dashboard
+
+ minivan.speedometer_id = speedometers(:second).id
+
+ assert proxy.stale_target?
+ assert_equal dashboards(:second), minivan.dashboard
+ end
+
+ def test_has_one_through_belongs_to_setting_belongs_to_foreign_key_after_nil_target_loaded
+ minivan = Minivan.new
+
+ minivan.dashboard
+ proxy = minivan.send(:association_instance_get, :dashboard)
+
+ minivan.speedometer_id = speedometers(:second).id
+
+ assert proxy.stale_target?
+ assert_equal dashboards(:second), minivan.dashboard
+ end
+
+ def test_assigning_has_one_through_belongs_to_with_new_record_owner
+ minivan = Minivan.new
+ dashboard = dashboards(:cool_first)
+
+ minivan.dashboard = dashboard
+
+ assert_equal dashboard, minivan.dashboard
+ assert_equal dashboard, minivan.speedometer.dashboard
+ end
end
diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb
index 780eabc443..da2a81e98a 100644
--- a/activerecord/test/cases/associations/inner_join_association_test.rb
+++ b/activerecord/test/cases/associations/inner_join_association_test.rb
@@ -65,21 +65,21 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase
authors_with_welcoming_post_titles = Author.calculate(:count, 'authors.id', :joins => :posts, :distinct => true, :conditions => "posts.title like 'Welcome%'")
assert_equal real_count, authors_with_welcoming_post_titles, "inner join and conditions should have only returned authors posting titles starting with 'Welcome'"
end
-
+
def test_find_with_sti_join
scope = Post.joins(:special_comments).where(:id => posts(:sti_comments).id)
-
+
# The join should match SpecialComment and its subclasses only
assert scope.where("comments.type" => "Comment").empty?
assert !scope.where("comments.type" => "SpecialComment").empty?
assert !scope.where("comments.type" => "SubSpecialComment").empty?
end
-
+
def test_find_with_conditions_on_reflection
assert !posts(:welcome).comments.empty?
assert Post.joins(:nonexistant_comments).where(:id => posts(:welcome).id).empty? # [sic!]
end
-
+
def test_find_with_conditions_on_through_reflection
assert !posts(:welcome).tags.empty?
assert Post.joins(:misc_tags).where(:id => posts(:welcome).id).empty?
diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb
index fa5c2e49df..e9a57a00a0 100644
--- a/activerecord/test/cases/associations/inverse_associations_test.rb
+++ b/activerecord/test/cases/associations/inverse_associations_test.rb
@@ -114,7 +114,7 @@ class InverseHasOneTests < ActiveRecord::TestCase
end
def test_parent_instance_should_be_shared_with_newly_built_child
- m = men(:gordon)
+ m = Man.find(:first)
f = m.build_face(:description => 'haunted')
assert_not_nil f.man
assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
@@ -125,7 +125,7 @@ class InverseHasOneTests < ActiveRecord::TestCase
end
def test_parent_instance_should_be_shared_with_newly_created_child
- m = men(:gordon)
+ m = Man.find(:first)
f = m.create_face(:description => 'haunted')
assert_not_nil f.man
assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
@@ -146,39 +146,6 @@ class InverseHasOneTests < ActiveRecord::TestCase
assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
end
- def test_parent_instance_should_be_shared_with_newly_built_child_when_we_dont_replace_existing
- m = Man.find(:first)
- f = m.build_face({:description => 'haunted'}, false)
- assert_not_nil f.man
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
- m.name = 'Bongo'
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
- f.man.name = 'Mungo'
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
- end
-
- def test_parent_instance_should_be_shared_with_newly_created_child_when_we_dont_replace_existing
- m = Man.find(:first)
- f = m.create_face({:description => 'haunted'}, false)
- assert_not_nil f.man
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
- m.name = 'Bongo'
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
- f.man.name = 'Mungo'
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
- end
-
- def test_parent_instance_should_be_shared_with_newly_created_child_via_bang_method_when_we_dont_replace_existing
- m = Man.find(:first)
- f = m.face.create!({:description => 'haunted'}, false)
- assert_not_nil f.man
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
- m.name = 'Bongo'
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
- f.man.name = 'Mungo'
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
- end
-
def test_parent_instance_should_be_shared_with_replaced_via_accessor_child
m = Man.find(:first)
f = Face.new(:description => 'haunted')
@@ -203,18 +170,6 @@ class InverseHasOneTests < ActiveRecord::TestCase
assert_equal m.name, f.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
end
- def test_parent_instance_should_be_shared_with_replaced_via_method_child_when_we_dont_replace_existing
- m = Man.find(:first)
- f = Face.new(:description => 'haunted')
- m.face.replace(f, false)
- assert_not_nil f.man
- assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance"
- m.name = 'Bongo'
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance"
- f.man.name = 'Mungo'
- assert_equal m.name, f.man.name, "Name of man should be the same after changes to replaced-child-owned instance"
- end
-
def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error
assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Man.find(:first).dirty_face }
end
@@ -257,17 +212,6 @@ class InverseHasManyTests < ActiveRecord::TestCase
end
end
- def test_parent_instance_should_be_shared_with_newly_built_child
- m = men(:gordon)
- i = m.interests.build(:topic => 'Industrial Revolution Re-enactment')
- assert_not_nil i.man
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
- m.name = 'Bongo'
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
- i.man.name = 'Mungo'
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
- end
-
def test_parent_instance_should_be_shared_with_newly_block_style_built_child
m = Man.find(:first)
i = m.interests.build {|ii| ii.topic = 'Industrial Revolution Re-enactment'}
@@ -280,17 +224,6 @@ class InverseHasManyTests < ActiveRecord::TestCase
assert_equal m.name, i.man.name, "Name of man should be the same after changes to just-built-child-owned instance"
end
- def test_parent_instance_should_be_shared_with_newly_created_child
- m = men(:gordon)
- i = m.interests.create(:topic => 'Industrial Revolution Re-enactment')
- assert_not_nil i.man
- assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance"
- m.name = 'Bongo'
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance"
- i.man.name = 'Mungo'
- assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance"
- end
-
def test_parent_instance_should_be_shared_with_newly_created_via_bang_method_child
m = Man.find(:first)
i = m.interests.create!(:topic => 'Industrial Revolution Re-enactment')
@@ -484,7 +417,6 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase
def test_child_instance_should_be_shared_with_replaced_via_accessor_parent
face = faces(:confused)
- old_man = face.polymorphic_man
new_man = Man.new
assert_not_nil face.polymorphic_man
@@ -499,7 +431,6 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase
def test_child_instance_should_be_shared_with_replaced_via_method_parent
face = faces(:confused)
- old_man = face.polymorphic_man
new_man = Man.new
assert_not_nil face.polymorphic_man
@@ -551,8 +482,8 @@ class InverseMultipleHasManyInversesForSameModel < ActiveRecord::TestCase
def test_that_we_can_load_associations_that_have_the_same_reciprocal_name_from_different_models
assert_nothing_raised(ActiveRecord::AssociationTypeMismatch) do
i = Interest.find(:first)
- z = i.zine
- m = i.man
+ i.zine
+ i.man
end
end
diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb
index 7a22ce4dad..c50fcd3f33 100644
--- a/activerecord/test/cases/associations/join_model_test.rb
+++ b/activerecord/test/cases/associations/join_model_test.rb
@@ -13,7 +13,8 @@ require 'models/book'
require 'models/citation'
class AssociationsJoinModelTest < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
+
fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books,
# Reload edges table from fixtures as otherwise repeated test was failing
:edges
@@ -44,16 +45,6 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
assert !authors(:mary).unique_categorized_posts.loaded?
end
- def test_column_caching
- # pre-heat our cache
- Post.arel_table.columns
- Comment.columns
-
- Post.connection.column_calls = 0
- 2.times { Post.joins(:comments).to_a }
- assert_equal 0, Post.connection.column_calls
- end
-
def test_has_many_uniq_through_find
assert_equal 1, authors(:mary).unique_categorized_posts.find(:all).size
end
@@ -95,13 +86,6 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
end
end
- def test_polymorphic_has_many_going_through_join_model_with_disabled_include
- assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
- assert_queries 1 do
- tag.tagging
- end
- end
-
def test_polymorphic_has_many_going_through_join_model_with_custom_select_and_joins
assert_equal tags(:general), tag = posts(:welcome).tags.add_joins_and_select.first
tag.author_id
@@ -308,6 +292,22 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
assert_equal [authors(:mary)], posts(:authorless).authors
end
+ def test_has_many_going_through_join_model_with_custom_primary_key
+ assert_equal [authors(:david)], posts(:thinking).authors_using_author_id
+ end
+
+ def test_has_many_going_through_polymorphic_join_model_with_custom_primary_key
+ assert_equal [tags(:general)], posts(:eager_other).tags_using_author_id
+ end
+
+ def test_has_many_through_with_custom_primary_key_on_belongs_to_source
+ assert_equal [authors(:david), authors(:david)], posts(:thinking).author_using_custom_pk
+ end
+
+ def test_has_many_through_with_custom_primary_key_on_has_many_source
+ assert_equal [authors(:david)], posts(:thinking).authors_using_custom_pk
+ end
+
def test_both_scoped_and_explicit_joins_should_be_respected
assert_nothing_raised do
Post.send(:with_scope, :find => {:joins => "left outer join comments on comments.id = posts.id"}) do
@@ -334,11 +334,16 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
end
def test_has_many_polymorphic
- assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicError do
- assert_equal posts(:welcome, :thinking), tags(:general).taggables
+ assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicSourceError do
+ tags(:general).taggables
end
+
+ assert_raise ActiveRecord::HasManyThroughAssociationPolymorphicThroughError do
+ taggings(:welcome_general).things
+ end
+
assert_raise ActiveRecord::EagerLoadPolymorphicError do
- assert_equal posts(:welcome, :thinking), tags(:general).taggings.find(:all, :include => :taggable, :conditions => 'bogus_table.column = 1')
+ tags(:general).taggings.find(:all, :include => :taggable, :conditions => 'bogus_table.column = 1')
end
end
@@ -450,11 +455,11 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
new_tag = Tag.new(:name => "new")
saved_post.tags << new_tag
- assert !new_tag.new_record? #consistent with habtm!
- assert !saved_post.new_record?
+ assert new_tag.persisted? #consistent with habtm!
+ assert saved_post.persisted?
assert saved_post.tags.include?(new_tag)
- assert !new_tag.new_record?
+ assert new_tag.persisted?
assert saved_post.reload.tags(true).include?(new_tag)
@@ -462,16 +467,16 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
saved_tag = tags(:general)
new_post.tags << saved_tag
- assert new_post.new_record?
- assert !saved_tag.new_record?
+ assert !new_post.persisted?
+ assert saved_tag.persisted?
assert new_post.tags.include?(saved_tag)
new_post.save!
- assert !new_post.new_record?
+ assert new_post.persisted?
assert new_post.reload.tags(true).include?(saved_tag)
- assert posts(:thinking).tags.build.new_record?
- assert posts(:thinking).tags.new.new_record?
+ assert !posts(:thinking).tags.build.persisted?
+ assert !posts(:thinking).tags.new.persisted?
end
def test_create_associate_when_adding_to_has_many_through
@@ -506,6 +511,10 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
end
+ def test_add_to_join_table_with_no_id
+ assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
+ end
+
def test_has_many_through_collection_size_doesnt_load_target_if_not_loaded
author = authors(:david)
assert_equal 10, author.comments.size
@@ -514,7 +523,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
author = authors(:david)
- author.stubs(:read_attribute).with('comments_count').returns(100)
+ author.stubs(:_read_attribute).with('comments_count').returns(100)
assert_equal 100, author.comments.size
assert !author.comments.loaded?
end
@@ -642,7 +651,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
def test_preload_nil_polymorphic_belongs_to
assert_nothing_raised do
- taggings = Tagging.find(:all, :include => :taggable, :conditions => ['taggable_type IS NULL'])
+ Tagging.find(:all, :include => :taggable, :conditions => ['taggable_type IS NULL'])
end
end
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index dd8152b219..83c605d2bb 100644
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -120,7 +120,7 @@ class AssociationsTest < ActiveRecord::TestCase
def test_force_reload_is_uncached
firm = Firm.create!("name" => "A New Firm, Inc")
- client = Client.create!("name" => "TheClient.com", :firm => firm)
+ Client.create!("name" => "TheClient.com", :firm => firm)
ActiveRecord::Base.cache do
firm.clients.each {}
assert_queries(0) { assert_not_nil firm.clients.each {} }
@@ -270,17 +270,17 @@ class OverridingAssociationsTest < ActiveRecord::TestCase
def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited
# redeclared association on AR descendant should not inherit callbacks from superclass
- callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
+ callbacks = PeopleList.before_add_for_has_and_belongs_to_many
assert_equal([:enlist], callbacks)
- callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_and_belongs_to_many)
+ callbacks = DifferentPeopleList.before_add_for_has_and_belongs_to_many
assert_equal([], callbacks)
end
def test_has_many_association_redefinition_callbacks_should_differ_and_not_inherited
# redeclared association on AR descendant should not inherit callbacks from superclass
- callbacks = PeopleList.read_inheritable_attribute(:before_add_for_has_many)
+ callbacks = PeopleList.before_add_for_has_many
assert_equal([:enlist], callbacks)
- callbacks = DifferentPeopleList.read_inheritable_attribute(:before_add_for_has_many)
+ callbacks = DifferentPeopleList.before_add_for_has_many
assert_equal([], callbacks)
end
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index ab9a65944f..a29e4349d6 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -86,6 +86,15 @@ class AttributeMethodsTest < ActiveRecord::TestCase
assert !topic.respond_to?(:nothingness)
end
+ # Syck calls respond_to? before actually calling initialize
+ def test_respond_to_with_allocated_object
+ topic = Topic.allocate
+ assert !topic.respond_to?("nothingness")
+ assert !topic.respond_to?(:nothingness)
+ assert_respond_to topic, "title"
+ assert_respond_to topic, :title
+ end
+
def test_array_content
topic = Topic.new
topic.content = %w( one two three )
@@ -96,7 +105,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
def test_read_attributes_before_type_cast
category = Category.new({:name=>"Test categoty", :type => nil})
- category_attrs = {"name"=>"Test categoty", "type" => nil, "categorizations_count" => nil}
+ category_attrs = {"name"=>"Test categoty", "id" => nil, "type" => nil, "categorizations_count" => nil}
assert_equal category_attrs , category.attributes_before_type_cast
end
@@ -238,6 +247,12 @@ class AttributeMethodsTest < ActiveRecord::TestCase
# puts ""
end
+ def test_read_overridden_attribute
+ topic = Topic.new(:title => 'a')
+ def topic.title() 'b' end
+ assert_equal 'a', topic[:title]
+ end
+
def test_query_attribute_string
[nil, "", " "].each do |value|
assert_equal false, Topic.new(:author_name => value).author_name?
@@ -568,7 +583,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
def test_bulk_update_respects_access_control
privatize("title=(value)")
- assert_raise(ActiveRecord::UnknownAttributeError) { topic = @target.new(:title => "Rants about pants") }
+ assert_raise(ActiveRecord::UnknownAttributeError) { @target.new(:title => "Rants about pants") }
assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { :title => "Ants in pants" } }
end
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index 89be94c81f..11c0c5b0ef 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -83,14 +83,14 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
assert !firm.build_account_using_primary_key.valid?
assert firm.save
- assert firm.account_using_primary_key.new_record?
+ assert !firm.account_using_primary_key.persisted?
end
def test_save_fails_for_invalid_has_one
firm = Firm.find(:first)
assert firm.valid?
- firm.account = Account.new
+ firm.build_account
assert !firm.account.valid?
assert !firm.valid?
@@ -102,7 +102,7 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
firm = Firm.find(:first)
assert firm.valid?
- firm.unvalidated_account = Account.new
+ firm.build_unvalidated_account
assert !firm.unvalidated_account.valid?
assert firm.valid?
@@ -114,10 +114,10 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
account = firm.account.build("credit_limit" => 1000)
assert_equal account, firm.account
- assert account.new_record?
+ assert !account.persisted?
assert firm.save
assert_equal account, firm.account
- assert !account.new_record?
+ assert account.persisted?
end
def test_build_before_either_saved
@@ -125,16 +125,16 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
firm.account = account = Account.new("credit_limit" => 1000)
assert_equal account, firm.account
- assert account.new_record?
+ assert !account.persisted?
assert firm.save
assert_equal account, firm.account
- assert !account.new_record?
+ assert account.persisted?
end
def test_assignment_before_parent_saved
firm = Firm.new("name" => "GlobalMegaCorp")
firm.account = a = Account.find(1)
- assert firm.new_record?
+ assert !firm.persisted?
assert_equal a, firm.account
assert firm.save
assert_equal a, firm.account
@@ -144,12 +144,12 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
def test_assignment_before_either_saved
firm = Firm.new("name" => "GlobalMegaCorp")
firm.account = a = Account.new("credit_limit" => 1000)
- assert firm.new_record?
- assert a.new_record?
+ assert !firm.persisted?
+ assert !a.persisted?
assert_equal a, firm.account
assert firm.save
- assert !firm.new_record?
- assert !a.new_record?
+ assert firm.persisted?
+ assert a.persisted?
assert_equal a, firm.account
assert_equal a, firm.account(true)
end
@@ -163,15 +163,15 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
firm.account = Account.find(:first)
assert_queries(Firm.partial_updates? ? 0 : 1) { firm.save! }
- firm = Firm.find(:first).clone
+ firm = Firm.find(:first).dup
firm.account = Account.find(:first)
assert_queries(2) { firm.save! }
- firm = Firm.find(:first).clone
- firm.account = Account.find(:first).clone
+ firm = Firm.find(:first).dup
+ firm.account = Account.find(:first).dup
assert_queries(2) { firm.save! }
end
-
+
def test_callbacks_firing_order_on_create
eye = Eye.create(:iris_attributes => {:color => 'honey'})
assert_equal [true, false], eye.after_create_callbacks_stack
@@ -203,7 +203,7 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
assert !client.firm.valid?
assert client.save
- assert client.firm.new_record?
+ assert !client.firm.persisted?
end
def test_save_fails_for_invalid_belongs_to
@@ -232,10 +232,10 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
apple = Firm.new("name" => "Apple")
client.firm = apple
assert_equal apple, client.firm
- assert apple.new_record?
+ assert !apple.persisted?
assert client.save
assert apple.save
- assert !apple.new_record?
+ assert apple.persisted?
assert_equal apple, client.firm
assert_equal apple, client.firm(true)
end
@@ -244,11 +244,11 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
final_cut = Client.new("name" => "Final Cut")
apple = Firm.new("name" => "Apple")
final_cut.firm = apple
- assert final_cut.new_record?
- assert apple.new_record?
+ assert !final_cut.persisted?
+ assert !apple.persisted?
assert final_cut.save
- assert !final_cut.new_record?
- assert !apple.new_record?
+ assert final_cut.persisted?
+ assert apple.persisted?
assert_equal apple, final_cut.firm
assert_equal apple, final_cut.firm(true)
end
@@ -340,6 +340,13 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test
tags(:misc).create_tagging(:taggable => posts(:thinking))
assert_equal num_tagging + 1, Tagging.count
end
+
+ def test_build_and_then_save_parent_should_not_reload_target
+ client = Client.find(:first)
+ apple = client.build_firm(:name => "Apple")
+ client.save!
+ assert_no_queries { assert_equal apple, client.firm }
+ end
end
class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
@@ -348,23 +355,21 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_invalid_adding
firm = Firm.find(1)
assert !(firm.clients_of_firm << c = Client.new)
- assert c.new_record?
+ assert !c.persisted?
assert !firm.valid?
assert !firm.save
- assert c.new_record?
+ assert !c.persisted?
end
def test_invalid_adding_before_save
- no_of_firms = Firm.count
- no_of_clients = Client.count
new_firm = Firm.new("name" => "A New Firm, Inc")
new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")])
- assert c.new_record?
+ assert !c.persisted?
assert !c.valid?
assert !new_firm.valid?
assert !new_firm.save
- assert c.new_record?
- assert new_firm.new_record?
+ assert !c.persisted?
+ assert !new_firm.persisted?
end
def test_invalid_adding_with_validate_false
@@ -375,7 +380,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert firm.valid?
assert !client.valid?
assert firm.save
- assert client.new_record?
+ assert !client.persisted?
end
def test_valid_adding_with_validate_false
@@ -386,22 +391,22 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert firm.valid?
assert client.valid?
- assert client.new_record?
+ assert !client.persisted?
firm.unvalidated_clients_of_firm << client
assert firm.save
- assert !client.new_record?
+ assert client.persisted?
assert_equal no_of_clients + 1, Client.count
end
def test_invalid_build
new_client = companies(:first_firm).clients_of_firm.build
- assert new_client.new_record?
+ assert !new_client.persisted?
assert !new_client.valid?
assert_equal new_client, companies(:first_firm).clients_of_firm.last
assert !companies(:first_firm).save
- assert new_client.new_record?
+ assert !new_client.persisted?
assert_equal 1, companies(:first_firm).clients_of_firm(true).size
end
@@ -420,8 +425,8 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
assert_equal no_of_firms, Firm.count # Firm was not saved to database.
assert_equal no_of_clients, Client.count # Clients were not saved to database.
assert new_firm.save
- assert !new_firm.new_record?
- assert !c.new_record?
+ assert new_firm.persisted?
+ assert c.persisted?
assert_equal new_firm, c.firm
assert_equal no_of_firms + 1, Firm.count # Firm was saved to database.
assert_equal no_of_clients + 2, Client.count # Clients were saved to database.
@@ -455,13 +460,13 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(2) { assert company.save }
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal 2, company.clients_of_firm(true).size
end
def test_build_many_before_save
company = companies(:first_firm)
- new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
+ assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
company.name += '-changed'
assert_queries(3) { assert company.save }
@@ -475,13 +480,13 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
company.name += '-changed'
assert_queries(2) { assert company.save }
- assert !new_client.new_record?
+ assert new_client.persisted?
assert_equal 2, company.clients_of_firm(true).size
end
def test_build_many_via_block_before_save
company = companies(:first_firm)
- new_clients = assert_no_queries do
+ assert_no_queries do
company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client|
client.name = "changed"
end
@@ -507,67 +512,67 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
new_account = Account.new("credit_limit" => 1000)
new_firm = Firm.new("name" => "some firm")
- assert new_firm.new_record?
+ assert !new_firm.persisted?
new_account.firm = new_firm
new_account.save!
- assert !new_firm.new_record?
+ assert new_firm.persisted?
new_account = Account.new("credit_limit" => 1000)
new_autosaved_firm = Firm.new("name" => "some firm")
- assert new_autosaved_firm.new_record?
+ assert !new_autosaved_firm.persisted?
new_account.unautosaved_firm = new_autosaved_firm
new_account.save!
- assert new_autosaved_firm.new_record?
+ assert !new_autosaved_firm.persisted?
end
def test_autosave_new_record_on_has_one_can_be_disabled_per_relationship
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.account = account
firm.save!
- assert !account.new_record?
+ assert account.persisted?
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
firm.unautosaved_account = account
- assert account.new_record?
+ assert !account.persisted?
firm.unautosaved_account = account
firm.save!
- assert account.new_record?
+ assert !account.persisted?
end
def test_autosave_new_record_on_has_many_can_be_disabled_per_relationship
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.accounts << account
firm.save!
- assert !account.new_record?
+ assert account.persisted?
firm = Firm.new("name" => "some firm")
account = Account.new("credit_limit" => 1000)
- assert account.new_record?
+ assert !account.persisted?
firm.unautosaved_accounts << account
firm.save!
- assert account.new_record?
+ assert !account.persisted?
end
end
class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -669,10 +674,21 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
end
end
+ @ship.pirate.catchphrase = "Changed Catchphrase"
+
assert_raise(RuntimeError) { assert !@ship.save }
assert_not_nil @ship.reload.pirate
end
+ def test_should_save_changed_child_objects_if_parent_is_saved
+ @pirate = @ship.create_pirate(:catchphrase => "Don' botharrr talkin' like one, savvy?")
+ @parrot = @pirate.parrots.create!(:name => 'Posideons Killer')
+ @parrot.name = "NewName"
+ @ship.save
+
+ assert_equal 'NewName', @parrot.reload.name
+ end
+
# has_many & has_and_belongs_to
%w{ parrots birds }.each do |association_name|
define_method("test_should_destroy_#{association_name}_as_part_of_the_save_transaction_if_they_were_marked_for_destroyal") do
@@ -781,7 +797,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
end
class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -901,7 +917,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
end
class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@ship = Ship.create(:name => 'Nights Dirty Lightning')
@@ -1148,7 +1164,7 @@ module AutosaveAssociationOnACollectionAssociationTests
end
class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@association_name = :birds
@@ -1162,7 +1178,7 @@ class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
end
class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@association_name = :parrots
@@ -1177,7 +1193,7 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::T
end
class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -1193,7 +1209,7 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
end
class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -1214,7 +1230,7 @@ class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::Tes
end
class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -1234,7 +1250,7 @@ class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord::
end
class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -1256,7 +1272,7 @@ class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::Test
end
class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.new
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index e63e1fbe09..a58d5dec81 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -19,6 +19,7 @@ require 'models/minimalistic'
require 'models/warehouse_thing'
require 'models/parrot'
require 'models/loose_person'
+require 'models/edge'
require 'rexml/document'
require 'active_support/core_ext/exception'
@@ -48,6 +49,10 @@ class Boolean < ActiveRecord::Base; end
class BasicsTest < ActiveRecord::TestCase
fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts
+ def test_primary_key_with_no_id
+ assert_nil Edge.primary_key
+ end
+
def test_select_symbol
topic_ids = Topic.select(:id).map(&:id).sort
assert_equal Topic.find(:all).map(&:id).sort, topic_ids
@@ -182,7 +187,7 @@ class BasicsTest < ActiveRecord::TestCase
def test_initialize_with_invalid_attribute
begin
- topic = Topic.new({ "title" => "test",
+ Topic.new({ "title" => "test",
"last_read(1i)" => "2005", "last_read(2i)" => "2", "last_read(3i)" => "31"})
rescue ActiveRecord::MultiparameterAssignmentErrors => ex
assert_equal(1, ex.errors.size)
@@ -397,6 +402,15 @@ class BasicsTest < ActiveRecord::TestCase
assert_not_equal Topic.new, Topic.new
end
+ def test_equality_of_destroyed_records
+ topic_1 = Topic.new(:title => 'test_1')
+ topic_1.save
+ topic_2 = Topic.find(topic_1.id)
+ topic_1.destroy
+ assert_equal topic_1, topic_2
+ assert_equal topic_2, topic_1
+ end
+
def test_hashing
assert_equal [ Topic.find(1) ], [ Topic.find(2).topic ] & [ Topic.find(1) ]
end
@@ -656,68 +670,69 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_new_record_returns_boolean
- assert_equal true, Topic.new.new_record?
- assert_equal false, Topic.find(1).new_record?
+ assert_equal false, Topic.new.persisted?
+ assert_equal true, Topic.find(1).persisted?
end
- def test_clone
+ def test_dup
topic = Topic.find(1)
- cloned_topic = nil
- assert_nothing_raised { cloned_topic = topic.clone }
- assert_equal topic.title, cloned_topic.title
- assert cloned_topic.new_record?
+ duped_topic = nil
+ assert_nothing_raised { duped_topic = topic.dup }
+ assert_equal topic.title, duped_topic.title
+ assert !duped_topic.persisted?
- # test if the attributes have been cloned
+ # test if the attributes have been duped
topic.title = "a"
- cloned_topic.title = "b"
+ duped_topic.title = "b"
assert_equal "a", topic.title
- assert_equal "b", cloned_topic.title
+ assert_equal "b", duped_topic.title
- # test if the attribute values have been cloned
+ # test if the attribute values have been duped
topic.title = {"a" => "b"}
- cloned_topic = topic.clone
- cloned_topic.title["a"] = "c"
+ duped_topic = topic.dup
+ duped_topic.title["a"] = "c"
assert_equal "b", topic.title["a"]
- # test if attributes set as part of after_initialize are cloned correctly
- assert_equal topic.author_email_address, cloned_topic.author_email_address
+ # test if attributes set as part of after_initialize are duped correctly
+ assert_equal topic.author_email_address, duped_topic.author_email_address
# test if saved clone object differs from original
- cloned_topic.save
- assert !cloned_topic.new_record?
- assert_not_equal cloned_topic.id, topic.id
+ duped_topic.save
+ assert duped_topic.persisted?
+ assert_not_equal duped_topic.id, topic.id
- cloned_topic.reload
+ duped_topic.reload
# FIXME: I think this is poor behavior, and will fix it with #5686
- assert_equal({'a' => 'c'}.to_s, cloned_topic.title)
+ assert_equal({'a' => 'c'}.to_yaml, duped_topic.title)
end
- def test_clone_with_aggregate_of_same_name_as_attribute
+ def test_dup_with_aggregate_of_same_name_as_attribute
dev = DeveloperWithAggregate.find(1)
assert_kind_of DeveloperSalary, dev.salary
- clone = nil
- assert_nothing_raised { clone = dev.clone }
- assert_kind_of DeveloperSalary, clone.salary
- assert_equal dev.salary.amount, clone.salary.amount
- assert clone.new_record?
+ dup = nil
+ assert_nothing_raised { dup = dev.dup }
+ assert_kind_of DeveloperSalary, dup.salary
+ assert_equal dev.salary.amount, dup.salary.amount
+ assert !dup.persisted?
- # test if the attributes have been cloned
- original_amount = clone.salary.amount
+ # test if the attributes have been dupd
+ original_amount = dup.salary.amount
dev.salary.amount = 1
- assert_equal original_amount, clone.salary.amount
+ assert_equal original_amount, dup.salary.amount
- assert clone.save
- assert !clone.new_record?
- assert_not_equal clone.id, dev.id
+ assert dup.save
+ assert dup.persisted?
+ assert_not_equal dup.id, dev.id
end
- def test_clone_does_not_clone_associations
+ def test_dup_does_not_copy_associations
author = authors(:david)
assert_not_equal [], author.posts
+ author.send(:clear_association_cache)
- author_clone = author.clone
- assert_equal [], author_clone.posts
+ author_dup = author.dup
+ assert_equal [], author_dup.posts
end
def test_clone_preserves_subtype
@@ -756,22 +771,22 @@ class BasicsTest < ActiveRecord::TestCase
assert !cloned_developer.salary_changed? # ... and cloned instance should behave same
end
- def test_clone_of_saved_object_marks_attributes_as_dirty
+ def test_dup_of_saved_object_marks_attributes_as_dirty
developer = Developer.create! :name => 'Bjorn', :salary => 100000
assert !developer.name_changed?
assert !developer.salary_changed?
- cloned_developer = developer.clone
+ cloned_developer = developer.dup
assert cloned_developer.name_changed? # both attributes differ from defaults
assert cloned_developer.salary_changed?
end
- def test_clone_of_saved_object_marks_as_dirty_only_changed_attributes
+ def test_dup_of_saved_object_marks_as_dirty_only_changed_attributes
developer = Developer.create! :name => 'Bjorn'
assert !developer.name_changed? # both attributes of saved object should be threated as not changed
assert !developer.salary_changed?
- cloned_developer = developer.clone
+ cloned_developer = developer.dup
assert cloned_developer.name_changed? # ... but on cloned object should be
assert !cloned_developer.salary_changed? # ... BUT salary has non-nil default which should be threated as not changed on cloned instance
end
@@ -963,7 +978,6 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_nil_serialized_attribute_with_class_constraint
- myobj = MyObject.new('value1', 'value2')
topic = Topic.new
assert_nil topic.content
end
@@ -988,6 +1002,22 @@ class BasicsTest < ActiveRecord::TestCase
Topic.serialize(:content)
end
+ def test_serialized_boolean_value_true
+ Topic.serialize(:content)
+ topic = Topic.new(:content => true)
+ assert topic.save
+ topic = topic.reload
+ assert_equal topic.content, true
+ end
+
+ def test_serialized_boolean_value_false
+ Topic.serialize(:content)
+ topic = Topic.new(:content => false)
+ assert topic.save
+ topic = topic.reload
+ assert_equal topic.content, false
+ end
+
def test_quote
author_name = "\\ \001 ' \n \\n \""
topic = Topic.create('author_name' => author_name)
@@ -1043,9 +1073,14 @@ class BasicsTest < ActiveRecord::TestCase
end
def test_define_attr_method_with_block
- k = Class.new( ActiveRecord::Base )
- k.send(:define_attr_method, :primary_key) { "sys_" + original_primary_key }
- assert_equal "sys_id", k.primary_key
+ k = Class.new( ActiveRecord::Base ) do
+ class << self
+ attr_accessor :foo_key
+ end
+ end
+ k.foo_key = "id"
+ k.send(:define_attr_method, :foo_key) { "sys_" + original_foo_key }
+ assert_equal "sys_id", k.foo_key
end
def test_set_table_name_with_value
@@ -1084,6 +1119,7 @@ class BasicsTest < ActiveRecord::TestCase
def test_set_primary_key_with_block
k = Class.new( ActiveRecord::Base )
+ k.primary_key = 'id'
k.set_primary_key { "sys_" + original_primary_key }
assert_equal "sys_id", k.primary_key
end
@@ -1353,7 +1389,7 @@ class BasicsTest < ActiveRecord::TestCase
def test_inspect_instance
topic = topics(:first)
- assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, parent_title: nil, type: nil, group: nil>), topic.inspect
+ assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, parent_title: nil, type: nil, group: nil, created_at: "#{topic.created_at.to_s(:db)}", updated_at: "#{topic.updated_at.to_s(:db)}">), topic.inspect
end
def test_inspect_new_instance
@@ -1435,10 +1471,6 @@ class BasicsTest < ActiveRecord::TestCase
ActiveRecord::Base.logger = original_logger
end
- def test_dup
- assert !Minimalistic.new.freeze.dup.frozen?
- end
-
def test_compute_type_success
assert_equal Author, ActiveRecord::Base.send(:compute_type, 'Author')
end
@@ -1471,4 +1503,11 @@ class BasicsTest < ActiveRecord::TestCase
ensure
Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost)
end
+
+ def test_marshal_round_trip
+ expected = posts(:welcome)
+ actual = Marshal.load(Marshal.dump(expected))
+
+ assert_equal expected.attributes, actual.attributes
+ end
end
diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb
index dcc49e12ca..6f65fb96d1 100644
--- a/activerecord/test/cases/batches_test.rb
+++ b/activerecord/test/cases/batches_test.rb
@@ -7,6 +7,7 @@ class EachTest < ActiveRecord::TestCase
def setup
@posts = Post.order("id asc")
@total = Post.count
+ Post.count('id') # preheat arel's table cache
end
def test_each_should_excecute_one_query_per_batch
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index 61fbf01a50..644c9cb528 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -23,6 +23,11 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal 53.0, value
end
+ def test_should_return_decimal_average_of_integer_field
+ value = Account.average(:id)
+ assert_equal 3.5, value
+ end
+
def test_should_return_nil_as_average
assert_nil NumericData.average(:bank_balance)
end
@@ -54,6 +59,19 @@ class CalculationsTest < ActiveRecord::TestCase
c = Account.sum(:credit_limit, :group => :firm_id)
[1,6,2].each { |firm_id| assert c.keys.include?(firm_id) }
end
+
+ def test_should_group_by_multiple_fields
+ c = Account.count(:all, :group => ['firm_id', :credit_limit])
+ [ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert c.keys.include?(firm_and_limit) }
+ end
+
+ def test_should_group_by_multiple_fields_having_functions
+ c = Topic.group(:author_name, 'COALESCE(type, title)').count(:all)
+ assert_equal 1, c[["Carl", "The Third Topic of the day"]]
+ assert_equal 1, c[["Mary", "Reply"]]
+ assert_equal 1, c[["David", "The First Topic"]]
+ assert_equal 1, c[["Carl", "Reply"]]
+ end
def test_should_group_by_summed_field
c = Account.sum(:credit_limit, :group => :firm_id)
diff --git a/activerecord/test/cases/clone_test.rb b/activerecord/test/cases/clone_test.rb
new file mode 100644
index 0000000000..d91646efca
--- /dev/null
+++ b/activerecord/test/cases/clone_test.rb
@@ -0,0 +1,33 @@
+require "cases/helper"
+require 'models/topic'
+
+module ActiveRecord
+ class CloneTest < ActiveRecord::TestCase
+ fixtures :topics
+
+ def test_persisted
+ topic = Topic.first
+ cloned = topic.clone
+ assert topic.persisted?, 'topic persisted'
+ assert cloned.persisted?, 'topic persisted'
+ assert !cloned.new_record?, 'topic is not new'
+ end
+
+ def test_stays_frozen
+ topic = Topic.first
+ topic.freeze
+
+ cloned = topic.clone
+ assert cloned.persisted?, 'topic persisted'
+ assert !cloned.new_record?, 'topic is not new'
+ assert cloned.frozen?, 'topic should be frozen'
+ end
+
+ def test_shallow
+ topic = Topic.first
+ cloned = topic.clone
+ topic.author_name = 'Aaron'
+ assert_equal 'Aaron', cloned.author_name
+ end
+ end
+end
diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb
index f0ec5c751c..2e18117895 100644
--- a/activerecord/test/cases/connection_pool_test.rb
+++ b/activerecord/test/cases/connection_pool_test.rb
@@ -38,9 +38,9 @@ module ActiveRecord
assert_not_nil connection
end
end
-
+
threads.each {|t| t.join}
-
+
Thread.new do
threads.each do |t|
thread_ids = pool.instance_variable_get(:@reserved_connections).keys
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index bde93d1c85..a6738fb654 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -338,13 +338,13 @@ class DirtyTest < ActiveRecord::TestCase
assert !pirate.changed?
end
- def test_cloned_objects_should_not_copy_dirty_flag_from_creator
+ def test_dup_objects_should_not_copy_dirty_flag_from_creator
pirate = Pirate.create!(:catchphrase => "shiver me timbers")
- pirate_clone = pirate.clone
- pirate_clone.reset_catchphrase!
+ pirate_dup = pirate.dup
+ pirate_dup.reset_catchphrase!
pirate.catchphrase = "I love Rum"
assert pirate.catchphrase_changed?
- assert !pirate_clone.catchphrase_changed?
+ assert !pirate_dup.catchphrase_changed?
end
def test_reverted_changes_are_not_dirty
@@ -395,6 +395,20 @@ class DirtyTest < ActiveRecord::TestCase
end
end
+ def test_save_always_should_update_timestamps_when_serialized_attributes_are_present
+ with_partial_updates(Topic) do
+ topic = Topic.create!(:content => {:a => "a"})
+ topic.save!
+
+ updated_at = topic.updated_at
+ topic.content[:hello] = 'world'
+ topic.save!
+
+ assert_not_equal updated_at, topic.updated_at
+ assert_equal 'world', topic.content[:hello]
+ end
+ end
+
def test_save_should_not_save_serialized_attribute_with_partial_updates_if_not_present
with_partial_updates(Topic) do
Topic.create!(:author_name => 'Bill', :content => {:a => "a"})
diff --git a/activerecord/test/cases/dup_test.rb b/activerecord/test/cases/dup_test.rb
new file mode 100644
index 0000000000..0236f9b0a1
--- /dev/null
+++ b/activerecord/test/cases/dup_test.rb
@@ -0,0 +1,103 @@
+require "cases/helper"
+require 'models/topic'
+
+module ActiveRecord
+ class DupTest < ActiveRecord::TestCase
+ fixtures :topics
+
+ def test_dup
+ assert !Topic.new.freeze.dup.frozen?
+ end
+
+ def test_not_readonly
+ topic = Topic.first
+
+ duped = topic.dup
+ assert !duped.readonly?, 'should not be readonly'
+ end
+
+ def test_is_readonly
+ topic = Topic.first
+ topic.readonly!
+
+ duped = topic.dup
+ assert duped.readonly?, 'should be readonly'
+ end
+
+ def test_dup_not_persisted
+ topic = Topic.first
+ duped = topic.dup
+
+ assert !duped.persisted?, 'topic not persisted'
+ assert duped.new_record?, 'topic is new'
+ end
+
+ def test_dup_has_no_id
+ topic = Topic.first
+ duped = topic.dup
+ assert_nil duped.id
+ end
+
+ def test_dup_with_modified_attributes
+ topic = Topic.first
+ topic.author_name = 'Aaron'
+ duped = topic.dup
+ assert_equal 'Aaron', duped.author_name
+ end
+
+ def test_dup_with_changes
+ dbtopic = Topic.first
+ topic = Topic.new
+
+ topic.attributes = dbtopic.attributes
+
+ #duped has no timestamp values
+ duped = dbtopic.dup
+
+ #clear topic timestamp values
+ topic.send(:clear_timestamp_attributes)
+
+ assert_equal topic.changes, duped.changes
+ end
+
+ def test_dup_topics_are_independent
+ topic = Topic.first
+ topic.author_name = 'Aaron'
+ duped = topic.dup
+
+ duped.author_name = 'meow'
+
+ assert_not_equal topic.changes, duped.changes
+ end
+
+ def test_dup_attributes_are_independent
+ topic = Topic.first
+ duped = topic.dup
+
+ duped.author_name = 'meow'
+ topic.author_name = 'Aaron'
+
+ assert_equal 'Aaron', topic.author_name
+ assert_equal 'meow', duped.author_name
+ end
+
+ def test_dup_timestamps_are_cleared
+ topic = Topic.first
+ assert_not_nil topic.updated_at
+ assert_not_nil topic.created_at
+
+ # temporary change to the topic object
+ topic.updated_at -= 3.days
+
+ #dup should not preserve the timestamps if present
+ new_topic = topic.dup
+ assert_nil new_topic.updated_at
+ assert_nil new_topic.created_at
+
+ new_topic.save
+ assert_not_nil new_topic.updated_at
+ assert_not_nil new_topic.created_at
+ end
+
+ end
+end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index c058196078..c35590b84b 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -10,6 +10,7 @@ require 'models/entrant'
require 'models/project'
require 'models/developer'
require 'models/customer'
+require 'models/toy'
class FinderTest < ActiveRecord::TestCase
fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers, :categories, :categorizations
@@ -726,7 +727,7 @@ class FinderTest < ActiveRecord::TestCase
sig38 = Company.find_or_create_by_name("38signals")
assert_equal number_of_companies + 1, Company.count
assert_equal sig38, Company.find_or_create_by_name("38signals")
- assert !sig38.new_record?
+ assert sig38.persisted?
end
def test_find_or_create_from_two_attributes
@@ -734,7 +735,7 @@ class FinderTest < ActiveRecord::TestCase
another = Topic.find_or_create_by_title_and_author_name("Another topic","John")
assert_equal number_of_topics + 1, Topic.count
assert_equal another, Topic.find_or_create_by_title_and_author_name("Another topic", "John")
- assert !another.new_record?
+ assert another.persisted?
end
def test_find_or_create_from_two_attributes_with_one_being_an_aggregate
@@ -742,7 +743,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance_and_name(Money.new(123), "Elizabeth")
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance(Money.new(123), "Elizabeth")
- assert !created_customer.new_record?
+ assert created_customer.persisted?
end
def test_find_or_create_from_one_attribute_and_hash
@@ -750,7 +751,7 @@ class FinderTest < ActiveRecord::TestCase
sig38 = Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
assert_equal number_of_companies + 1, Company.count
assert_equal sig38, Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})
- assert !sig38.new_record?
+ assert sig38.persisted?
assert_equal "38signals", sig38.name
assert_equal 17, sig38.firm_id
assert_equal 23, sig38.client_of
@@ -761,7 +762,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance(Money.new(123))
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance(Money.new(123))
- assert !created_customer.new_record?
+ assert created_customer.persisted?
end
def test_find_or_create_from_one_aggregate_attribute_and_hash
@@ -771,7 +772,7 @@ class FinderTest < ActiveRecord::TestCase
created_customer = Customer.find_or_create_by_balance({:balance => balance, :name => name})
assert_equal number_of_customers + 1, Customer.count
assert_equal created_customer, Customer.find_or_create_by_balance({:balance => balance, :name => name})
- assert !created_customer.new_record?
+ assert created_customer.persisted?
assert_equal balance, created_customer.balance
assert_equal name, created_customer.name
end
@@ -779,13 +780,13 @@ class FinderTest < ActiveRecord::TestCase
def test_find_or_initialize_from_one_attribute
sig38 = Company.find_or_initialize_by_name("38signals")
assert_equal "38signals", sig38.name
- assert sig38.new_record?
+ assert !sig38.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute
new_customer = Customer.find_or_initialize_by_balance(Money.new(123))
assert_equal 123, new_customer.balance.amount
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_or_initialize_from_one_attribute_should_not_set_attribute_even_when_protected
@@ -793,7 +794,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_not_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_not_set_attribute_even_when_protected
@@ -801,7 +802,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_not_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_one_attribute_should_set_attribute_even_when_protected
@@ -809,7 +810,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_set_attribute_even_when_protected
@@ -817,7 +818,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_one_attribute_should_set_attribute_even_when_protected_and_also_set_the_hash
@@ -825,7 +826,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_from_one_attribute_should_set_attribute_even_when_protected_and_also_set_the_hash
@@ -833,7 +834,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000, c.rating
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_should_set_protected_attributes_if_given_as_block
@@ -841,7 +842,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert c.new_record?
+ assert !c.persisted?
end
def test_find_or_create_should_set_protected_attributes_if_given_as_block
@@ -849,7 +850,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_create_should_work_with_block_on_first_call
@@ -860,21 +861,21 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "Fortune 1000", c.name
assert_equal 1000.to_f, c.rating.to_f
assert c.valid?
- assert !c.new_record?
+ assert c.persisted?
end
def test_find_or_initialize_from_two_attributes
another = Topic.find_or_initialize_by_title_and_author_name("Another topic","John")
assert_equal "Another topic", another.title
assert_equal "John", another.author_name
- assert another.new_record?
+ assert !another.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute_and_one_not
new_customer = Customer.find_or_initialize_by_balance_and_name(Money.new(123), "Elizabeth")
assert_equal 123, new_customer.balance.amount
assert_equal "Elizabeth", new_customer.name
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_or_initialize_from_one_attribute_and_hash
@@ -882,7 +883,7 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "38signals", sig38.name
assert_equal 17, sig38.firm_id
assert_equal 23, sig38.client_of
- assert sig38.new_record?
+ assert !sig38.persisted?
end
def test_find_or_initialize_from_one_aggregate_attribute_and_hash
@@ -891,7 +892,7 @@ class FinderTest < ActiveRecord::TestCase
new_customer = Customer.find_or_initialize_by_balance({:balance => balance, :name => name})
assert_equal balance, new_customer.balance
assert_equal name, new_customer.name
- assert new_customer.new_record?
+ assert !new_customer.persisted?
end
def test_find_with_bad_sql
@@ -948,7 +949,7 @@ class FinderTest < ActiveRecord::TestCase
# http://dev.rubyonrails.org/ticket/6778
def test_find_ignores_previously_inserted_record
- post = Post.create!(:title => 'test', :body => 'it out')
+ Post.create!(:title => 'test', :body => 'it out')
assert_equal [], Post.find_all_by_id(nil)
end
@@ -981,7 +982,7 @@ class FinderTest < ActiveRecord::TestCase
def test_select_rows
assert_equal(
- [["1", nil, nil, "37signals"],
+ [["1", "1", nil, "37signals"],
["2", "1", "2", "Summit"],
["3", "1", "1", "Microsoft"]],
Company.connection.select_rows("SELECT id, firm_id, client_of, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! {|i| i.map! {|j| j.to_s unless j.nil?}})
@@ -1010,6 +1011,15 @@ class FinderTest < ActiveRecord::TestCase
end
end
+ def test_find_one_message_with_custom_primary_key
+ Toy.set_primary_key :name
+ begin
+ Toy.find 'Hello World!'
+ rescue ActiveRecord::RecordNotFound => e
+ assert_equal 'Couldn\'t find Toy with name=Hello World!', e.message
+ end
+ end
+
protected
def bind(statement, *vars)
if vars.first.is_a?(Hash)
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index d5ef30e137..864a7a2acc 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -13,6 +13,7 @@ require 'models/category'
require 'models/parrot'
require 'models/pirate'
require 'models/treasure'
+require 'models/traffic_light'
require 'models/matey'
require 'models/ship'
require 'models/book'
@@ -24,7 +25,7 @@ class FixturesTest < ActiveRecord::TestCase
self.use_instantiated_fixtures = true
self.use_transactional_fixtures = false
- fixtures :topics, :developers, :accounts, :tasks, :categories, :funny_jokes, :binaries
+ fixtures :topics, :developers, :accounts, :tasks, :categories, :funny_jokes, :binaries, :traffic_lights
FIXTURES = %w( accounts binaries companies customers
developers developers_projects entrants
@@ -58,7 +59,7 @@ class FixturesTest < ActiveRecord::TestCase
end
def test_inserts
- topics = create_fixtures("topics")
+ create_fixtures("topics")
first_row = ActiveRecord::Base.connection.select_one("SELECT * FROM topics WHERE author_name = 'David'")
assert_equal("The First Topic", first_row["title"])
@@ -114,7 +115,7 @@ class FixturesTest < ActiveRecord::TestCase
end
def test_insert_with_datetime
- topics = create_fixtures("tasks")
+ create_fixtures("tasks")
first = Task.find(1)
assert first
end
@@ -204,6 +205,10 @@ class FixturesTest < ActiveRecord::TestCase
data.freeze
assert_equal data, @flowers.data
end
+
+ def test_serialized_fixtures
+ assert_equal ["Green", "Red", "Orange"], traffic_lights(:uk).state
+ end
end
if Account.connection.respond_to?(:reset_pk_sequence!)
@@ -240,7 +245,7 @@ if Account.connection.respond_to?(:reset_pk_sequence!)
def test_create_fixtures_resets_sequences_when_not_cached
@instances.each do |instance|
- max_id = create_fixtures(instance.class.table_name).inject(0) do |_max_id, (name, fixture)|
+ max_id = create_fixtures(instance.class.table_name).inject(0) do |_max_id, (_, fixture)|
fixture_id = fixture['id'].to_i
fixture_id > _max_id ? fixture_id : _max_id
end
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index f6ef155d66..2cc993b6ed 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -13,11 +13,6 @@ require 'active_record'
require 'active_support/dependencies'
require 'connection'
-begin
- require 'ruby-debug'
-rescue LoadError
-end
-
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
@@ -31,6 +26,15 @@ def current_adapter?(*types)
end
end
+def in_memory_db?
+ current_adapter?(:SQLiteAdapter) &&
+ ActiveRecord::Base.connection_pool.spec.config[:database] == ":memory:"
+end
+
+def supports_savepoints?
+ ActiveRecord::Base.connection.supports_savepoints?
+end
+
def with_env_tz(new_tz = 'US/Eastern')
old_tz, ENV['TZ'] = ENV['TZ'], new_tz
yield
@@ -48,6 +52,10 @@ end
ActiveRecord::Base.connection.class.class_eval do
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /SHOW FIELDS/]
+ # FIXME: this needs to be refactored so specific database can add their own
+ # ignored SQL. This ignored SQL is for Oracle.
+ IGNORED_SQL.concat [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from ((all|user)_tab_columns|(all|user)_triggers|(all|user)_constraints)/im]
+
def execute_with_query_record(sql, name = nil, &block)
$queries_executed ||= []
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
@@ -56,13 +64,13 @@ ActiveRecord::Base.connection.class.class_eval do
alias_method_chain :execute, :query_record
- def exec_with_query_record(sql, name = nil, binds = [], &block)
+ def exec_query_with_query_record(sql, name = nil, binds = [], &block)
$queries_executed ||= []
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
- exec_without_query_record(sql, name, binds, &block)
+ exec_query_without_query_record(sql, name, binds, &block)
end
- alias_method_chain :exec, :query_record
+ alias_method_chain :exec_query, :query_record
end
ActiveRecord::Base.connection.class.class_eval {
@@ -101,11 +109,11 @@ class ActiveSupport::TestCase
end
end
-# silence verbose schema loading
-original_stdout = $stdout
-$stdout = StringIO.new
+def load_schema
+ # silence verbose schema loading
+ original_stdout = $stdout
+ $stdout = StringIO.new
-begin
adapter_name = ActiveRecord::Base.connection.adapter_name.downcase
adapter_specific_schema_file = SCHEMA_ROOT + "/#{adapter_name}_specific_schema.rb"
@@ -118,6 +126,8 @@ ensure
$stdout = original_stdout
end
+load_schema
+
class << Time
unless method_defined? :now_before_time_travel
alias_method :now_before_time_travel, :now
@@ -134,4 +144,3 @@ class << Time
@now = nil
end
end
-
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index 31679b2efe..680d4ca5dd 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -16,7 +16,7 @@ class InheritanceTest < ActiveRecord::TestCase
def test_class_with_blank_sti_name
company = Company.find(:first)
- company = company.clone
+ company = company.dup
company.extend(Module.new {
def read_attribute(name)
return ' ' if name == 'type'
@@ -203,12 +203,12 @@ class InheritanceTest < ActiveRecord::TestCase
def test_eager_load_belongs_to_something_inherited
account = Account.find(1, :include => :firm)
- assert_not_nil account.instance_variable_get("@firm"), "nil proves eager load failed"
+ assert account.association_cache.key?(:firm), "nil proves eager load failed"
end
def test_eager_load_belongs_to_primary_key_quoting
con = Account.connection
- assert_sql(/\(#{con.quote_table_name('companies')}.#{con.quote_column_name('id')} = 1\)/) do
+ assert_sql(/#{con.quote_table_name('companies')}.#{con.quote_column_name('id')} = 1/) do
Account.find(1, :include => :firm)
end
end
@@ -219,6 +219,10 @@ class InheritanceTest < ActiveRecord::TestCase
switch_to_default_inheritance_column
end
+ def test_inherits_custom_primary_key
+ assert_equal Subscriber.primary_key, SpecialSubscriber.primary_key
+ end
+
def test_inheritance_without_mapping
assert_kind_of SpecialSubscriber, SpecialSubscriber.find("webster132")
assert_nothing_raised { s = SpecialSubscriber.new("name" => "And breaaaaathe!"); s.id = 'roger'; s.save }
diff --git a/activerecord/test/cases/invertible_migration_test.rb b/activerecord/test/cases/invertible_migration_test.rb
new file mode 100644
index 0000000000..afec64750e
--- /dev/null
+++ b/activerecord/test/cases/invertible_migration_test.rb
@@ -0,0 +1,57 @@
+require "cases/helper"
+
+module ActiveRecord
+ class InvertibleMigrationTest < ActiveRecord::TestCase
+ class SilentMigration < ActiveRecord::Migration
+ def write(text = '')
+ # sssshhhhh!!
+ end
+ end
+
+ class InvertibleMigration < SilentMigration
+ def change
+ create_table("horses") do |t|
+ t.column :content, :text
+ t.column :remind_at, :datetime
+ end
+ end
+ end
+
+ class NonInvertibleMigration < SilentMigration
+ def change
+ create_table("horses") do |t|
+ t.column :content, :text
+ t.column :remind_at, :datetime
+ end
+ remove_column "horses", :content
+ end
+ end
+
+ def teardown
+ if ActiveRecord::Base.connection.table_exists?("horses")
+ ActiveRecord::Base.connection.drop_table("horses")
+ end
+ end
+
+ def test_no_reverse
+ migration = NonInvertibleMigration.new
+ migration.migrate(:up)
+ assert_raises(IrreversibleMigration) do
+ migration.migrate(:down)
+ end
+ end
+
+ def test_up
+ migration = InvertibleMigration.new
+ migration.migrate(:up)
+ assert migration.connection.table_exists?("horses"), "horses should exist"
+ end
+
+ def test_down
+ migration = InvertibleMigration.new
+ migration.migrate :up
+ migration.migrate :down
+ assert !migration.connection.table_exists?("horses")
+ end
+ end
+end
diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb
index 233338498f..0558deb71b 100644
--- a/activerecord/test/cases/lifecycle_test.rb
+++ b/activerecord/test/cases/lifecycle_test.rb
@@ -9,10 +9,19 @@ class SpecialDeveloper < Developer; end
class SalaryChecker < ActiveRecord::Observer
observe :special_developer
+ attr_accessor :last_saved
def before_save(developer)
return developer.salary > 80000
end
+
+ module Implementation
+ def after_save(developer)
+ self.last_saved = developer
+ end
+ end
+ include Implementation
+
end
class TopicaAuditor < ActiveRecord::Observer
@@ -92,9 +101,10 @@ class LifecycleTest < ActiveRecord::TestCase
fixtures :topics, :developers, :minimalistics
def test_before_destroy
- original_count = Topic.count
- (topic_to_be_destroyed = Topic.find(1)).destroy
- assert_equal original_count - (1 + topic_to_be_destroyed.replies.size), Topic.count
+ topic = Topic.find(1)
+ assert_difference 'Topic.count', -(1 + topic.replies.size) do
+ topic.destroy
+ end
end
def test_auto_observer
@@ -179,4 +189,11 @@ class LifecycleTest < ActiveRecord::TestCase
developer = SpecialDeveloper.new :name => 'Rookie', :salary => 50000
assert !developer.save, "allowed to save a developer with too low salary"
end
+
+ test "able to call methods defined with included module" do # https://rails.lighthouseapp.com/projects/8994/tickets/6065-activerecordobserver-is-not-aware-of-method-added-by-including-modules
+ SalaryChecker.instance # activate
+ developer = SpecialDeveloper.create! :name => 'Roger', :salary => 100000
+ assert_equal developer, SalaryChecker.instance.last_saved
+ end
+
end
diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb
index 4ddcdc010b..2a72838d06 100644
--- a/activerecord/test/cases/locking_test.rb
+++ b/activerecord/test/cases/locking_test.rb
@@ -1,3 +1,4 @@
+require 'thread'
require "cases/helper"
require 'models/person'
require 'models/reader'
@@ -18,11 +19,6 @@ end
class OptimisticLockingTest < ActiveRecord::TestCase
fixtures :people, :legacy_things, :references
- # need to disable transactional fixtures, because otherwise the sqlite3
- # adapter (at least) chokes when we try and change the schema in the middle
- # of a test (see test_increment_counter_*).
- self.use_transactional_fixtures = false
-
def test_lock_existing
p1 = Person.find(1)
p2 = Person.find(1)
@@ -151,6 +147,33 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_equal "unchangeable name", p.first_name
end
+ def test_quote_table_name
+ ref = references(:michael_magician)
+ ref.favourite = !ref.favourite
+ assert ref.save
+ end
+
+ # Useful for partial updates, don't only update the lock_version if there
+ # is nothing else being updated.
+ def test_update_without_attributes_does_not_only_update_lock_version
+ assert_nothing_raised do
+ p1 = Person.create!(:first_name => 'anika')
+ lock_version = p1.lock_version
+ p1.save
+ p1.reload
+ assert_equal lock_version, p1.lock_version
+ end
+ end
+end
+
+class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
+ fixtures :people, :legacy_things, :references
+
+ # need to disable transactional fixtures, because otherwise the sqlite3
+ # adapter (at least) chokes when we try and change the schema in the middle
+ # of a test (see test_increment_counter_*).
+ self.use_transactional_fixtures = false
+
{ :lock_version => Person, :custom_lock_version => LegacyThing }.each do |name, model|
define_method("test_increment_counter_updates_#{name}") do
counter_test model, 1 do |id|
@@ -197,24 +220,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_raises(ActiveRecord::RecordNotFound) { LegacyThing.find(t.id) }
end
- def test_quote_table_name
- ref = references(:michael_magician)
- ref.favourite = !ref.favourite
- assert ref.save
- end
-
- # Useful for partial updates, don't only update the lock_version if there
- # is nothing else being updated.
- def test_update_without_attributes_does_not_only_update_lock_version
- assert_nothing_raised do
- p1 = Person.create!(:first_name => 'anika')
- lock_version = p1.lock_version
- p1.save
- p1.reload
- assert_equal lock_version, p1.lock_version
- end
- end
-
private
def add_counter_column_to(model, col='test_count')
@@ -251,7 +256,7 @@ end
# TODO: The Sybase, and OpenBase adapters currently have no support for pessimistic locking
-unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter)
+unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db?
class PessimisticLockingTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
fixtures :people, :readers
diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb
index f3d3d62830..e3ba65b4fa 100644
--- a/activerecord/test/cases/method_scoping_test.rb
+++ b/activerecord/test/cases/method_scoping_test.rb
@@ -14,7 +14,7 @@ class MethodScopingTest < ActiveRecord::TestCase
def test_set_conditions
Developer.send(:with_scope, :find => { :conditions => 'just a test...' }) do
- assert_equal '(just a test...)', Developer.scoped.arel.send(:where_clauses).join(' AND ')
+ assert_match '(just a test...)', Developer.scoped.arel.to_sql
end
end
@@ -226,6 +226,12 @@ class MethodScopingTest < ActiveRecord::TestCase
assert Post.find(1).comments.include?(new_comment)
end
+ def test_scoped_create_with_join_and_merge
+ (Comment.where(:body => "but Who's Buying?").joins(:post) & Post.where(:body => 'Peace Sells...')).with_scope do
+ assert_equal({:body => "but Who's Buying?"}, Comment.scoped.scope_for_create)
+ end
+ end
+
def test_immutable_scope
options = { :conditions => "name = 'David'" }
Developer.send(:with_scope, :find => options) do
@@ -269,7 +275,7 @@ class NestedScopingTest < ActiveRecord::TestCase
Developer.send(:with_scope, :find => { :conditions => 'salary = 80000' }) do
Developer.send(:with_scope, :find => { :limit => 10 }) do
devs = Developer.scoped
- assert_equal '(salary = 80000)', devs.arel.send(:where_clauses).join(' AND ')
+ assert_match '(salary = 80000)', devs.arel.to_sql
assert_equal 10, devs.taken
end
end
@@ -303,7 +309,7 @@ class NestedScopingTest < ActiveRecord::TestCase
Developer.send(:with_scope, :find => { :conditions => "name = 'David'" }) do
Developer.send(:with_scope, :find => { :conditions => 'salary = 80000' }) do
devs = Developer.scoped
- assert_equal "(name = 'David') AND (salary = 80000)", devs.arel.send(:where_clauses).join(' AND ')
+ assert_match "(name = 'David') AND (salary = 80000)", devs.arel.to_sql
assert_equal(1, Developer.count)
end
Developer.send(:with_scope, :find => { :conditions => "name = 'Maiha'" }) do
@@ -316,7 +322,7 @@ class NestedScopingTest < ActiveRecord::TestCase
Developer.send(:with_scope, :find => { :conditions => 'salary = 80000', :limit => 10 }) do
Developer.send(:with_scope, :find => { :conditions => "name = 'David'" }) do
devs = Developer.scoped
- assert_equal "(salary = 80000) AND (name = 'David')", devs.arel.send(:where_clauses).join(' AND ')
+ assert_match "(salary = 80000) AND (name = 'David')", devs.arel.to_sql
assert_equal 10, devs.taken
end
end
diff --git a/activerecord/test/cases/migration/command_recorder_test.rb b/activerecord/test/cases/migration/command_recorder_test.rb
new file mode 100644
index 0000000000..ea2292dda5
--- /dev/null
+++ b/activerecord/test/cases/migration/command_recorder_test.rb
@@ -0,0 +1,108 @@
+require "cases/helper"
+
+module ActiveRecord
+ class Migration
+ class CommandRecorderTest < ActiveRecord::TestCase
+ def setup
+ @recorder = CommandRecorder.new
+ end
+
+ def test_respond_to_delegates
+ recorder = CommandRecorder.new(Class.new {
+ def america; end
+ }.new)
+ assert recorder.respond_to?(:america)
+ end
+
+ def test_send_calls_super
+ assert_raises(NoMethodError) do
+ @recorder.send(:create_table, :horses)
+ end
+ end
+
+ def test_send_delegates_to_record
+ recorder = CommandRecorder.new(Class.new {
+ def create_table(name); end
+ }.new)
+ assert recorder.respond_to?(:create_table), 'respond_to? create_table'
+ recorder.send(:create_table, :horses)
+ assert_equal [[:create_table, [:horses]]], recorder.commands
+ end
+
+ def test_unknown_commands_raise_exception
+ @recorder.record :execute, ['some sql']
+ assert_raises(ActiveRecord::IrreversibleMigration) do
+ @recorder.inverse
+ end
+ end
+
+ def test_record
+ @recorder.record :create_table, [:system_settings]
+ assert_equal 1, @recorder.commands.length
+ end
+
+ def test_inverse
+ @recorder.record :create_table, [:system_settings]
+ assert_equal 1, @recorder.inverse.length
+
+ @recorder.record :rename_table, [:old, :new]
+ assert_equal 2, @recorder.inverse.length
+ end
+
+ def test_inverted_commands_are_reveresed
+ @recorder.record :create_table, [:hello]
+ @recorder.record :create_table, [:world]
+ tables = @recorder.inverse.map(&:last)
+ assert_equal [[:world], [:hello]], tables
+ end
+
+ def test_invert_create_table
+ @recorder.record :create_table, [:system_settings]
+ drop_table = @recorder.inverse.first
+ assert_equal [:drop_table, [:system_settings]], drop_table
+ end
+
+ def test_invert_rename_table
+ @recorder.record :rename_table, [:old, :new]
+ rename = @recorder.inverse.first
+ assert_equal [:rename_table, [:new, :old]], rename
+ end
+
+ def test_invert_add_column
+ @recorder.record :add_column, [:table, :column, :type, {}]
+ remove = @recorder.inverse.first
+ assert_equal [:remove_column, [:table, :column]], remove
+ end
+
+ def test_invert_rename_column
+ @recorder.record :rename_column, [:table, :old, :new]
+ rename = @recorder.inverse.first
+ assert_equal [:rename_column, [:table, :new, :old]], rename
+ end
+
+ def test_invert_add_index
+ @recorder.record :add_index, [:table, [:one, :two], {:options => true}]
+ remove = @recorder.inverse.first
+ assert_equal [:remove_index, [:table, {:column => [:one, :two]}]], remove
+ end
+
+ def test_invert_rename_index
+ @recorder.record :rename_index, [:old, :new]
+ rename = @recorder.inverse.first
+ assert_equal [:rename_index, [:new, :old]], rename
+ end
+
+ def test_invert_add_timestamps
+ @recorder.record :add_timestamps, [:table]
+ remove = @recorder.inverse.first
+ assert_equal [:remove_timestamps, [:table]], remove
+ end
+
+ def test_invert_remove_timestamps
+ @recorder.record :remove_timestamps, [:table]
+ add = @recorder.inverse.first
+ assert_equal [:add_timestamps, [:table]], add
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index e6eef805cf..a5a9965c3a 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -5,10 +5,8 @@ require 'models/person'
require 'models/topic'
require 'models/developer'
-require MIGRATIONS_ROOT + "/valid/1_people_have_last_names"
require MIGRATIONS_ROOT + "/valid/2_we_need_reminders"
require MIGRATIONS_ROOT + "/decimal/1_give_me_big_numbers"
-require MIGRATIONS_ROOT + "/interleaved/pass_3/2_i_raise_on_down"
if ActiveRecord::Base.connection.supports_migrations?
class BigNumber < ActiveRecord::Base; end
@@ -16,12 +14,13 @@ if ActiveRecord::Base.connection.supports_migrations?
class Reminder < ActiveRecord::Base; end
class ActiveRecord::Migration
- class <<self
+ class << self
attr_accessor :message_count
- def puts(text="")
- self.message_count ||= 0
- self.message_count += 1
- end
+ end
+
+ def puts(text="")
+ ActiveRecord::Migration.message_count ||= 0
+ ActiveRecord::Migration.message_count += 1
end
end
@@ -51,7 +50,7 @@ if ActiveRecord::Base.connection.supports_migrations?
def setup
ActiveRecord::Migration.verbose = true
- PeopleHaveLastNames.message_count = 0
+ ActiveRecord::Migration.message_count = 0
end
def teardown
@@ -1165,6 +1164,44 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_raise(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
end
+ class MockMigration < ActiveRecord::Migration
+ attr_reader :went_up, :went_down
+ def initialize
+ @went_up = false
+ @went_down = false
+ end
+
+ def up
+ @went_up = true
+ super
+ end
+
+ def down
+ @went_down = true
+ super
+ end
+ end
+
+ def test_instance_based_migration_up
+ migration = MockMigration.new
+ assert !migration.went_up, 'have not gone up'
+ assert !migration.went_down, 'have not gone down'
+
+ migration.migrate :up
+ assert migration.went_up, 'have gone up'
+ assert !migration.went_down, 'have not gone down'
+ end
+
+ def test_instance_based_migration_down
+ migration = MockMigration.new
+ assert !migration.went_up, 'have not gone up'
+ assert !migration.went_down, 'have not gone down'
+
+ migration.migrate :down
+ assert !migration.went_up, 'have gone up'
+ assert migration.went_down, 'have not gone down'
+ end
+
def test_migrator_one_up
assert !Person.column_methods_hash.include?(:last_name)
assert !Reminder.table_exists?
@@ -1232,51 +1269,56 @@ if ActiveRecord::Base.connection.supports_migrations?
def test_finds_migrations
migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations
- [[1, 'PeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
+ [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
assert_equal migrations[i].version, pair.first
assert_equal migrations[i].name, pair.last
end
end
+ def test_finds_migrations_from_two_directories
+ directories = [MIGRATIONS_ROOT + '/valid_with_timestamps', MIGRATIONS_ROOT + '/to_copy_with_timestamps']
+ migrations = ActiveRecord::Migrator.new(:up, directories).migrations
+
+ [[20090101010101, "PeopleHaveHobbies"],
+ [20090101010202, "PeopleHaveDescriptions"],
+ [20100101010101, "ValidWithTimestampsPeopleHaveLastNames"],
+ [20100201010101, "ValidWithTimestampsWeNeedReminders"],
+ [20100301010101, "ValidWithTimestampsInnocentJointable"]].each_with_index do |pair, i|
+ assert_equal pair.first, migrations[i].version
+ assert_equal pair.last, migrations[i].name
+ end
+ end
+
def test_finds_pending_migrations
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2", 1)
migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/interleaved/pass_2").pending_migrations
assert_equal 1, migrations.size
assert_equal migrations[0].version, 3
- assert_equal migrations[0].name, 'InnocentJointable'
+ assert_equal migrations[0].name, 'InterleavedInnocentJointable'
end
def test_relative_migrations
- $".delete_if do |fname|
- fname == (MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
- end
- Object.send(:remove_const, :PeopleHaveLastNames)
-
- Dir.chdir(MIGRATIONS_ROOT) do
+ list = Dir.chdir(MIGRATIONS_ROOT) do
ActiveRecord::Migrator.up("valid/", 1)
end
- assert defined?(PeopleHaveLastNames)
+ migration_proxy = list.find { |item|
+ item.name == 'ValidPeopleHaveLastNames'
+ }
+ assert migration_proxy, 'should find pending migration'
end
def test_only_loads_pending_migrations
# migrate up to 1
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
- # now unload the migrations that have been defined
- Object.send(:remove_const, :PeopleHaveLastNames)
-
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil)
-
- assert !defined? PeopleHaveLastNames
+ proxies = ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil)
- %w(WeNeedReminders, InnocentJointable).each do |migration|
- assert defined? migration
- end
-
- ensure
- load(MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
+ names = proxies.map(&:name)
+ assert !names.include?('ValidPeopleHaveLastNames')
+ assert names.include?('WeNeedReminders')
+ assert names.include?('InnocentJointable')
end
def test_target_version_zero_should_run_only_once
@@ -1286,16 +1328,9 @@ if ActiveRecord::Base.connection.supports_migrations?
# migrate down to 0
ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
- # now unload the migrations that have been defined
- PeopleHaveLastNames.unloadable
- ActiveSupport::Dependencies.remove_unloadable_constants!
-
# migrate down to 0 again
- ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
-
- assert !defined? PeopleHaveLastNames
- ensure
- load(MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
+ proxies = ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
+ assert_equal [], proxies
end
def test_migrator_db_has_no_schema_migrations_table
@@ -1312,20 +1347,20 @@ if ActiveRecord::Base.connection.supports_migrations?
def test_migrator_verbosity
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
- assert PeopleHaveLastNames.message_count > 0
- PeopleHaveLastNames.message_count = 0
+ assert_not_equal 0, ActiveRecord::Migration.message_count
+ ActiveRecord::Migration.message_count = 0
ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
- assert PeopleHaveLastNames.message_count > 0
- PeopleHaveLastNames.message_count = 0
+ assert_not_equal 0, ActiveRecord::Migration.message_count
+ ActiveRecord::Migration.message_count = 0
end
def test_migrator_verbosity_off
- PeopleHaveLastNames.verbose = false
+ ActiveRecord::Migration.verbose = false
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
- assert PeopleHaveLastNames.message_count.zero?
+ assert_equal 0, ActiveRecord::Migration.message_count
ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
- assert PeopleHaveLastNames.message_count.zero?
+ assert_equal 0, ActiveRecord::Migration.message_count
end
def test_migrator_going_down_due_to_version_target
@@ -1619,10 +1654,6 @@ if ActiveRecord::Base.connection.supports_migrations?
end # SexyMigrationsTest
class MigrationLoggerTest < ActiveRecord::TestCase
- def setup
- Object.send(:remove_const, :InnocentJointable)
- end
-
def test_migration_should_be_run_without_logger
previous_logger = ActiveRecord::Base.logger
ActiveRecord::Base.logger = nil
@@ -1635,10 +1666,6 @@ if ActiveRecord::Base.connection.supports_migrations?
end
class InterleavedMigrationsTest < ActiveRecord::TestCase
- def setup
- Object.send(:remove_const, :PeopleHaveLastNames)
- end
-
def test_migrator_interleaved_migrations
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_1")
@@ -1649,10 +1676,12 @@ if ActiveRecord::Base.connection.supports_migrations?
Person.reset_column_information
assert Person.column_methods_hash.include?(:last_name)
- Object.send(:remove_const, :PeopleHaveLastNames)
- Object.send(:remove_const, :InnocentJointable)
assert_nothing_raised do
- ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/interleaved/pass_3")
+ proxies = ActiveRecord::Migrator.down(
+ MIGRATIONS_ROOT + "/interleaved/pass_3")
+ names = proxies.map(&:name)
+ assert names.include?('InterleavedPeopleHaveLastNames')
+ assert names.include?('InterleavedInnocentJointable')
end
end
end
@@ -1947,7 +1976,7 @@ if ActiveRecord::Base.connection.supports_migrations?
@migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
@existing_migrations = Dir[@migrations_path + "/*.rb"]
- Time.travel_to(created_at = Time.utc(2010, 7, 26, 10, 10, 10)) do
+ Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
@@ -1972,7 +2001,7 @@ if ActiveRecord::Base.connection.supports_migrations?
sources[:bukkits] = MIGRATIONS_ROOT + "/to_copy_with_timestamps"
sources[:omg] = MIGRATIONS_ROOT + "/to_copy_with_timestamps2"
- Time.travel_to(created_at = Time.utc(2010, 7, 26, 10, 10, 10)) do
+ Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
copied = ActiveRecord::Migration.copy(@migrations_path, sources)
assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
@@ -1992,7 +2021,7 @@ if ActiveRecord::Base.connection.supports_migrations?
@migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
@existing_migrations = Dir[@migrations_path + "/*.rb"]
- Time.travel_to(created_at = Time.utc(2010, 2, 20, 10, 10, 10)) do
+ Time.travel_to(Time.utc(2010, 2, 20, 10, 10, 10)) do
ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
assert File.exists?(@migrations_path + "/20100301010102_people_have_hobbies.rb")
assert File.exists?(@migrations_path + "/20100301010103_people_have_descriptions.rb")
@@ -2024,11 +2053,26 @@ if ActiveRecord::Base.connection.supports_migrations?
clear
end
+ def test_copying_migrations_to_non_existing_directory
+ @migrations_path = MIGRATIONS_ROOT + "/non_existing"
+ @existing_migrations = []
+
+ Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
+ copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
+ assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
+ assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
+ assert_equal 2, copied.length
+ end
+ ensure
+ clear
+ Dir.delete(@migrations_path)
+ end
+
def test_copying_migrations_to_empty_directory
@migrations_path = MIGRATIONS_ROOT + "/empty"
@existing_migrations = []
- Time.travel_to(created_at = Time.utc(2010, 7, 26, 10, 10, 10)) do
+ Time.travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"})
assert File.exists?(@migrations_path + "/20100726101010_people_have_hobbies.rb")
assert File.exists?(@migrations_path + "/20100726101011_people_have_descriptions.rb")
@@ -2039,4 +2083,3 @@ if ActiveRecord::Base.connection.supports_migrations?
end
end
end
-
diff --git a/activerecord/test/cases/modules_test.rb b/activerecord/test/cases/modules_test.rb
index 14870cb0e2..a2041af16a 100644
--- a/activerecord/test/cases/modules_test.rb
+++ b/activerecord/test/cases/modules_test.rb
@@ -49,7 +49,6 @@ class ModulesTest < ActiveRecord::TestCase
def test_find_account_and_include_company
account = MyApplication::Billing::Account.find(1, :include => :firm)
- assert_kind_of MyApplication::Business::Firm, account.instance_variable_get('@firm')
assert_kind_of MyApplication::Business::Firm, account.firm
end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index fb24c65fff..ed5e1e0cba 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -122,7 +122,7 @@ class NamedScopeTest < ActiveRecord::TestCase
:joins => 'JOIN authors ON authors.id = posts.author_id',
:conditions => [ 'authors.author_address_id = ?', address.id ]
)
- assert_equal posts_with_authors_at_address_titles, Post.with_authors_at_address(address).find(:all, :select => 'title')
+ assert_equal posts_with_authors_at_address_titles.map(&:title), Post.with_authors_at_address(address).find(:all, :select => 'title').map(&:title)
end
def test_scope_with_object
@@ -141,26 +141,26 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_equal 1, Topic.multiple_extensions.extension_one
end
- def test_has_many_associations_have_access_to_named_scopes
+ def test_has_many_associations_have_access_to_scopes
assert_not_equal Post.containing_the_letter_a, authors(:david).posts
assert !Post.containing_the_letter_a.empty?
assert_equal authors(:david).posts & Post.containing_the_letter_a, authors(:david).posts.containing_the_letter_a
end
- def test_named_scope_with_STI
+ def test_scope_with_STI
assert_equal 3,Post.containing_the_letter_a.count
assert_equal 1,SpecialPost.containing_the_letter_a.count
end
- def test_has_many_through_associations_have_access_to_named_scopes
+ def test_has_many_through_associations_have_access_to_scopes
assert_not_equal Comment.containing_the_letter_e, authors(:david).comments
assert !Comment.containing_the_letter_e.empty?
assert_equal authors(:david).comments & Comment.containing_the_letter_e, authors(:david).comments.containing_the_letter_e
end
- def test_named_scopes_honor_current_scopes_from_when_defined
+ def test_scopes_honor_current_scopes_from_when_defined
assert !Post.ranked_by_comments.limit_by(5).empty?
assert !authors(:david).posts.ranked_by_comments.limit_by(5).empty?
assert_not_equal Post.ranked_by_comments.limit_by(5), authors(:david).posts.ranked_by_comments.limit_by(5)
@@ -236,7 +236,7 @@ class NamedScopeTest < ActiveRecord::TestCase
end
end
- def test_any_should_not_fire_query_if_named_scope_loaded
+ def test_any_should_not_fire_query_if_scope_loaded
topics = Topic.base
topics.collect # force load
assert_no_queries { assert topics.any? }
@@ -259,7 +259,7 @@ class NamedScopeTest < ActiveRecord::TestCase
end
end
- def test_many_should_not_fire_query_if_named_scope_loaded
+ def test_many_should_not_fire_query_if_scope_loaded
topics = Topic.base
topics.collect # force load
assert_no_queries { assert topics.many? }
@@ -276,27 +276,27 @@ class NamedScopeTest < ActiveRecord::TestCase
assert Topic.base.many?
end
- def test_should_build_on_top_of_named_scope
+ def test_should_build_on_top_of_scope
topic = Topic.approved.build({})
assert topic.approved
end
- def test_should_build_new_on_top_of_named_scope
+ def test_should_build_new_on_top_of_scope
topic = Topic.approved.new
assert topic.approved
end
- def test_should_create_on_top_of_named_scope
+ def test_should_create_on_top_of_scope
topic = Topic.approved.create({})
assert topic.approved
end
- def test_should_create_with_bang_on_top_of_named_scope
+ def test_should_create_with_bang_on_top_of_scope
topic = Topic.approved.create!({})
assert topic.approved
end
- def test_should_build_on_top_of_chained_named_scopes
+ def test_should_build_on_top_of_chained_scopes
topic = Topic.approved.by_lifo.build({})
assert topic.approved
assert_equal 'lifo', topic.author_name
@@ -310,7 +310,7 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_kind_of Topic, Topic.approved.sample
end
- def test_should_use_where_in_query_for_named_scope
+ def test_should_use_where_in_query_for_scope
assert_equal Developer.find_all_by_name('Jamis').to_set, Developer.find_all_by_id(Developer.jamises).to_set
end
@@ -361,7 +361,7 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).all.uniq
end
- def test_named_scopes_batch_finders
+ def test_scopes_batch_finders
assert_equal 3, Topic.approved.count
assert_queries(4) do
@@ -381,7 +381,7 @@ class NamedScopeTest < ActiveRecord::TestCase
end
end
- def test_named_scopes_with_reserved_names
+ def test_scopes_with_reserved_names
class << Topic
def public_method; end
public :public_method
@@ -400,7 +400,7 @@ class NamedScopeTest < ActiveRecord::TestCase
end
end
- def test_named_scopes_on_relations
+ def test_scopes_on_relations
# Topic.replied
approved_topics = Topic.scoped.approved.order('id DESC')
assert_equal topics(:fourth), approved_topics.first
@@ -409,19 +409,19 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_equal topics(:third), replied_approved_topics.first
end
- def test_index_on_named_scope
+ def test_index_on_scope
approved = Topic.approved.order('id ASC')
assert_equal topics(:second), approved[0]
assert approved.loaded?
end
- def test_nested_named_scopes_queries_size
+ def test_nested_scopes_queries_size
assert_queries(1) do
Topic.approved.by_lifo.replied.written_before(Time.now).all
end
end
- def test_named_scopes_are_cached_on_associations
+ def test_scopes_are_cached_on_associations
post = posts(:welcome)
assert_equal post.comments.containing_the_letter_e.object_id, post.comments.containing_the_letter_e.object_id
@@ -430,7 +430,7 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_no_queries { post.comments.containing_the_letter_e.all }
end
- def test_named_scopes_with_arguments_are_cached_on_associations
+ def test_scopes_with_arguments_are_cached_on_associations
post = posts(:welcome)
one = post.comments.limit_by(1).all
@@ -443,7 +443,7 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_no_queries { post.comments.limit_by(2).all }
end
- def test_named_scopes_are_reset_on_association_reload
+ def test_scopes_are_reset_on_association_reload
post = posts(:welcome)
[:destroy_all, :reset, :delete_all].each do |method|
@@ -453,7 +453,7 @@ class NamedScopeTest < ActiveRecord::TestCase
end
end
- def test_named_scoped_are_lazy_loaded_if_table_still_does_not_exist
+ def test_scoped_are_lazy_loaded_if_table_still_does_not_exist
assert_nothing_raised do
require "models/without_table"
end
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index 60f89da95e..e1f938be84 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -139,6 +139,14 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
assert_equal 'gardening', interest.reload.topic
end
+ def test_reject_if_with_blank_nested_attributes_id
+ # When using a select list to choose an existing 'ship' id, with :include_blank => true
+ Pirate.accepts_nested_attributes_for :ship, :reject_if => proc {|attributes| attributes[:id].blank? }
+
+ pirate = Pirate.new(:catchphrase => "Stop wastin' me time")
+ pirate.ship_attributes = { :id => "" }
+ assert_nothing_raised(ActiveRecord::RecordNotFound) { pirate.save! }
+ end
end
class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
@@ -163,7 +171,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
@ship.destroy
@pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger' }
- assert @pirate.ship.new_record?
+ assert !@pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
end
@@ -184,7 +192,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
def test_should_replace_an_existing_record_if_there_is_no_id
@pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger' }
- assert @pirate.ship.new_record?
+ assert !@pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
assert_equal 'Nights Dirty Lightning', @ship.name
end
@@ -256,7 +264,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
def test_should_also_work_with_a_HashWithIndifferentAccess
@pirate.ship_attributes = HashWithIndifferentAccess.new(:id => @ship.id, :name => 'Davy Jones Gold Dagger')
- assert !@pirate.ship.new_record?
+ assert @pirate.ship.persisted?
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
end
@@ -290,7 +298,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
def test_should_create_new_model_when_nothing_is_there_and_update_only_is_true
@ship.delete
-
+
@pirate.reload.update_attributes(:update_only_ship_attributes => { :name => 'Mayflower' })
assert_not_nil @pirate.ship
@@ -348,7 +356,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
@pirate.destroy
@ship.reload.pirate_attributes = { :catchphrase => 'Arr' }
- assert @ship.pirate.new_record?
+ assert !@ship.pirate.persisted?
assert_equal 'Arr', @ship.pirate.catchphrase
end
@@ -369,7 +377,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
def test_should_replace_an_existing_record_if_there_is_no_id
@ship.reload.pirate_attributes = { :catchphrase => 'Arr' }
- assert @ship.pirate.new_record?
+ assert !@ship.pirate.persisted?
assert_equal 'Arr', @ship.pirate.catchphrase
assert_equal 'Aye', @pirate.catchphrase
end
@@ -443,7 +451,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
def test_should_not_destroy_the_associated_model_until_the_parent_is_saved
pirate = @ship.pirate
-
+
@ship.attributes = { :pirate_attributes => { :id => pirate.id, '_destroy' => true } }
assert_nothing_raised(ActiveRecord::RecordNotFound) { Pirate.find(pirate.id) }
@ship.save
@@ -458,7 +466,7 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
@pirate.delete
@ship.reload.attributes = { :update_only_pirate_attributes => { :catchphrase => 'Arr' } }
- assert @ship.update_only_pirate.new_record?
+ assert !@ship.update_only_pirate.persisted?
end
def test_should_update_existing_when_update_only_is_true_and_no_id_is_given
@@ -596,10 +604,10 @@ module NestedAttributesOnACollectionAssociationTests
association_getter => { 'foo' => { :name => 'Grace OMalley' }, 'bar' => { :name => 'Privateers Greed' }}
}
- assert @pirate.send(@association_name).first.new_record?
+ assert !@pirate.send(@association_name).first.persisted?
assert_equal 'Grace OMalley', @pirate.send(@association_name).first.name
- assert @pirate.send(@association_name).last.new_record?
+ assert !@pirate.send(@association_name).last.persisted?
assert_equal 'Privateers Greed', @pirate.send(@association_name).last.name
end
@@ -819,7 +827,7 @@ class TestNestedAttributesWithNonStandardPrimaryKeys < ActiveRecord::TestCase
fixtures :owners, :pets
def setup
- Owner.accepts_nested_attributes_for :pets
+ Owner.accepts_nested_attributes_for :pets, :allow_destroy => true
@owner = owners(:ashley)
@pet1, @pet2 = pets(:chew), pets(:mochi)
@@ -836,10 +844,22 @@ class TestNestedAttributesWithNonStandardPrimaryKeys < ActiveRecord::TestCase
@owner.update_attributes(@params)
assert_equal ['Foo', 'Bar'], @owner.pets.map(&:name)
end
+
+ def test_attr_accessor_of_child_should_be_value_provided_during_update_attributes
+ @owner = owners(:ashley)
+ @pet1 = pets(:chew)
+ attributes = {:pets_attributes => { "1"=> { :id => @pet1.id,
+ :name => "Foo2",
+ :current_user => "John",
+ :_destroy=>true }}}
+ @owner.update_attributes(attributes)
+ assert_equal 'John', Pet.after_destroy_output
+ end
+
end
class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create!(:catchphrase => "My baby takes tha mornin' train!")
@@ -879,7 +899,7 @@ class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRe
end
class TestHasManyAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@ship = Ship.create!(:name => "The good ship Dollypop")
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index ffe6fb95b8..8ca9d626d1 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -192,7 +192,6 @@ class PersistencesTest < ActiveRecord::TestCase
topic = Topic.create("title" => "New Topic") do |t|
t.author_name = "David"
end
- topicReloaded = Topic.find(topic.id)
assert_equal("New Topic", topic.title)
assert_equal("David", topic.author_name)
end
@@ -241,6 +240,15 @@ class PersistencesTest < ActiveRecord::TestCase
assert_nothing_raised { minimalistic.save }
end
+ def test_update_sti_type
+ assert_instance_of Reply, topics(:second)
+
+ topic = topics(:second).becomes(Topic)
+ assert_instance_of Topic, topic
+ topic.save!
+ assert_instance_of Topic, Topic.find(topic.id)
+ end
+
def test_delete
topic = Topic.find(1)
assert_equal topic, topic.delete, 'topic.delete did not return self'
@@ -261,7 +269,7 @@ class PersistencesTest < ActiveRecord::TestCase
end
def test_record_not_found_exception
- assert_raise(ActiveRecord::RecordNotFound) { topicReloaded = Topic.find(99999) }
+ assert_raise(ActiveRecord::RecordNotFound) { Topic.find(99999) }
end
def test_update_all
diff --git a/activerecord/test/cases/pooled_connections_test.rb b/activerecord/test/cases/pooled_connections_test.rb
index de5fa140ba..6269437b14 100644
--- a/activerecord/test/cases/pooled_connections_test.rb
+++ b/activerecord/test/cases/pooled_connections_test.rb
@@ -137,4 +137,4 @@ class PooledConnectionsTest < ActiveRecord::TestCase
def add_record(name)
ActiveRecord::Base.connection_pool.with_connection { Project.create! :name => name }
end
-end unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
+end unless current_adapter?(:FrontBase) || in_memory_db?
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 5bb21a54bd..53aefc7b58 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -63,7 +63,7 @@ class QueryCacheTest < ActiveRecord::TestCase
# Oracle adapter returns count() as Fixnum or Float
if current_adapter?(:OracleAdapter)
assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
- elsif current_adapter?(:SQLite3Adapter) && SQLite3::Version::VERSION > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter)
+ elsif current_adapter?(:SQLite3Adapter) && SQLite3::VERSION > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter)
# Future versions of the sqlite3 adapter will return numeric
assert_instance_of Fixnum,
Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
@@ -133,7 +133,6 @@ class QueryCacheExpiryTest < ActiveRecord::TestCase
def test_cache_is_expired_by_habtm_delete
ActiveRecord::Base.connection.expects(:clear_query_cache).times(2)
ActiveRecord::Base.cache do
- c = Category.find(1)
p = Post.find(1)
assert p.categories.any?
p.categories.delete_all
diff --git a/activerecord/test/cases/quoting_test.rb b/activerecord/test/cases/quoting_test.rb
index 2ef5b5a800..b87fb51d97 100644
--- a/activerecord/test/cases/quoting_test.rb
+++ b/activerecord/test/cases/quoting_test.rb
@@ -154,13 +154,13 @@ module ActiveRecord
end
def test_crazy_object
- crazy = Class.new { def to_s; 'lol' end }.new
+ crazy = Class.new { def to_yaml; 'lol' end }.new
assert_equal "'lol'", @quoter.quote(crazy, nil)
assert_equal "'lol'", @quoter.quote(crazy, Object.new)
end
def test_crazy_object_calls_quote_string
- crazy = Class.new { def to_s; 'lo\l' end }.new
+ crazy = Class.new { def to_yaml; 'lo\l' end }.new
assert_equal "'lo\\\\l'", @quoter.quote(crazy, nil)
assert_equal "'lo\\\\l'", @quoter.quote(crazy, Object.new)
end
diff --git a/activerecord/test/cases/readonly_test.rb b/activerecord/test/cases/readonly_test.rb
index 98011f40a4..e21109baae 100644
--- a/activerecord/test/cases/readonly_test.rb
+++ b/activerecord/test/cases/readonly_test.rb
@@ -6,13 +6,8 @@ require 'models/project'
require 'models/reader'
require 'models/person'
-# Dummy class methods to test implicit association scoping.
-def Comment.foo() find :first end
-def Project.foo() find :first end
-
-
class ReadOnlyTest < ActiveRecord::TestCase
- fixtures :posts, :comments, :developers, :projects, :developers_projects
+ fixtures :posts, :comments, :developers, :projects, :developers_projects, :people, :readers
def test_cant_save_readonly_record
dev = Developer.find(1)
@@ -49,15 +44,6 @@ class ReadOnlyTest < ActiveRecord::TestCase
Developer.joins(', projects').readonly(false).each { |d| assert !d.readonly? }
end
-
- def test_habtm_find_readonly
- dev = Developer.find(1)
- assert !dev.projects.empty?
- assert dev.projects.all?(&:readonly?)
- assert dev.projects.find(:all).all?(&:readonly?)
- assert dev.projects.readonly(true).all?(&:readonly?)
- end
-
def test_has_many_find_readonly
post = Post.find(1)
assert !post.comments.empty?
@@ -71,6 +57,18 @@ class ReadOnlyTest < ActiveRecord::TestCase
assert !people.any?(&:readonly?)
end
+ def test_has_many_with_through_is_not_implicitly_marked_readonly_while_finding_by_id
+ assert !posts(:welcome).people.find(1).readonly?
+ end
+
+ def test_has_many_with_through_is_not_implicitly_marked_readonly_while_finding_first
+ assert !posts(:welcome).people.first.readonly?
+ end
+
+ def test_has_many_with_through_is_not_implicitly_marked_readonly_while_finding_last
+ assert !posts(:welcome).people.last.readonly?
+ end
+
def test_readonly_scoping
Post.send(:with_scope, :find => { :conditions => '1=1' }) do
assert !Post.find(1).readonly?
@@ -102,7 +100,13 @@ class ReadOnlyTest < ActiveRecord::TestCase
end
def test_association_collection_method_missing_scoping_not_readonly
- assert !Developer.find(1).projects.foo.readonly?
- assert !Post.find(1).comments.foo.readonly?
+ developer = Developer.find(1)
+ project = Post.find(1)
+
+ assert !developer.projects.all_as_method.first.readonly?
+ assert !developer.projects.all_as_scope.first.readonly?
+
+ assert !project.comments.all_as_method.first.readonly?
+ assert !project.comments.all_as_scope.first.readonly?
end
end
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index eeb619ac2f..eb580928ba 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -7,6 +7,10 @@ require 'models/subscriber'
require 'models/ship'
require 'models/pirate'
require 'models/price_estimate'
+require 'models/tagging'
+require 'models/author'
+require 'models/post'
+require 'models/sponsor'
class ReflectionTest < ActiveRecord::TestCase
include ActiveRecord::Reflection
@@ -24,25 +28,25 @@ class ReflectionTest < ActiveRecord::TestCase
def test_read_attribute_names
assert_equal(
- %w( id title author_name author_email_address bonus_time written_on last_read content group approved replies_count parent_id parent_title type ).sort,
- @first.attribute_names
+ %w( id title author_name author_email_address bonus_time written_on last_read content group approved replies_count parent_id parent_title type created_at updated_at ).sort,
+ @first.attribute_names.sort
)
end
def test_columns
- assert_equal 14, Topic.columns.length
+ assert_equal 16, Topic.columns.length
end
def test_columns_are_returned_in_the_order_they_were_declared
column_names = Topic.columns.map { |column| column.name }
- assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id parent_title type group), column_names
+ assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id parent_title type group created_at updated_at), column_names
end
def test_content_columns
content_columns = Topic.content_columns
content_column_names = content_columns.map {|column| column.name}
- assert_equal 10, content_columns.length
- assert_equal %w(title author_name author_email_address written_on bonus_time last_read content group approved parent_title).sort, content_column_names.sort
+ assert_equal 12, content_columns.length
+ assert_equal %w(title author_name author_email_address written_on bonus_time last_read content group approved parent_title created_at updated_at).sort, content_column_names.sort
end
def test_column_string_type_and_limit
@@ -126,11 +130,11 @@ class ReflectionTest < ActiveRecord::TestCase
def test_belongs_to_inferred_foreign_key_from_assoc_name
Company.belongs_to :foo
- assert_equal "foo_id", Company.reflect_on_association(:foo).primary_key_name
+ assert_equal "foo_id", Company.reflect_on_association(:foo).foreign_key
Company.belongs_to :bar, :class_name => "Xyzzy"
- assert_equal "bar_id", Company.reflect_on_association(:bar).primary_key_name
+ assert_equal "bar_id", Company.reflect_on_association(:bar).foreign_key
Company.belongs_to :baz, :class_name => "Xyzzy", :foreign_key => "xyzzy_id"
- assert_equal "xyzzy_id", Company.reflect_on_association(:baz).primary_key_name
+ assert_equal "xyzzy_id", Company.reflect_on_association(:baz).foreign_key
end
def test_association_reflection_in_modules
@@ -177,8 +181,8 @@ class ReflectionTest < ActiveRecord::TestCase
def test_reflection_of_all_associations
# FIXME these assertions bust a lot
- assert_equal 37, Firm.reflect_on_all_associations.size
- assert_equal 27, Firm.reflect_on_all_associations(:has_many).size
+ assert_equal 36, Firm.reflect_on_all_associations.size
+ assert_equal 26, Firm.reflect_on_all_associations(:has_many).size
assert_equal 10, Firm.reflect_on_all_associations(:has_one).size
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
end
@@ -191,6 +195,22 @@ class ReflectionTest < ActiveRecord::TestCase
assert_kind_of ThroughReflection, Subscriber.reflect_on_association(:books)
end
+ def test_association_primary_key
+ assert_equal "id", Author.reflect_on_association(:posts).association_primary_key.to_s
+ assert_equal "name", Author.reflect_on_association(:essay).association_primary_key.to_s
+ assert_equal "id", Tagging.reflect_on_association(:taggable).association_primary_key.to_s
+ end
+
+ def test_active_record_primary_key
+ assert_equal "nick", Subscriber.reflect_on_association(:subscriptions).active_record_primary_key.to_s
+ assert_equal "name", Author.reflect_on_association(:essay).active_record_primary_key.to_s
+ end
+
+ def test_foreign_type
+ assert_equal "sponsorable_type", Sponsor.reflect_on_association(:sponsorable).foreign_type.to_s
+ assert_equal "sponsorable_type", Sponsor.reflect_on_association(:thing).foreign_type.to_s
+ end
+
def test_collection_association
assert Pirate.reflect_on_association(:birds).collection?
assert Pirate.reflect_on_association(:parrots).collection?
@@ -228,6 +248,18 @@ class ReflectionTest < ActiveRecord::TestCase
assert !AssociationReflection.new(:has_and_belongs_to_many, :clients, { :autosave => true, :validate => false }, Firm).validate?
end
+ def test_foreign_key
+ assert_equal "author_id", Author.reflect_on_association(:posts).foreign_key.to_s
+ assert_equal "category_id", Post.reflect_on_association(:categorizations).foreign_key.to_s
+ end
+
+ def test_primary_key_name
+ assert_deprecated do
+ assert_equal "author_id", Author.reflect_on_association(:posts).primary_key_name.to_s
+ assert_equal "category_id", Post.reflect_on_association(:categorizations).primary_key_name.to_s
+ end
+ end
+
private
def assert_reflection(klass, association, options)
assert reflection = klass.reflect_on_association(association)
diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb
index a27e2e72cd..1bdf3136d4 100644
--- a/activerecord/test/cases/relation_scoping_test.rb
+++ b/activerecord/test/cases/relation_scoping_test.rb
@@ -152,7 +152,7 @@ class NestedRelationScopingTest < ActiveRecord::TestCase
Developer.where('salary = 80000').scoping do
Developer.limit(10).scoping do
devs = Developer.scoped
- assert_equal '(salary = 80000)', devs.arel.send(:where_clauses).join(' AND ')
+ assert_match '(salary = 80000)', devs.arel.to_sql
assert_equal 10, devs.taken
end
end
@@ -254,14 +254,13 @@ class HasManyScopingTest< ActiveRecord::TestCase
end
def test_should_maintain_default_scope_on_associations
- person = people(:michael)
magician = BadReference.find(1)
assert_equal [magician], people(:michael).bad_references
end
def test_should_default_scope_on_associations_is_overriden_by_association_conditions
- person = people(:michael)
- assert_equal [], people(:michael).fixed_bad_references
+ reference = references(:michael_unicyclist).becomes(BadReference)
+ assert_equal [reference], people(:michael).fixed_bad_references
end
def test_should_maintain_default_scope_on_eager_loaded_associations
@@ -424,7 +423,7 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal expected, received
end
- def test_named_scope_overwrites_default
+ def test_scope_overwrites_default
expected = Developer.find(:all, :order => 'salary DESC, name DESC').collect { |dev| dev.name }
received = DeveloperOrderedBySalary.by_name.find(:all).collect { |dev| dev.name }
assert_equal expected, received
@@ -466,9 +465,42 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal 50000, PoorDeveloperCalledJamis.create!(:name => 'David').salary
end
+ def test_default_scope_attribute
+ jamis = PoorDeveloperCalledJamis.new(:name => 'David')
+ assert_equal 50000, jamis.salary
+ end
+
+ def test_where_attribute
+ aaron = PoorDeveloperCalledJamis.where(:salary => 20).new(:name => 'Aaron')
+ assert_equal 20, aaron.salary
+ assert_equal 'Aaron', aaron.name
+ end
+
+ def test_where_attribute_merge
+ aaron = PoorDeveloperCalledJamis.where(:name => 'foo').new(:name => 'Aaron')
+ assert_equal 'Aaron', aaron.name
+ end
+
def test_scope_composed_by_limit_and_then_offset_is_equal_to_scope_composed_by_offset_and_then_limit
posts_limit_offset = Post.limit(3).offset(2)
posts_offset_limit = Post.offset(2).limit(3)
assert_equal posts_limit_offset, posts_offset_limit
end
+
+ def test_create_with_merge
+ aaron = (PoorDeveloperCalledJamis.create_with(:name => 'foo', :salary => 20) &
+ PoorDeveloperCalledJamis.create_with(:name => 'Aaron')).new
+ assert_equal 20, aaron.salary
+ assert_equal 'Aaron', aaron.name
+
+ aaron = PoorDeveloperCalledJamis.create_with(:name => 'foo', :salary => 20).
+ create_with(:name => 'Aaron').new
+ assert_equal 20, aaron.salary
+ assert_equal 'Aaron', aaron.name
+ end
+
+ def test_create_with_reset
+ jamis = PoorDeveloperCalledJamis.create_with(:name => 'Aaron').create_with(nil).new
+ assert_equal 'Jamis', jamis.name
+ end
end
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
new file mode 100644
index 0000000000..7bdbd773b6
--- /dev/null
+++ b/activerecord/test/cases/relation_test.rb
@@ -0,0 +1,139 @@
+require "cases/helper"
+require 'models/post'
+require 'models/comment'
+
+module ActiveRecord
+ class RelationTest < ActiveRecord::TestCase
+ fixtures :posts, :comments
+
+ class FakeKlass < Struct.new(:table_name)
+ end
+
+ def test_construction
+ relation = nil
+ assert_nothing_raised do
+ relation = Relation.new :a, :b
+ end
+ assert_equal :a, relation.klass
+ assert_equal :b, relation.table
+ assert !relation.loaded, 'relation is not loaded'
+ end
+
+ def test_single_values
+ assert_equal [:limit, :offset, :lock, :readonly, :create_with, :from].map(&:to_s).sort,
+ Relation::SINGLE_VALUE_METHODS.map(&:to_s).sort
+ end
+
+ def test_initialize_single_values
+ relation = Relation.new :a, :b
+ Relation::SINGLE_VALUE_METHODS.each do |method|
+ assert_nil relation.send("#{method}_value"), method.to_s
+ end
+ end
+
+ def test_association_methods
+ assert_equal [:includes, :eager_load, :preload].map(&:to_s).sort,
+ Relation::ASSOCIATION_METHODS.map(&:to_s).sort
+ end
+
+ def test_initialize_association_methods
+ relation = Relation.new :a, :b
+ Relation::ASSOCIATION_METHODS.each do |method|
+ assert_equal [], relation.send("#{method}_values"), method.to_s
+ end
+ end
+
+ def test_multi_value_methods
+ assert_equal [:select, :group, :order, :joins, :where, :having, :bind].map(&:to_s).sort,
+ Relation::MULTI_VALUE_METHODS.map(&:to_s).sort
+ end
+
+ def test_multi_value_initialize
+ relation = Relation.new :a, :b
+ Relation::MULTI_VALUE_METHODS.each do |method|
+ assert_equal [], relation.send("#{method}_values"), method.to_s
+ end
+ end
+
+ def test_extensions
+ relation = Relation.new :a, :b
+ assert_equal [], relation.extensions
+ end
+
+ def test_empty_where_values_hash
+ relation = Relation.new :a, :b
+ assert_equal({}, relation.where_values_hash)
+
+ relation.where_values << :hello
+ assert_equal({}, relation.where_values_hash)
+ end
+
+ def test_has_values
+ relation = Relation.new Post, Post.arel_table
+ relation.where_values << relation.table[:id].eq(10)
+ assert_equal({:id => 10}, relation.where_values_hash)
+ end
+
+ def test_values_wrong_table
+ relation = Relation.new Post, Post.arel_table
+ relation.where_values << Comment.arel_table[:id].eq(10)
+ assert_equal({}, relation.where_values_hash)
+ end
+
+ def test_tree_is_not_traversed
+ relation = Relation.new Post, Post.arel_table
+ left = relation.table[:id].eq(10)
+ right = relation.table[:id].eq(10)
+ combine = left.and right
+ relation.where_values << combine
+ assert_equal({}, relation.where_values_hash)
+ end
+
+ def test_table_name_delegates_to_klass
+ relation = Relation.new FakeKlass.new('foo'), :b
+ assert_equal 'foo', relation.table_name
+ end
+
+ def test_scope_for_create
+ relation = Relation.new :a, :b
+ assert_equal({}, relation.scope_for_create)
+ end
+
+ def test_create_with_value
+ relation = Relation.new Post, Post.arel_table
+ hash = { :hello => 'world' }
+ relation.create_with_value = hash
+ assert_equal hash, relation.scope_for_create
+ end
+
+ def test_create_with_value_with_wheres
+ relation = Relation.new Post, Post.arel_table
+ relation.where_values << relation.table[:id].eq(10)
+ relation.create_with_value = {:hello => 'world'}
+ assert_equal({:hello => 'world', :id => 10}, relation.scope_for_create)
+ end
+
+ # FIXME: is this really wanted or expected behavior?
+ def test_scope_for_create_is_cached
+ relation = Relation.new Post, Post.arel_table
+ assert_equal({}, relation.scope_for_create)
+
+ relation.where_values << relation.table[:id].eq(10)
+ assert_equal({}, relation.scope_for_create)
+
+ relation.create_with_value = {:hello => 'world'}
+ assert_equal({}, relation.scope_for_create)
+ end
+
+ def test_empty_eager_loading?
+ relation = Relation.new :a, :b
+ assert !relation.eager_loading?
+ end
+
+ def test_eager_load_values
+ relation = Relation.new :a, :b
+ relation.eager_load_values << :b
+ assert relation.eager_loading?
+ end
+ end
+end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index d2ccc1480a..5018b16b67 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -1,4 +1,5 @@
require "cases/helper"
+require 'models/tag'
require 'models/tagging'
require 'models/post'
require 'models/topic'
@@ -13,11 +14,24 @@ require 'models/bird'
require 'models/car'
require 'models/engine'
require 'models/tyre'
+require 'models/minivan'
class RelationTest < ActiveRecord::TestCase
fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments,
- :taggings, :cars
+ :tags, :taggings, :cars, :minivans
+
+ def test_do_not_double_quote_string_id
+ van = Minivan.last
+ assert van
+ assert_equal van.id, Minivan.where(:minivan_id => van).to_a.first.minivan_id
+ end
+
+ def test_do_not_double_quote_string_id_with_array
+ van = Minivan.last
+ assert van
+ assert_equal van, Minivan.where(:minivan_id => [van]).to_a.first
+ end
def test_bind_values
relation = Post.scoped
@@ -28,7 +42,7 @@ class RelationTest < ActiveRecord::TestCase
assert_equal [], relation.bind_values
end
- def test_two_named_scopes_with_includes_should_not_drop_any_include
+ def test_two_scopes_with_includes_should_not_drop_any_include
car = Car.incl_engines.incl_tyres.first
assert_no_queries { car.tyres.length }
assert_no_queries { car.engines.length }
@@ -144,6 +158,16 @@ class RelationTest < ActiveRecord::TestCase
assert_equal entrants(:first).name, entrants.first.name
end
+ def test_finding_with_complex_order_and_limit
+ tags = Tag.includes(:taggings).order("REPLACE('abc', taggings.taggable_type, taggings.taggable_type)").limit(1).to_a
+ assert_equal 1, tags.length
+ end
+
+ def test_finding_with_complex_order
+ tags = Tag.includes(:taggings).order("REPLACE('abc', taggings.taggable_type, taggings.taggable_type)").to_a
+ assert_equal 2, tags.length
+ end
+
def test_finding_with_order_limit_and_offset
entrants = Entrant.order("id ASC").limit(2).offset(1)
@@ -166,6 +190,10 @@ class RelationTest < ActiveRecord::TestCase
assert_equal [2, 4, 6, 8, 10], even_ids.sort
end
+ def test_joins_with_nil_argument
+ assert_nothing_raised { DependentFirm.joins(nil).first }
+ end
+
def test_finding_with_hash_conditions_on_joined_table
firms = DependentFirm.joins(:account).where({:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}).to_a
assert_equal 1, firms.size
@@ -230,7 +258,7 @@ class RelationTest < ActiveRecord::TestCase
end
end
- def test_respond_to_class_methods_and_named_scopes
+ def test_respond_to_class_methods_and_scopes
assert DeveloperOrderedBySalary.scoped.respond_to?(:all_ordered_by_name)
assert Topic.scoped.respond_to?(:by_lifo)
end
@@ -372,7 +400,7 @@ class RelationTest < ActiveRecord::TestCase
lifo = authors.find_or_initialize_by_name('Lifo')
assert_equal "Lifo", lifo.name
- assert lifo.new_record?
+ assert !lifo.persisted?
assert_equal authors(:david), authors.find_or_initialize_by_name(:name => 'David')
end
@@ -382,7 +410,7 @@ class RelationTest < ActiveRecord::TestCase
lifo = authors.find_or_create_by_name('Lifo')
assert_equal "Lifo", lifo.name
- assert ! lifo.new_record?
+ assert lifo.persisted?
assert_equal authors(:david), authors.find_or_create_by_name(:name => 'David')
end
@@ -415,6 +443,52 @@ class RelationTest < ActiveRecord::TestCase
assert_blank authors.all
end
+ def test_where_with_ar_object
+ author = Author.first
+ authors = Author.scoped.where(:id => author)
+ assert_equal 1, authors.all.length
+ end
+
+ def test_find_with_list_of_ar
+ author = Author.first
+ authors = Author.find([author])
+ assert_equal author, authors.first
+ end
+
+ class Mary < Author; end
+
+ def test_find_by_classname
+ Author.create!(:name => Mary.name)
+ assert_equal 1, Author.where(:name => Mary).size
+ end
+
+ def test_find_by_id_with_list_of_ar
+ author = Author.first
+ authors = Author.find_by_id([author])
+ assert_equal author, authors
+ end
+
+ def test_find_all_using_where_twice_should_or_the_relation
+ david = authors(:david)
+ relation = Author.unscoped
+ relation = relation.where(:name => david.name)
+ relation = relation.where(:name => 'Santiago')
+ relation = relation.where(:id => david.id)
+ assert_equal [david], relation.all
+ end
+
+ def test_find_all_with_multiple_ors
+ david = authors(:david)
+ relation = [
+ { :name => david.name },
+ { :name => 'Santiago' },
+ { :name => 'tenderlove' },
+ ].inject(Author.unscoped) do |memo, param|
+ memo.where(param)
+ end
+ assert_equal [david], relation.all
+ end
+
def test_exists
davids = Author.where(:name => 'David')
assert davids.exists?
@@ -500,6 +574,11 @@ class RelationTest < ActiveRecord::TestCase
end
end
+ def test_relation_merging_with_joins
+ comments = Comment.joins(:post).where(:body => 'Thank you for the welcome') & Post.where(:body => 'Such a lovely day')
+ assert_equal 1, comments.count
+ end
+
def test_count
posts = Post.scoped
@@ -561,6 +640,14 @@ class RelationTest < ActiveRecord::TestCase
def test_any
posts = Post.scoped
+ # This test was failing when run on its own (as opposed to running the entire suite).
+ # The second line in the assert_queries block was causing visit_Arel_Attributes_Attribute
+ # in Arel::Visitors::ToSql to trigger a SHOW TABLES query. Running that line here causes
+ # the SHOW TABLES result to be cached so we don't have to do it again in the block.
+ #
+ # This is obviously a rubbish fix but it's the best I can come up with for now...
+ posts.where(:id => nil).any?
+
assert_queries(3) do
assert posts.any? # Uses COUNT()
assert ! posts.where(:id => nil).any?
@@ -611,10 +698,10 @@ class RelationTest < ActiveRecord::TestCase
sparrow = birds.create
assert_kind_of Bird, sparrow
- assert sparrow.new_record?
+ assert !sparrow.persisted?
hen = birds.where(:name => 'hen').create
- assert ! hen.new_record?
+ assert hen.persisted?
assert_equal 'hen', hen.name
end
@@ -625,7 +712,7 @@ class RelationTest < ActiveRecord::TestCase
hen = birds.where(:name => 'hen').create!
assert_kind_of Bird, hen
- assert ! hen.new_record?
+ assert hen.persisted?
assert_equal 'hen', hen.name
end
@@ -685,7 +772,7 @@ class RelationTest < ActiveRecord::TestCase
assert_equal 'zyke', FastCar.order('name desc').find(:first, :order => 'id').name
end
- def test_default_scope_order_with_named_scope_order
+ def test_default_scope_order_with_scope_order
assert_equal 'zyke', CoolCar.order_using_new_style.limit(1).first.name
assert_equal 'zyke', CoolCar.order_using_old_style.limit(1).first.name
assert_equal 'zyke', FastCar.order_using_new_style.limit(1).first.name
@@ -719,4 +806,12 @@ class RelationTest < ActiveRecord::TestCase
assert_equal [rails_author], [rails_author] & relation
assert_equal [rails_author], relation & [rails_author]
end
+
+ def test_removing_limit_with_options
+ assert_not_equal 1, Post.limit(1).all(:limit => nil).count
+ end
+
+ def test_primary_key
+ assert_equal "id", Post.scoped.primary_key
+ end
end
diff --git a/activerecord/test/cases/session_store/session_test.rb b/activerecord/test/cases/session_store/session_test.rb
index 6f1c170a0c..f906bda8c3 100644
--- a/activerecord/test/cases/session_store/session_test.rb
+++ b/activerecord/test/cases/session_store/session_test.rb
@@ -5,7 +5,7 @@ require 'active_record/session_store'
module ActiveRecord
class SessionStore
class SessionTest < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints? && ActiveRecord::Base.connection.supports_ddl_transactions?
def setup
super
diff --git a/activerecord/test/cases/session_store/sql_bypass.rb b/activerecord/test/cases/session_store/sql_bypass.rb
index f0ba166465..7402b2afd6 100644
--- a/activerecord/test/cases/session_store/sql_bypass.rb
+++ b/activerecord/test/cases/session_store/sql_bypass.rb
@@ -18,9 +18,9 @@ module ActiveRecord
assert !Session.table_exists?
end
- def test_new_record?
+ def test_persisted?
s = SqlBypass.new :data => 'foo', :session_id => 10
- assert s.new_record?, 'this is a new record!'
+ assert !s.persisted?, 'this is a new record!'
end
def test_not_loaded?
diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb
index eb93761fb2..70c098bc6d 100644
--- a/activerecord/test/cases/timestamp_test.rb
+++ b/activerecord/test/cases/timestamp_test.rb
@@ -113,7 +113,7 @@ class TimestampTest < ActiveRecord::TestCase
pet = Pet.first
owner = pet.owner
- owner.update_attribute(:happy_at, (time = 3.days.ago))
+ owner.update_attribute(:happy_at, 3.days.ago)
previously_owner_updated_at = owner.updated_at
pet.name = "I'm a parrot"
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 0fbcef4091..110a18772f 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -163,7 +163,7 @@ class TransactionTest < ActiveRecord::TestCase
@first.author_name += '_this_should_not_end_up_in_the_db'
@first.save!
flunk
- rescue => e
+ rescue
assert_equal original_author_name, @first.reload.author_name
assert_equal nbooks_before_save, Book.count
ensure
@@ -182,7 +182,7 @@ class TransactionTest < ActiveRecord::TestCase
:bonus_time => "2005-01-30t15:28:00.00+01:00",
:content => "Have a nice day",
:approved => false)
- new_record_snapshot = new_topic.new_record?
+ new_record_snapshot = !new_topic.persisted?
id_present = new_topic.has_attribute?(Topic.primary_key)
id_snapshot = new_topic.id
@@ -195,7 +195,7 @@ class TransactionTest < ActiveRecord::TestCase
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 new_record_snapshot, !new_topic.persisted?, "The topic should have its old persisted 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
@@ -370,23 +370,23 @@ class TransactionTest < ActiveRecord::TestCase
assert topic_2.save
@first.save
@second.destroy
- assert_equal false, topic_1.new_record?
+ assert topic_1.persisted?, 'persisted'
assert_not_nil topic_1.id
- assert_equal false, topic_2.new_record?
+ assert topic_2.persisted?, 'persisted'
assert_not_nil topic_2.id
- assert_equal false, @first.new_record?
+ assert @first.persisted?, 'persisted'
assert_not_nil @first.id
- assert_equal true, @second.destroyed?
+ assert @second.destroyed?, 'destroyed'
raise ActiveRecord::Rollback
end
- assert_equal true, topic_1.new_record?
+ assert !topic_1.persisted?, 'not persisted'
assert_nil topic_1.id
- assert_equal true, topic_2.new_record?
+ assert !topic_2.persisted?, 'not persisted'
assert_nil topic_2.id
- assert_equal false, @first.new_record?
+ assert @first.persisted?, 'persisted'
assert_not_nil @first.id
- assert_equal false, @second.destroyed?
+ assert !@second.destroyed?, 'not destroyed'
end
if current_adapter?(:PostgreSQLAdapter) && defined?(PGconn::PQTRANS_IDLE)
diff --git a/activerecord/test/cases/unconnected_test.rb b/activerecord/test/cases/unconnected_test.rb
index 23ad10f3f9..f85fb4e5da 100644
--- a/activerecord/test/cases/unconnected_test.rb
+++ b/activerecord/test/cases/unconnected_test.rb
@@ -4,7 +4,7 @@ class TestRecord < ActiveRecord::Base
end
class TestUnconnectedAdapter < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
+ self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@underlying = ActiveRecord::Base.connection
@@ -14,6 +14,7 @@ class TestUnconnectedAdapter < ActiveRecord::TestCase
def teardown
@underlying = nil
ActiveRecord::Base.establish_connection(@specification)
+ load_schema if in_memory_db?
end
def test_connection_no_longer_established
diff --git a/activerecord/test/cases/validations/association_validation_test.rb b/activerecord/test/cases/validations/association_validation_test.rb
index 1246dd4276..56e345990f 100644
--- a/activerecord/test/cases/validations/association_validation_test.rb
+++ b/activerecord/test/cases/validations/association_validation_test.rb
@@ -17,7 +17,7 @@ class AssociationValidationTest < ActiveRecord::TestCase
o = Owner.new('name' => 'nopets')
assert !o.save
assert o.errors[:pets].any?
- pet = o.pets.build('name' => 'apet')
+ o.pets.build('name' => 'apet')
assert o.valid?
end
@@ -27,7 +27,7 @@ class AssociationValidationTest < ActiveRecord::TestCase
assert !o.save
assert o.errors[:pets].any?
- pet = o.pets.build('name' => 'apet')
+ o.pets.build('name' => 'apet')
assert o.valid?
2.times { o.pets.build('name' => 'apet') }
diff --git a/activerecord/test/cases/validations/uniqueness_validation_test.rb b/activerecord/test/cases/validations/uniqueness_validation_test.rb
index 9a863c25a8..b4f3dd034c 100644
--- a/activerecord/test/cases/validations/uniqueness_validation_test.rb
+++ b/activerecord/test/cases/validations/uniqueness_validation_test.rb
@@ -6,19 +6,6 @@ require 'models/warehouse_thing'
require 'models/guid'
require 'models/event'
-# The following methods in Topic are used in test_conditional_validation_*
-class Topic
- has_many :unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
- has_many :silly_unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
-end
-
-class UniqueReply < Reply
- validates_uniqueness_of :content, :scope => 'parent_id'
-end
-
-class SillyUniqueReply < UniqueReply
-end
-
class Wizard < ActiveRecord::Base
self.abstract_class = true
@@ -60,7 +47,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase
def test_validates_uniqueness_with_validates
Topic.validates :title, :uniqueness => true
- t = Topic.create!('title' => 'abc')
+ Topic.create!('title' => 'abc')
t2 = Topic.new('title' => 'abc')
assert !t2.valid?
@@ -201,7 +188,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase
def test_validate_case_sensitive_uniqueness_with_attribute_passed_as_integer
Topic.validates_uniqueness_of(:title, :case_sensitve => true)
- t = Topic.create!('title' => 101)
+ Topic.create!('title' => 101)
t2 = Topic.new('title' => 101)
assert !t2.valid?
diff --git a/activerecord/test/cases/xml_serialization_test.rb b/activerecord/test/cases/xml_serialization_test.rb
index b11b340e94..a6074b23e7 100644
--- a/activerecord/test/cases/xml_serialization_test.rb
+++ b/activerecord/test/cases/xml_serialization_test.rb
@@ -4,6 +4,7 @@ require 'models/post'
require 'models/author'
require 'models/comment'
require 'models/company_in_module'
+require 'models/toy'
class XmlSerializationTest < ActiveRecord::TestCase
def test_should_serialize_default_root
@@ -83,6 +84,26 @@ class DefaultXmlSerializationTest < ActiveRecord::TestCase
end
end
+class DefaultXmlSerializationTimezoneTest < ActiveRecord::TestCase
+ def test_should_serialize_datetime_with_timezone
+ timezone, Time.zone = Time.zone, "Pacific Time (US & Canada)"
+
+ toy = Toy.create(:name => 'Mickey', :updated_at => Time.utc(2006, 8, 1))
+ assert_match %r{<updated-at type=\"datetime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml
+ ensure
+ Time.zone = timezone
+ end
+
+ def test_should_serialize_datetime_with_timezone_reloaded
+ timezone, Time.zone = Time.zone, "Pacific Time (US & Canada)"
+
+ toy = Toy.create(:name => 'Minnie', :updated_at => Time.utc(2006, 8, 1)).reload
+ assert_match %r{<updated-at type=\"datetime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml
+ ensure
+ Time.zone = timezone
+ end
+end
+
class NilXmlSerializationTest < ActiveRecord::TestCase
def setup
@xml = Contact.new.to_xml(:root => 'xml_contact')
@@ -241,4 +262,10 @@ class DatabaseConnectedXmlSerializationTest < ActiveRecord::TestCase
assert array.include? 'github'
end
+ def test_should_support_aliased_attributes
+ xml = Author.select("name as firstname").to_xml
+ array = Hash.from_xml(xml)['authors']
+ assert_equal array.size, array.select { |author| author.has_key? 'firstname' }.size
+ end
+
end
diff --git a/activerecord/test/cases/yaml_serialization_test.rb b/activerecord/test/cases/yaml_serialization_test.rb
index f221def6b6..0b54c309d1 100644
--- a/activerecord/test/cases/yaml_serialization_test.rb
+++ b/activerecord/test/cases/yaml_serialization_test.rb
@@ -2,10 +2,45 @@ require "cases/helper"
require 'models/topic'
class YamlSerializationTest < ActiveRecord::TestCase
+ fixtures :topics
+
def test_to_yaml_with_time_with_zone_should_not_raise_exception
Time.zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"]
ActiveRecord::Base.time_zone_aware_attributes = true
topic = Topic.new(:written_on => DateTime.now)
assert_nothing_raised { topic.to_yaml }
end
+
+ def test_roundtrip
+ topic = Topic.first
+ assert topic
+ t = YAML.load YAML.dump topic
+ assert_equal topic, t
+ end
+
+ def test_encode_with_coder
+ topic = Topic.first
+ coder = {}
+ topic.encode_with coder
+ assert_equal({'attributes' => topic.attributes}, coder)
+ end
+
+ begin
+ require 'psych'
+
+ def test_psych_roundtrip
+ topic = Topic.first
+ assert topic
+ t = Psych.load Psych.dump topic
+ assert_equal topic, t
+ end
+
+ def test_psych_roundtrip_new_object
+ topic = Topic.new
+ assert topic
+ t = Psych.load Psych.dump topic
+ assert_equal topic.attributes, t.attributes
+ end
+ rescue LoadError
+ end
end