aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
authorSven Fuchs <svenfuchs@artweb-design.de>2008-07-16 03:41:11 +0200
committerSven Fuchs <svenfuchs@artweb-design.de>2008-07-16 03:41:11 +0200
commit931f366ffcacc0444fcca2fb2e2b44644db9642f (patch)
tree4c056de1273d23e2b8494cfe452caaeb98ade820 /activerecord/test
parent8691e255402b27eae594530001227fc05416a00c (diff)
parentfbef982e4b906b879240a35a1ecff447007da6b2 (diff)
downloadrails-931f366ffcacc0444fcca2fb2e2b44644db9642f.tar.gz
rails-931f366ffcacc0444fcca2fb2e2b44644db9642f.tar.bz2
rails-931f366ffcacc0444fcca2fb2e2b44644db9642f.zip
merge forward to current rails/master
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/cases/adapter_test.rb6
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb6
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb61
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb6
-rwxr-xr-xactiverecord/test/cases/associations/has_one_associations_test.rb7
-rwxr-xr-xactiverecord/test/cases/associations_test.rb108
-rwxr-xr-xactiverecord/test/cases/base_test.rb21
-rw-r--r--activerecord/test/cases/column_definition_test.rb36
-rw-r--r--activerecord/test/cases/dirty_test.rb46
-rw-r--r--activerecord/test/cases/finder_test.rb24
-rwxr-xr-xactiverecord/test/cases/fixtures_test.rb35
-rw-r--r--activerecord/test/cases/helper.rb10
-rwxr-xr-xactiverecord/test/cases/inheritance_test.rb7
-rwxr-xr-xactiverecord/test/cases/lifecycle_test.rb12
-rw-r--r--activerecord/test/cases/locking_test.rb20
-rw-r--r--activerecord/test/cases/method_scoping_test.rb10
-rw-r--r--activerecord/test/cases/migration_test.rb127
-rw-r--r--activerecord/test/cases/multiple_db_test.rb25
-rw-r--r--activerecord/test/cases/named_scope_test.rb57
-rw-r--r--activerecord/test/cases/reflection_test.rb6
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb46
-rwxr-xr-xactiverecord/test/cases/validations_test.rb23
-rw-r--r--activerecord/test/fixtures/companies.yml1
-rw-r--r--activerecord/test/models/author.rb3
-rw-r--r--activerecord/test/models/category.rb1
-rwxr-xr-xactiverecord/test/models/company.rb3
-rw-r--r--activerecord/test/models/person.rb2
-rw-r--r--activerecord/test/models/post.rb13
-rwxr-xr-xactiverecord/test/models/topic.rb4
-rw-r--r--activerecord/test/schema/schema.rb9
30 files changed, 694 insertions, 41 deletions
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 11f9870534..04770646b2 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -65,6 +65,12 @@ class AdapterTest < ActiveRecord::TestCase
end
end
+ if current_adapter?(:PostgreSQLAdapter)
+ def test_encoding
+ assert_not_nil @connection.encoding
+ end
+ end
+
def test_table_alias
def @connection.test_table_alias_length() 10; end
class << @connection
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 294b993c55..b29df68d22 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
@@ -681,4 +681,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal developer, project.developers.find(:first)
assert_equal project, developer.projects.find(:first)
end
+
+ def test_dynamic_find_should_respect_association_include
+ # SQL error in sort clause if :include is not included
+ # due to Unknown column 'authors.id'
+ assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
+ end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index b638143c5a..b9c7ec6377 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -129,6 +129,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal "Microsoft", Firm.find(:first).clients_like_ms_with_hash_conditions.first.name
end
+ def test_finding_using_primary_key
+ assert_equal "Summit", Firm.find(:first).clients_using_primary_key.first.name
+ end
+
def test_finding_using_sql
firm = Firm.find(:first)
first_client = firm.clients_using_sql.first
@@ -345,7 +349,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_invalid_adding_with_validate_false
firm = Firm.find(:first)
client = Client.new
- firm.unvalidated_clients_of_firm << Client.new
+ firm.unvalidated_clients_of_firm << client
assert firm.valid?
assert !client.valid?
@@ -353,6 +357,23 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert client.new_record?
end
+ def test_valid_adding_with_validate_false
+ no_of_clients = Client.count
+
+ firm = Firm.find(:first)
+ client = Client.new("name" => "Apple")
+
+ assert firm.valid?
+ assert client.valid?
+ assert client.new_record?
+
+ firm.unvalidated_clients_of_firm << client
+
+ assert firm.save
+ assert !client.new_record?
+ assert_equal no_of_clients+1, Client.count
+ end
+
def test_build
company = companies(:first_firm)
new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
@@ -367,6 +388,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 2, company.clients_of_firm(true).size
end
+ def test_collection_size_after_building
+ company = companies(:first_firm) # company already has one client
+ company.clients_of_firm.build("name" => "Another Client")
+ company.clients_of_firm.build("name" => "Yet Another Client")
+ assert_equal 3, company.clients_of_firm.size
+ end
+
def test_build_many
company = companies(:first_firm)
new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
@@ -397,6 +425,37 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_equal 2, first_topic.replies.to_ary.size
end
+ def test_build_via_block
+ company = companies(:first_firm)
+ new_client = assert_no_queries { company.clients_of_firm.build {|client| client.name = "Another Client" } }
+ assert !company.clients_of_firm.loaded?
+
+ assert_equal "Another Client", new_client.name
+ assert new_client.new_record?
+ assert_equal new_client, company.clients_of_firm.last
+ company.name += '-changed'
+ assert_queries(2) { assert company.save }
+ assert !new_client.new_record?
+ assert_equal 2, company.clients_of_firm(true).size
+ end
+
+ def test_build_many_via_block
+ company = companies(:first_firm)
+ new_clients = assert_no_queries do
+ company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client|
+ client.name = "changed"
+ end
+ end
+
+ assert_equal 2, new_clients.size
+ assert_equal "changed", new_clients.first.name
+ assert_equal "changed", new_clients.last.name
+
+ company.name += '-changed'
+ assert_queries(3) { assert company.save }
+ assert_equal 3, company.clients_of_firm(true).size
+ end
+
def test_create_without_loading_association
first_firm = companies(:first_firm)
Firm.column_names
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 05155f6303..be5170f830 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -187,4 +187,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
post.people_with_callbacks.clear
assert_equal (%w(Michael David Julian Roger) * 2).sort, log.last(8).collect(&:last).sort
end
+
+ def test_dynamic_find_should_respect_association_include
+ # SQL error in sort clause if :include is not included
+ # due to Unknown column 'comments.id'
+ assert Person.find(1).posts_with_comments_sorted_by_comment_id.find_by_title('Welcome to the weblog')
+ 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 d3ca0cae41..99639849a5 100755
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -29,6 +29,13 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal Firm.find(1, :include => :account_with_select).account_with_select.attributes.size, 2
end
+ def test_finding_using_primary_key
+ firm = companies(:first_firm)
+ assert_equal Account.find_by_firm_id(firm.id), firm.account
+ firm.firm_id = companies(:rails_core).id
+ assert_equal accounts(:rails_core_account), firm.account_using_primary_key
+ end
+
def test_can_marshal_has_one_association_with_nil_target
firm = Firm.new
assert_nothing_raised do
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index 59349dd7cf..4904feeb7d 100755
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -189,6 +189,114 @@ class AssociationProxyTest < ActiveRecord::TestCase
end
end
+ def test_belongs_to_mass_assignment
+ post_attributes = { :title => 'Associations', :body => 'Are They Accessible?' }
+ author_attributes = { :name => 'David Dollar' }
+
+ assert_no_difference 'Author.count' do
+ assert_raise(ActiveRecord::AssociationTypeMismatch) do
+ Post.create(post_attributes.merge({:author => author_attributes}))
+ end
+ end
+
+ assert_difference 'Author.count' do
+ post = Post.create(post_attributes.merge({:creatable_author => author_attributes}))
+ assert_equal post.creatable_author.name, author_attributes[:name]
+ end
+ end
+
+ def test_has_one_mass_assignment
+ post_attributes = { :title => 'Associations', :body => 'Are They Accessible?' }
+ comment_attributes = { :body => 'Setter Takes Hash' }
+
+ assert_no_difference 'Comment.count' do
+ assert_raise(ActiveRecord::AssociationTypeMismatch) do
+ Post.create(post_attributes.merge({:uncreatable_comment => comment_attributes}))
+ end
+ end
+
+ assert_difference 'Comment.count' do
+ post = Post.create(post_attributes.merge({:creatable_comment => comment_attributes}))
+ assert_equal post.creatable_comment.body, comment_attributes[:body]
+ end
+ end
+
+ def test_has_many_mass_assignment
+ post = posts(:welcome)
+ post_attributes = { :title => 'Associations', :body => 'Are They Accessible?' }
+ comment_attributes = { :body => 'Setter Takes Hash' }
+
+ assert_no_difference 'Comment.count' do
+ assert_raise(ActiveRecord::AssociationTypeMismatch) do
+ Post.create(post_attributes.merge({:comments => [comment_attributes]}))
+ end
+ assert_raise(ActiveRecord::AssociationTypeMismatch) do
+ post.comments << comment_attributes
+ end
+ end
+
+ assert_difference 'Comment.count' do
+ post = Post.create(post_attributes.merge({:creatable_comments => [comment_attributes]}))
+ assert_equal post.creatable_comments.last.body, comment_attributes[:body]
+ end
+
+ assert_difference 'Comment.count' do
+ post.creatable_comments << comment_attributes
+ assert_equal post.comments.last.body, comment_attributes[:body]
+ end
+
+ post.creatable_comments = [comment_attributes, comment_attributes]
+ assert_equal post.creatable_comments.count, 2
+ end
+
+ def test_has_and_belongs_to_many_mass_assignment
+ post = posts(:welcome)
+ post_attributes = { :title => 'Associations', :body => 'Are They Accessible?' }
+ category_attributes = { :name => 'Accessible Association', :type => 'Category' }
+
+ assert_no_difference 'Category.count' do
+ assert_raise(ActiveRecord::AssociationTypeMismatch) do
+ Post.create(post_attributes.merge({:categories => [category_attributes]}))
+ end
+ assert_raise(ActiveRecord::AssociationTypeMismatch) do
+ post.categories << category_attributes
+ end
+ end
+
+ assert_difference 'Category.count' do
+ post = Post.create(post_attributes.merge({:creatable_categories => [category_attributes]}))
+ assert_equal post.creatable_categories.last.name, category_attributes[:name]
+ end
+
+ assert_difference 'Category.count' do
+ post.creatable_categories << category_attributes
+ assert_equal post.creatable_categories.last.name, category_attributes[:name]
+ end
+
+ post.creatable_categories = [category_attributes, category_attributes]
+ assert_equal post.creatable_categories.count, 2
+ end
+
+ def test_association_proxy_setter_can_take_hash
+ special_comment_attributes = { :body => 'Setter Takes Hash' }
+
+ post = posts(:welcome)
+ post.creatable_comment = { :body => 'Setter Takes Hash' }
+
+ assert_equal post.creatable_comment.body, special_comment_attributes[:body]
+ end
+
+ def test_association_collection_can_take_hash
+ post_attributes = { :title => 'Setter Takes', :body => 'Hash' }
+ david = authors(:david)
+
+ post = (david.posts << post_attributes).last
+ assert_equal post.title, post_attributes[:title]
+
+ david.posts = [post_attributes, post_attributes]
+ assert_equal david.posts.count, 2
+ end
+
def setup_dangling_association
josh = Author.create(:name => "Josh")
p = Post.create(:title => "New on Edge", :body => "More cool stuff!", :author => josh)
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index a4be629fbd..9e4f268db7 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -19,6 +19,7 @@ require 'models/warehouse_thing'
require 'rexml/document'
class Category < ActiveRecord::Base; end
+class Categorization < ActiveRecord::Base; end
class Smarts < ActiveRecord::Base; end
class CreditCard < ActiveRecord::Base
class PinNumber < ActiveRecord::Base
@@ -75,7 +76,7 @@ class TopicWithProtectedContentAndAccessibleAuthorName < ActiveRecord::Base
end
class BasicsTest < ActiveRecord::TestCase
- fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors
+ fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations
def test_table_exists
assert !NonExistentTable.table_exists?
@@ -130,7 +131,7 @@ class BasicsTest < ActiveRecord::TestCase
def test_read_attributes_before_type_cast
category = Category.new({:name=>"Test categoty", :type => nil})
- category_attrs = {"name"=>"Test categoty", "type" => nil}
+ category_attrs = {"name"=>"Test categoty", "type" => nil, "categorizations_count" => nil}
assert_equal category_attrs , category.attributes_before_type_cast
end
@@ -614,6 +615,22 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal -2, Topic.find(2).replies_count
end
+ def test_update_counter
+ category = Category.first
+ assert_nil category.categorizations_count
+ assert_equal 2, category.categorizations.count
+
+ Category.update_counters(category.id, "categorizations_count" => category.categorizations.count)
+ category.reload
+ assert_not_nil category.categorizations_count
+ assert_equal 2, category.categorizations_count
+
+ Category.update_counters(category.id, "categorizations_count" => category.categorizations.count)
+ category.reload
+ assert_not_nil category.categorizations_count
+ assert_equal 4, category.categorizations_count
+ end
+
def test_update_all
assert_equal Topic.count, Topic.update_all("content = 'bulk updated!'")
assert_equal "bulk updated!", Topic.find(1).content
diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb
new file mode 100644
index 0000000000..540f42f4b6
--- /dev/null
+++ b/activerecord/test/cases/column_definition_test.rb
@@ -0,0 +1,36 @@
+require "cases/helper"
+
+class ColumnDefinitionTest < ActiveRecord::TestCase
+ def setup
+ @adapter = ActiveRecord::ConnectionAdapters::AbstractAdapter.new(nil)
+ def @adapter.native_database_types
+ {:string => "varchar"}
+ end
+ end
+
+ # Avoid column definitions in create table statements like:
+ # `title` varchar(255) DEFAULT NULL NULL
+ def test_should_not_include_default_clause_when_default_is_null
+ column = ActiveRecord::ConnectionAdapters::Column.new("title", nil, "varchar(20)")
+ column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new(
+ @adapter, column.name, "string",
+ column.limit, column.precision, column.scale, column.default, column.null)
+ assert_equal "title varchar(20) NULL", column_def.to_sql
+ end
+
+ def test_should_include_default_clause_when_default_is_present
+ column = ActiveRecord::ConnectionAdapters::Column.new("title", "Hello", "varchar(20)")
+ column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new(
+ @adapter, column.name, "string",
+ column.limit, column.precision, column.scale, column.default, column.null)
+ assert_equal %Q{title varchar(20) DEFAULT 'Hello' NULL}, column_def.to_sql
+ end
+
+ def test_should_specify_not_null_if_null_option_is_false
+ column = ActiveRecord::ConnectionAdapters::Column.new("title", "Hello", "varchar(20)", false)
+ column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new(
+ @adapter, column.name, "string",
+ column.limit, column.precision, column.scale, column.default, column.null)
+ assert_equal %Q{title varchar(20) DEFAULT 'Hello' NOT NULL}, column_def.to_sql
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index c011ffaf57..e5e022050d 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -2,6 +2,7 @@ require 'cases/helper'
require 'models/topic' # For booleans
require 'models/pirate' # For timestamps
require 'models/parrot'
+require 'models/person' # For optimistic locking
class Pirate # Just reopening it, not defining it
attr_accessor :detected_changes_in_after_update # Boolean for if changes are detected
@@ -54,6 +55,33 @@ class DirtyTest < ActiveRecord::TestCase
end
end
+ def test_zero_to_blank_marked_as_changed
+ pirate = Pirate.new
+ pirate.catchphrase = "Yarrrr, me hearties"
+ pirate.parrot_id = 1
+ pirate.save
+
+ # check the change from 1 to ''
+ pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
+ pirate.parrot_id = ''
+ assert pirate.parrot_id_changed?
+ assert_equal([1, nil], pirate.parrot_id_change)
+ pirate.save
+
+ # check the change from nil to 0
+ pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
+ pirate.parrot_id = 0
+ assert pirate.parrot_id_changed?
+ assert_equal([nil, 0], pirate.parrot_id_change)
+ pirate.save
+
+ # check the change from 0 to ''
+ pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties")
+ pirate.parrot_id = ''
+ assert pirate.parrot_id_changed?
+ assert_equal([0, nil], pirate.parrot_id_change)
+ end
+
def test_object_should_be_changed_if_any_attribute_is_changed
pirate = Pirate.new
assert !pirate.changed?
@@ -125,6 +153,24 @@ class DirtyTest < ActiveRecord::TestCase
end
end
+ def test_partial_update_with_optimistic_locking
+ person = Person.new(:first_name => 'foo')
+ old_lock_version = 1
+
+ with_partial_updates Person, false do
+ assert_queries(2) { 2.times { person.save! } }
+ Person.update_all({ :first_name => 'baz' }, :id => person.id)
+ end
+
+ with_partial_updates Person, true do
+ assert_queries(0) { 2.times { person.save! } }
+ assert_equal old_lock_version, person.reload.lock_version
+
+ assert_queries(1) { person.first_name = 'bar'; person.save! }
+ assert_not_equal old_lock_version, person.reload.lock_version
+ end
+ end
+
def test_changed_attributes_should_be_preserved_if_save_failure
pirate = Pirate.new
pirate.parrot_id = 1
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 80936d51f3..b97db73b68 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -1,5 +1,6 @@
require "cases/helper"
require 'models/author'
+require 'models/categorization'
require 'models/comment'
require 'models/company'
require 'models/topic'
@@ -199,6 +200,23 @@ class FinderTest < ActiveRecord::TestCase
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { 'topics.approved' => true }) }
end
+ def test_find_on_hash_conditions_with_hashed_table_name
+ assert Topic.find(1, :conditions => {:topics => { :approved => false }})
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => {:topics => { :approved => true }}) }
+ end
+
+ def test_find_with_hash_conditions_on_joined_table
+ firms = Firm.all :joins => :account, :conditions => {:accounts => { :credit_limit => 50 }}
+ assert_equal 1, firms.size
+ assert_equal companies(:first_firm), firms.first
+ end
+
+ def test_find_with_hash_conditions_on_joined_table_and_with_range
+ firms = DependentFirm.all :joins => :account, :conditions => {:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}
+ assert_equal 1, firms.size
+ assert_equal companies(:rails_core), firms.first
+ end
+
def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate
david = customers(:david)
assert Customer.find(david.id, :conditions => { 'customers.name' => david.name, :address => david.address })
@@ -394,6 +412,12 @@ class FinderTest < ActiveRecord::TestCase
assert_equal '1,1,1', bind('?', os)
end
+ def test_named_bind_with_postgresql_type_casts
+ l = Proc.new { bind(":a::integer '2009-01-01'::date", :a => '10') }
+ assert_nothing_raised(&l)
+ assert_equal "#{ActiveRecord::Base.quote_value('10')}::integer '2009-01-01'::date", l.call
+ end
+
def test_string_sanitation
assert_not_equal "#{ActiveRecord::Base.connection.quoted_string_prefix}'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
assert_equal "#{ActiveRecord::Base.connection.quoted_string_prefix}'something; select table'", ActiveRecord::Base.sanitize("something; select table")
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index aca7cfb367..6ba7597f56 100755
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -15,6 +15,7 @@ require 'models/pirate'
require 'models/treasure'
require 'models/matey'
require 'models/ship'
+require 'models/book'
class FixturesTest < ActiveRecord::TestCase
self.use_instantiated_fixtures = true
@@ -373,6 +374,34 @@ class CheckSetTableNameFixturesTest < ActiveRecord::TestCase
end
end
+class FixtureNameIsNotTableNameFixturesTest < ActiveRecord::TestCase
+ set_fixture_class :items => Book
+ fixtures :items
+ # Set to false to blow away fixtures cache and ensure our fixtures are loaded
+ # and thus takes into account our set_fixture_class
+ self.use_transactional_fixtures = false
+
+ def test_named_accessor
+ assert_kind_of Book, items(:dvd)
+ end
+end
+
+class FixtureNameIsNotTableNameMultipleFixturesTest < ActiveRecord::TestCase
+ set_fixture_class :items => Book, :funny_jokes => Joke
+ fixtures :items, :funny_jokes
+ # Set to false to blow away fixtures cache and ensure our fixtures are loaded
+ # and thus takes into account our set_fixture_class
+ self.use_transactional_fixtures = false
+
+ def test_named_accessor_of_differently_named_fixture
+ assert_kind_of Book, items(:dvd)
+ end
+
+ def test_named_accessor_of_same_named_fixture
+ assert_kind_of Joke, funny_jokes(:a_joke)
+ end
+end
+
class CustomConnectionFixturesTest < ActiveRecord::TestCase
set_fixture_class :courses => Course
fixtures :courses
@@ -432,11 +461,11 @@ class FixturesBrokenRollbackTest < ActiveRecord::TestCase
alias_method :teardown, :blank_teardown
def test_no_rollback_in_teardown_unless_transaction_active
- assert_equal 0, Thread.current['open_transactions']
+ assert_equal 0, ActiveRecord::Base.connection.open_transactions
assert_raise(RuntimeError) { ar_setup_fixtures }
- assert_equal 0, Thread.current['open_transactions']
+ assert_equal 0, ActiveRecord::Base.connection.open_transactions
assert_nothing_raised { ar_teardown_fixtures }
- assert_equal 0, Thread.current['open_transactions']
+ assert_equal 0, ActiveRecord::Base.connection.open_transactions
end
private
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index dc83300efa..0530ba9bd9 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -32,13 +32,13 @@ end
ActiveRecord::Base.connection.class.class_eval do
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/]
- def execute_with_counting(sql, name = nil, &block)
- $query_count ||= 0
- $query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r }
- execute_without_counting(sql, name, &block)
+ def execute_with_query_record(sql, name = nil, &block)
+ $queries_executed ||= []
+ $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
+ execute_without_query_record(sql, name, &block)
end
- alias_method_chain :execute, :counting
+ alias_method_chain :execute, :query_record
end
# Make with_scope public for tests
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index 47fb5c608f..4fd38bfbc9 100755
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -191,6 +191,13 @@ class InheritanceTest < ActiveRecord::TestCase
assert_not_nil account.instance_variable_get("@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')} IN \(1\)\)/) do
+ Account.find(1, :include => :firm)
+ end
+ end
+
def test_alt_eager_loading
switch_to_alt_inheritance_column
test_eager_load_belongs_to_something_inherited
diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb
index 258f7c7a0f..3432abee31 100755
--- a/activerecord/test/cases/lifecycle_test.rb
+++ b/activerecord/test/cases/lifecycle_test.rb
@@ -143,12 +143,20 @@ class LifecycleTest < ActiveRecord::TestCase
assert_equal developer.name, multi_observer.record.name
end
- def test_observing_after_find_when_not_defined_on_the_model
+ def test_after_find_cannot_be_observed_when_its_not_defined_on_the_model
observer = MinimalisticObserver.instance
assert_equal Minimalistic, MinimalisticObserver.observed_class
minimalistic = Minimalistic.find(1)
- assert_equal minimalistic, observer.minimalistic
+ assert_nil observer.minimalistic
+ end
+
+ def test_after_find_can_be_observed_when_its_defined_on_the_model
+ observer = TopicObserver.instance
+ assert_equal Topic, TopicObserver.observed_class
+
+ topic = Topic.find(1)
+ assert_equal topic, observer.topic
end
def test_invalid_observer
diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb
index 7db6c570b5..701187223f 100644
--- a/activerecord/test/cases/locking_test.rb
+++ b/activerecord/test/cases/locking_test.rb
@@ -29,10 +29,12 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_equal 0, p1.lock_version
assert_equal 0, p2.lock_version
+ p1.first_name = 'stu'
p1.save!
assert_equal 1, p1.lock_version
assert_equal 0, p2.lock_version
+ p2.first_name = 'sue'
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
end
@@ -42,11 +44,14 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_equal 0, p1.lock_version
assert_equal 0, p2.lock_version
+ p1.first_name = 'stu'
p1.save!
assert_equal 1, p1.lock_version
assert_equal 0, p2.lock_version
+ p2.first_name = 'sue'
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
+ p2.first_name = 'sue2'
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
end
@@ -54,15 +59,18 @@ class OptimisticLockingTest < ActiveRecord::TestCase
p1 = Person.new(:first_name => 'anika')
assert_equal 0, p1.lock_version
+ p1.first_name = 'anika2'
p1.save!
p2 = Person.find(p1.id)
assert_equal 0, p1.lock_version
assert_equal 0, p2.lock_version
+ p1.first_name = 'anika3'
p1.save!
assert_equal 1, p1.lock_version
assert_equal 0, p2.lock_version
+ p2.first_name = 'sue'
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
end
@@ -81,10 +89,12 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_equal 0, t1.version
assert_equal 0, t2.version
+ t1.tps_report_number = 700
t1.save!
assert_equal 1, t1.version
assert_equal 0, t2.version
+ t2.tps_report_number = 800
assert_raises(ActiveRecord::StaleObjectError) { t2.save! }
end
@@ -93,6 +103,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_equal 0, p1.lock_version
assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
+ p1.first_name = 'bianca2'
p1.save!
assert_equal 1, p1.lock_version
assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
@@ -146,6 +157,15 @@ class OptimisticLockingTest < ActiveRecord::TestCase
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.new(:first_name => 'anika')
+ p1.send(:update_with_lock, [])
+ end
+ end
+
private
def add_counter_column_to(model)
diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb
index 1a9a875730..d6b3e341df 100644
--- a/activerecord/test/cases/method_scoping_test.rb
+++ b/activerecord/test/cases/method_scoping_test.rb
@@ -87,6 +87,16 @@ class MethodScopingTest < ActiveRecord::TestCase
assert_equal 1, scoped_developers.size
end
+ def test_scoped_find_joins
+ scoped_developers = Developer.with_scope(:find => { :joins => 'JOIN developers_projects ON id = developer_id' } ) do
+ Developer.find(:all, :conditions => 'developers_projects.project_id = 2')
+ end
+ assert scoped_developers.include?(developers(:david))
+ assert !scoped_developers.include?(developers(:jamis))
+ assert_equal 1, scoped_developers.size
+ assert_equal developers(:david).attributes, scoped_developers.first.attributes
+ end
+
def test_scoped_count_include
# with the include, will retrieve only developers for the given project
Developer.with_scope(:find => { :include => :projects }) do
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index f36255e209..7ecf755ef8 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -3,6 +3,7 @@ require 'bigdecimal/util'
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"
@@ -153,9 +154,10 @@ if ActiveRecord::Base.connection.supports_migrations?
t.column :default_int, :integer
- t.column :one_int, :integer, :limit => 1
- t.column :four_int, :integer, :limit => 4
- t.column :eight_int, :integer, :limit => 8
+ t.column :one_int, :integer, :limit => 1
+ t.column :four_int, :integer, :limit => 4
+ t.column :eight_int, :integer, :limit => 8
+ t.column :eleven_int, :integer, :limit => 11
end
end
@@ -167,12 +169,20 @@ if ActiveRecord::Base.connection.supports_migrations?
one = columns.detect { |c| c.name == "one_int" }
four = columns.detect { |c| c.name == "four_int" }
eight = columns.detect { |c| c.name == "eight_int" }
+ eleven = columns.detect { |c| c.name == "eleven_int" }
if current_adapter?(:PostgreSQLAdapter)
assert_equal 'integer', default.sql_type
assert_equal 'smallint', one.sql_type
assert_equal 'integer', four.sql_type
assert_equal 'bigint', eight.sql_type
+ assert_equal 'integer', eleven.sql_type
+ elsif current_adapter?(:MysqlAdapter)
+ assert_match 'int(11)', default.sql_type
+ assert_match 'tinyint', one.sql_type
+ assert_match 'int', four.sql_type
+ assert_match 'bigint', eight.sql_type
+ assert_match 'int(11)', eleven.sql_type
elsif current_adapter?(:OracleAdapter)
assert_equal 'NUMBER(38)', default.sql_type
assert_equal 'NUMBER(1)', one.sql_type
@@ -483,6 +493,37 @@ if ActiveRecord::Base.connection.supports_migrations?
end
end
+ def test_rename_column_preserves_default_value_not_null
+ begin
+ default_before = Developer.connection.columns("developers").find { |c| c.name == "salary" }.default
+ assert_equal 70000, default_before
+ Developer.connection.rename_column "developers", "salary", "anual_salary"
+ Developer.reset_column_information
+ assert Developer.column_names.include?("anual_salary")
+ default_after = Developer.connection.columns("developers").find { |c| c.name == "anual_salary" }.default
+ assert_equal 70000, default_after
+ ensure
+ Developer.connection.rename_column "developers", "anual_salary", "salary"
+ Developer.reset_column_information
+ end
+ end
+
+ def test_rename_nonexistent_column
+ ActiveRecord::Base.connection.create_table(:hats) do |table|
+ table.column :hat_name, :string, :default => nil
+ end
+ exception = if current_adapter?(:PostgreSQLAdapter)
+ ActiveRecord::StatementInvalid
+ else
+ ActiveRecord::ActiveRecordError
+ end
+ assert_raises(exception) do
+ Person.connection.rename_column "hats", "nonexistent", "should_fail"
+ end
+ ensure
+ ActiveRecord::Base.connection.drop_table(:hats)
+ end
+
def test_rename_column_with_sql_reserved_word
begin
assert_nothing_raised { Person.connection.rename_column "people", "first_name", "group" }
@@ -662,6 +703,55 @@ if ActiveRecord::Base.connection.supports_migrations?
Person.connection.drop_table :testings rescue nil
end
+ def test_keeping_default_and_notnull_constaint_on_change
+ Person.connection.create_table :testings do |t|
+ t.column :title, :string
+ end
+ person_klass = Class.new(Person)
+ person_klass.set_table_name 'testings'
+
+ person_klass.connection.add_column "testings", "wealth", :integer, :null => false, :default => 99
+ person_klass.reset_column_information
+ assert_equal 99, person_klass.columns_hash["wealth"].default
+ assert_equal false, person_klass.columns_hash["wealth"].null
+ assert_nothing_raised {person_klass.connection.execute("insert into testings (title) values ('tester')")}
+
+ # change column default to see that column doesn't lose its not null definition
+ person_klass.connection.change_column_default "testings", "wealth", 100
+ person_klass.reset_column_information
+ assert_equal 100, person_klass.columns_hash["wealth"].default
+ assert_equal false, person_klass.columns_hash["wealth"].null
+
+ # rename column to see that column doesn't lose its not null and/or default definition
+ person_klass.connection.rename_column "testings", "wealth", "money"
+ person_klass.reset_column_information
+ assert_nil person_klass.columns_hash["wealth"]
+ assert_equal 100, person_klass.columns_hash["money"].default
+ assert_equal false, person_klass.columns_hash["money"].null
+
+ # change column
+ person_klass.connection.change_column "testings", "money", :integer, :null => false, :default => 1000
+ person_klass.reset_column_information
+ assert_equal 1000, person_klass.columns_hash["money"].default
+ assert_equal false, person_klass.columns_hash["money"].null
+
+ # change column, make it nullable and clear default
+ person_klass.connection.change_column "testings", "money", :integer, :null => true, :default => nil
+ person_klass.reset_column_information
+ assert_nil person_klass.columns_hash["money"].default
+ assert_equal true, person_klass.columns_hash["money"].null
+
+ # change_column_null, make it not nullable and set null values to a default value
+ person_klass.connection.execute('UPDATE testings SET money = NULL')
+ person_klass.connection.change_column_null "testings", "money", false, 2000
+ person_klass.reset_column_information
+ assert_nil person_klass.columns_hash["money"].default
+ assert_equal false, person_klass.columns_hash["money"].null
+ assert_equal [2000], Person.connection.select_values("SELECT money FROM testings").map { |s| s.to_i }.sort
+ ensure
+ Person.connection.drop_table :testings rescue nil
+ end
+
def test_change_column_default_to_null
Person.connection.change_column_default "people", "first_name", nil
Person.reset_column_information
@@ -799,6 +889,21 @@ if ActiveRecord::Base.connection.supports_migrations?
assert !Reminder.table_exists?
end
+ def test_migrator_double_up
+ assert_equal(0, ActiveRecord::Migrator.current_version)
+ ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/valid", 1)
+ assert_nothing_raised { ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/valid", 1) }
+ assert_equal(1, ActiveRecord::Migrator.current_version)
+ end
+
+ def test_migrator_double_down
+ assert_equal(0, ActiveRecord::Migrator.current_version)
+ ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/valid", 1)
+ ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT + "/valid", 1)
+ assert_nothing_raised { ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT + "/valid", 1) }
+ assert_equal(0, ActiveRecord::Migrator.current_version)
+ end
+
def test_finds_migrations
migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations
[['1', 'people_have_last_names'],
@@ -888,16 +993,6 @@ if ActiveRecord::Base.connection.supports_migrations?
ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
assert_equal(0, ActiveRecord::Migrator.current_version)
end
-
- def test_migrator_run
- assert_equal(0, ActiveRecord::Migrator.current_version)
- ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/valid", 3)
- assert_equal(0, ActiveRecord::Migrator.current_version)
-
- assert_equal(0, ActiveRecord::Migrator.current_version)
- ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT + "/valid", 3)
- assert_equal(0, ActiveRecord::Migrator.current_version)
- end
def test_schema_migrations_table_name
ActiveRecord::Base.table_name_prefix = "prefix_"
@@ -1206,10 +1301,10 @@ if ActiveRecord::Base.connection.supports_migrations?
end
def integer_column
- if current_adapter?(:SQLite3Adapter) || current_adapter?(:SQLiteAdapter) || current_adapter?(:PostgreSQLAdapter)
- "integer"
- else
+ if current_adapter?(:MysqlAdapter)
'int(11)'
+ else
+ 'integer'
end
end
diff --git a/activerecord/test/cases/multiple_db_test.rb b/activerecord/test/cases/multiple_db_test.rb
index eb3e43c8ac..7c3e0f2ca6 100644
--- a/activerecord/test/cases/multiple_db_test.rb
+++ b/activerecord/test/cases/multiple_db_test.rb
@@ -57,4 +57,29 @@ class MultipleDbTest < ActiveRecord::TestCase
assert Course.connection
end
+
+ def test_transactions_across_databases
+ c1 = Course.find(1)
+ e1 = Entrant.find(1)
+
+ begin
+ Course.transaction do
+ Entrant.transaction do
+ c1.name = "Typo"
+ e1.name = "Typo"
+ c1.save
+ e1.save
+ raise "No I messed up."
+ end
+ end
+ rescue
+ # Yup caught it
+ end
+
+ assert_equal "Typo", c1.name
+ assert_equal "Typo", e1.name
+
+ assert_equal "Ruby Development", Course.find(1).name
+ assert_equal "Ruby Developer", Entrant.find(1).name
+ end
end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index d890cf7936..0c1eb23428 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -6,7 +6,7 @@ require 'models/reply'
require 'models/author'
class NamedScopeTest < ActiveRecord::TestCase
- fixtures :posts, :authors, :topics, :comments
+ fixtures :posts, :authors, :topics, :comments, :author_addresses
def test_implements_enumerable
assert !Topic.find(:all).empty?
@@ -59,6 +59,16 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_equal Topic.count(:conditions => {:approved => true}), Topic.approved.count
end
+ def test_scopes_with_string_name_can_be_composed
+ # NOTE that scopes defined with a string as a name worked on their own
+ # but when called on another scope the other scope was completely replaced
+ assert_equal Topic.replied.approved, Topic.replied.approved_as_string
+ end
+
+ def test_scopes_can_be_specified_with_deep_hash_conditions
+ assert_equal Topic.replied.approved, Topic.replied.approved_as_hash_condition
+ end
+
def test_scopes_are_composable
assert_equal (approved = Topic.find(:all, :conditions => {:approved => true})), Topic.approved
assert_equal (replied = Topic.find(:all, :conditions => 'replies_count > 0')), Topic.replied
@@ -77,6 +87,25 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_equal topics_written_before_the_second, Topic.written_before(topics(:second).written_on)
end
+ def test_scopes_with_joins
+ address = author_addresses(:david_address)
+ posts_with_authors_at_address = Post.find(
+ :all, :joins => 'JOIN authors ON authors.id = posts.author_id',
+ :conditions => [ 'authors.author_address_id = ?', address.id ]
+ )
+ assert_equal posts_with_authors_at_address, Post.with_authors_at_address(address)
+ end
+
+ def test_scopes_with_joins_respects_custom_select
+ address = author_addresses(:david_address)
+ posts_with_authors_at_address_titles = Post.find(:all,
+ :select => 'title',
+ :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')
+ end
+
def test_extensions
assert_equal 1, Topic.anonymous_extension.one
assert_equal 2, Topic.named_extension.two
@@ -154,4 +183,30 @@ class NamedScopeTest < ActiveRecord::TestCase
topics.empty? # use loaded (no query)
end
end
+
+ def test_should_build_with_proxy_options
+ topic = Topic.approved.build({})
+ assert topic.approved
+ end
+
+ def test_should_build_new_with_proxy_options
+ topic = Topic.approved.new
+ assert topic.approved
+ end
+
+ def test_should_create_with_proxy_options
+ topic = Topic.approved.create({})
+ assert topic.approved
+ end
+
+ def test_should_create_with_bang_with_proxy_options
+ topic = Topic.approved.create!({})
+ assert topic.approved
+ end
+
+ def test_should_build_with_proxy_options_chained
+ topic = Topic.approved.by_lifo.build({})
+ assert topic.approved
+ assert_equal 'lifo', topic.author_name
+ end
end
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index 0c57b79401..723062e3b8 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -160,9 +160,9 @@ class ReflectionTest < ActiveRecord::TestCase
def test_reflection_of_all_associations
# FIXME these assertions bust a lot
- assert_equal 22, Firm.reflect_on_all_associations.size
- assert_equal 17, Firm.reflect_on_all_associations(:has_many).size
- assert_equal 5, Firm.reflect_on_all_associations(:has_one).size
+ assert_equal 24, Firm.reflect_on_all_associations.size
+ assert_equal 18, Firm.reflect_on_all_associations(:has_many).size
+ assert_equal 6, Firm.reflect_on_all_associations(:has_one).size
assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
end
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index c42b0efba0..ee7e285a73 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -72,6 +72,52 @@ class SchemaDumperTest < ActiveRecord::TestCase
assert_match %r{:null => false}, output
end
+ def test_schema_dump_includes_limit_constraint_for_integer_columns
+ stream = StringIO.new
+
+ ActiveRecord::SchemaDumper.ignore_tables = [/^(?!integer_limits)/]
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
+ output = stream.string
+
+ if current_adapter?(:PostgreSQLAdapter)
+ assert_match %r{c_int_1.*:limit => 2}, output
+ assert_match %r{c_int_2.*:limit => 2}, output
+
+ # int 3 is 4 bytes in postgresql
+ assert_match %r{c_int_3.*}, output
+ assert_no_match %r{c_int_3.*:limit}, output
+
+ assert_match %r{c_int_4.*}, output
+ assert_no_match %r{c_int_4.*:limit}, output
+ elsif current_adapter?(:MysqlAdapter)
+ assert_match %r{c_int_1.*:limit => 1}, output
+ assert_match %r{c_int_2.*:limit => 2}, output
+ assert_match %r{c_int_3.*:limit => 3}, output
+
+ assert_match %r{c_int_4.*}, output
+ assert_no_match %r{c_int_4.*:limit}, output
+ elsif current_adapter?(:SQLiteAdapter)
+ assert_match %r{c_int_1.*:limit => 1}, output
+ assert_match %r{c_int_2.*:limit => 2}, output
+ assert_match %r{c_int_3.*:limit => 3}, output
+ assert_match %r{c_int_4.*:limit => 4}, output
+ end
+ assert_match %r{c_int_without_limit.*}, output
+ assert_no_match %r{c_int_without_limit.*:limit}, output
+
+ if current_adapter?(:SQLiteAdapter)
+ assert_match %r{c_int_5.*:limit => 5}, output
+ assert_match %r{c_int_6.*:limit => 6}, output
+ assert_match %r{c_int_7.*:limit => 7}, output
+ assert_match %r{c_int_8.*:limit => 8}, output
+ else
+ assert_match %r{c_int_5.*:limit => 8}, output
+ assert_match %r{c_int_6.*:limit => 8}, output
+ assert_match %r{c_int_7.*:limit => 8}, output
+ assert_match %r{c_int_8.*:limit => 8}, output
+ end
+ end
+
def test_schema_dump_with_string_ignored_table
stream = StringIO.new
diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb
index ad27ac951c..60b00b3e8f 100755
--- a/activerecord/test/cases/validations_test.rb
+++ b/activerecord/test/cases/validations_test.rb
@@ -1061,6 +1061,18 @@ class ValidationsTest < ActiveRecord::TestCase
end
end
+ def test_validates_length_of_with_block
+ Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least %d words.",
+ :tokenizer => lambda {|str| str.scan(/\w+/) }
+ t = Topic.create!(:content => "this content should be long enough")
+ assert t.valid?
+
+ t.content = "not long enough"
+ assert !t.valid?
+ assert t.errors.on(:content)
+ assert_equal "Your essay must be at least 5 words.", t.errors[:content]
+ end
+
def test_validates_size_of_association_utf8
with_kcode('UTF8') do
assert_nothing_raised { Topic.validates_size_of :replies, :minimum => 1 }
@@ -1381,6 +1393,7 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase
INTEGERS = [0, 10, -10] + INTEGER_STRINGS
BIGDECIMAL = BIGDECIMAL_STRINGS.collect! { |bd| BigDecimal.new(bd) }
JUNK = ["not a number", "42 not a number", "0xdeadbeef", "00-1", "--3", "+-3", "+3-1", "-+019.0", "12.12.13.12", "123\nnot a number"]
+ INFINITY = [1.0/0.0]
def setup
Topic.instance_variable_set("@validate_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
@@ -1392,27 +1405,27 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase
Topic.validates_numericality_of :approved
invalid!(NIL + BLANK + JUNK)
- valid!(FLOATS + INTEGERS + BIGDECIMAL)
+ valid!(FLOATS + INTEGERS + BIGDECIMAL + INFINITY)
end
def test_validates_numericality_of_with_nil_allowed
Topic.validates_numericality_of :approved, :allow_nil => true
invalid!(BLANK + JUNK)
- valid!(NIL + FLOATS + INTEGERS + BIGDECIMAL)
+ valid!(NIL + FLOATS + INTEGERS + BIGDECIMAL + INFINITY)
end
def test_validates_numericality_of_with_integer_only
Topic.validates_numericality_of :approved, :only_integer => true
- invalid!(NIL + BLANK + JUNK + FLOATS + BIGDECIMAL)
+ invalid!(NIL + BLANK + JUNK + FLOATS + BIGDECIMAL + INFINITY)
valid!(INTEGERS)
end
def test_validates_numericality_of_with_integer_only_and_nil_allowed
Topic.validates_numericality_of :approved, :only_integer => true, :allow_nil => true
- invalid!(BLANK + JUNK + FLOATS + BIGDECIMAL)
+ invalid!(BLANK + JUNK + FLOATS + BIGDECIMAL + INFINITY)
valid!(NIL + INTEGERS)
end
@@ -1433,7 +1446,7 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase
def test_validates_numericality_with_equal_to
Topic.validates_numericality_of :approved, :equal_to => 10
- invalid!([-10, 11], 'must be equal to 10')
+ invalid!([-10, 11] + INFINITY, 'must be equal to 10')
valid!([10])
end
diff --git a/activerecord/test/fixtures/companies.yml b/activerecord/test/fixtures/companies.yml
index c61128c09b..e7691fde46 100644
--- a/activerecord/test/fixtures/companies.yml
+++ b/activerecord/test/fixtures/companies.yml
@@ -5,6 +5,7 @@ first_client:
client_of: 2
name: Summit
ruby_type: Client
+ firm_name: 37signals
first_firm:
id: 1
diff --git a/activerecord/test/models/author.rb b/activerecord/test/models/author.rb
index f63af27403..136dc39cf3 100644
--- a/activerecord/test/models/author.rb
+++ b/activerecord/test/models/author.rb
@@ -1,6 +1,7 @@
class Author < ActiveRecord::Base
- has_many :posts
+ has_many :posts, :accessible => true
has_many :posts_with_comments, :include => :comments, :class_name => "Post"
+ has_many :posts_with_comments_sorted_by_comment_id, :include => :comments, :class_name => "Post", :order => 'comments.id'
has_many :posts_with_categories, :include => :categories, :class_name => "Post"
has_many :posts_with_comments_and_categories, :include => [ :comments, :categories ], :order => "posts.id", :class_name => "Post"
has_many :posts_containing_the_letter_a, :class_name => "Post"
diff --git a/activerecord/test/models/category.rb b/activerecord/test/models/category.rb
index f1d2e4805a..1660c61682 100644
--- a/activerecord/test/models/category.rb
+++ b/activerecord/test/models/category.rb
@@ -2,6 +2,7 @@ class Category < ActiveRecord::Base
has_and_belongs_to_many :posts
has_and_belongs_to_many :special_posts, :class_name => "Post"
has_and_belongs_to_many :other_posts, :class_name => "Post"
+ has_and_belongs_to_many :posts_with_authors_sorted_by_author_id, :class_name => "Post", :include => :authors, :order => "authors.id"
has_and_belongs_to_many(:select_testing_posts,
:class_name => 'Post',
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index 9fa810ac68..e6aa810146 100755
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -46,11 +46,14 @@ class Firm < Company
has_many :clients_using_finder_sql, :class_name => "Client", :finder_sql => 'SELECT * FROM companies WHERE 1=1'
has_many :plain_clients, :class_name => 'Client'
has_many :readonly_clients, :class_name => 'Client', :readonly => true
+ has_many :clients_using_primary_key, :class_name => 'Client',
+ :primary_key => 'name', :foreign_key => 'firm_name'
has_one :account, :foreign_key => "firm_id", :dependent => :destroy, :validate => true
has_one :unvalidated_account, :foreign_key => "firm_id", :class_name => 'Account', :validate => false
has_one :account_with_select, :foreign_key => "firm_id", :select => "id, firm_id", :class_name=>'Account'
has_one :readonly_account, :foreign_key => "firm_id", :class_name => "Account", :readonly => true
+ has_one :account_using_primary_key, :primary_key => "firm_id", :class_name => "Account"
end
class DependentFirm < Company
diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb
index 4f4d695b24..430d0b38f7 100644
--- a/activerecord/test/models/person.rb
+++ b/activerecord/test/models/person.rb
@@ -6,5 +6,5 @@ class Person < ActiveRecord::Base
has_many :references
has_many :jobs, :through => :references
has_one :favourite_reference, :class_name => 'Reference', :conditions => ['favourite=?', true]
-
+ has_many :posts_with_comments_sorted_by_comment_id, :through => :readers, :source => :post, :include => :comments, :order => 'comments.id'
end
diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb
index d9101706b5..e23818eb33 100644
--- a/activerecord/test/models/post.rb
+++ b/activerecord/test/models/post.rb
@@ -1,6 +1,11 @@
class Post < ActiveRecord::Base
named_scope :containing_the_letter_a, :conditions => "body LIKE '%a%'"
-
+ named_scope :with_authors_at_address, lambda { |address| {
+ :conditions => [ 'authors.author_address_id = ?', address.id ],
+ :joins => 'JOIN authors ON authors.id = posts.author_id'
+ }
+ }
+
belongs_to :author do
def greeting
"hello"
@@ -28,6 +33,12 @@ class Post < ActiveRecord::Base
has_and_belongs_to_many :categories
has_and_belongs_to_many :special_categories, :join_table => "categories_posts", :association_foreign_key => 'category_id'
+ belongs_to :creatable_author, :class_name => 'Author', :accessible => true
+ has_one :uncreatable_comment, :class_name => 'Comment', :accessible => false, :order => 'id desc'
+ has_one :creatable_comment, :class_name => 'Comment', :accessible => true, :order => 'id desc'
+ has_many :creatable_comments, :class_name => 'Comment', :accessible => true, :dependent => :destroy
+ has_and_belongs_to_many :creatable_categories, :class_name => 'Category', :accessible => true
+
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings do
def add_joins_and_select
diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb
index f63e862cfd..39ca1bf42a 100755
--- a/activerecord/test/models/topic.rb
+++ b/activerecord/test/models/topic.rb
@@ -4,6 +4,10 @@ class Topic < ActiveRecord::Base
{ :conditions => ['written_on < ?', time] }
}
named_scope :approved, :conditions => {:approved => true}
+ named_scope :by_lifo, :conditions => {:author_name => 'lifo'}
+
+ named_scope :approved_as_hash_condition, :conditions => {:topics => {:approved => true}}
+ named_scope 'approved_as_string', :conditions => {:approved => true}
named_scope :replied, :conditions => ['replies_count > 0']
named_scope :anonymous_extension do
def one
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 423929fd55..487a08f4ab 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -66,6 +66,7 @@ ActiveRecord::Schema.define do
create_table :categories, :force => true do |t|
t.string :name, :null => false
t.string :type
+ t.integer :categorizations_count
end
create_table :categories_posts, :force => true, :id => false do |t|
@@ -102,6 +103,7 @@ ActiveRecord::Schema.define do
t.string :type
t.string :ruby_type
t.integer :firm_id
+ t.string :firm_name
t.string :name
t.integer :client_of
t.integer :rating, :default => 1
@@ -407,6 +409,13 @@ ActiveRecord::Schema.define do
t.column :key, :string
end
+ create_table :integer_limits, :force => true do |t|
+ t.integer :"c_int_without_limit"
+ (1..8).each do |i|
+ t.integer :"c_int_#{i}", :limit => i
+ end
+ end
+
except 'SQLite' do
# fk_test_has_fk should be before fk_test_has_pk
create_table :fk_test_has_fk, :force => true do |t|