diff options
Diffstat (limited to 'activerecord/test')
34 files changed, 870 insertions, 417 deletions
diff --git a/activerecord/test/cases/adapters/mysql/enum_test.rb b/activerecord/test/cases/adapters/mysql/enum_test.rb index 40af317ad1..f4e7a3ef0a 100644 --- a/activerecord/test/cases/adapters/mysql/enum_test.rb +++ b/activerecord/test/cases/adapters/mysql/enum_test.rb @@ -5,6 +5,6 @@ class MysqlEnumTest < ActiveRecord::TestCase end def test_enum_limit - assert_equal 5, EnumTest.columns.first.limit + assert_equal 6, EnumTest.columns.first.limit end end diff --git a/activerecord/test/cases/adapters/mysql2/enum_test.rb b/activerecord/test/cases/adapters/mysql2/enum_test.rb index f3a05e48ad..6dd9a5ec87 100644 --- a/activerecord/test/cases/adapters/mysql2/enum_test.rb +++ b/activerecord/test/cases/adapters/mysql2/enum_test.rb @@ -5,6 +5,6 @@ class Mysql2EnumTest < ActiveRecord::TestCase end def test_enum_limit - assert_equal 5, EnumTest.columns.first.limit + assert_equal 6, EnumTest.columns.first.limit end end diff --git a/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb b/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb index a5a22bc30b..e78cb88562 100644 --- a/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb @@ -54,7 +54,7 @@ class CopyTableTest < ActiveRecord::TestCase end def test_copy_table_with_id_col_that_is_not_primary_key - test_copy_table('goofy_string_id', 'goofy_string_id2') do |from, to, options| + test_copy_table('goofy_string_id', 'goofy_string_id2') do original_id = @connection.columns('goofy_string_id').detect{|col| col.name == 'id' } copied_id = @connection.columns('goofy_string_id2').detect{|col| col.name == 'id' } assert_equal original_id.type, copied_id.type @@ -65,7 +65,7 @@ class CopyTableTest < ActiveRecord::TestCase end def test_copy_table_with_unconventional_primary_key - test_copy_table('owners', 'owners_unconventional') do |from, to, options| + test_copy_table('owners', 'owners_unconventional') do original_pk = @connection.primary_key('owners') copied_pk = @connection.primary_key('owners_unconventional') assert_equal original_pk, copied_pk diff --git a/activerecord/test/cases/aggregations_test.rb b/activerecord/test/cases/aggregations_test.rb index 10195e3ae4..5536702f58 100644 --- a/activerecord/test/cases/aggregations_test.rb +++ b/activerecord/test/cases/aggregations_test.rb @@ -141,7 +141,6 @@ class AggregationsTest < ActiveRecord::TestCase end class OverridingAggregationsTest < ActiveRecord::TestCase - class Name; end class DifferentName; end class Person < ActiveRecord::Base diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index d6850215b5..4aa6567d85 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -302,7 +302,7 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_association_loading_with_belongs_to_and_foreign_keys pets = Pet.all.merge!(:includes => :owner).to_a - assert_equal 3, pets.length + assert_equal 4, pets.length end def test_eager_association_loading_with_belongs_to 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 67d18f313a..70c6b489aa 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -583,7 +583,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_has_many_association_through_a_has_many_association_with_nonstandard_primary_keys - assert_equal 1, owners(:blackbeard).toys.count + assert_equal 2, owners(:blackbeard).toys.count end def test_find_on_has_many_association_collection_with_include_and_conditions @@ -882,6 +882,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert_equal [tags(:general)], post.reload.tags end + def test_has_many_through_obeys_order_on_through_association + owner = owners(:blackbeard) + assert owner.toys.to_sql.include?("pets.name desc") + assert_equal ["parrot", "bulbul"], owner.toys.map { |r| r.pet.name } + end + test "has many through associations on new records use null relations" do person = Person.new diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb index c8cad84013..ec128acf28 100644 --- a/activerecord/test/cases/associations/inverse_associations_test.rb +++ b/activerecord/test/cases/associations/inverse_associations_test.rb @@ -235,6 +235,22 @@ class InverseHasManyTests < ActiveRecord::TestCase 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_within_create_block_of_new_child + man = Man.first + interest = man.interests.build do |i| + assert i.man.equal?(man), "Man of child should be the same instance as a parent" + end + assert interest.man.equal?(man), "Man of the child should still be the same instance as a parent" + end + + def test_parent_instance_should_be_shared_within_build_block_of_new_child + man = Man.first + interest = man.interests.build do |i| + assert i.man.equal?(man), "Man of child should be the same instance as a parent" + end + assert interest.man.equal?(man), "Man of the child should still be the same instance as a parent" + end + def test_parent_instance_should_be_shared_with_poked_in_child m = men(:gordon) i = Interest.create(:topic => 'Industrial Revolution Re-enactment') @@ -303,6 +319,22 @@ class InverseHasManyTests < ActiveRecord::TestCase assert_equal man.name, man.interests.find(interest.id).man.name, "The name of the man should match after the child name is changed" end + def test_raise_record_not_found_error_when_invalid_ids_are_passed + man = Man.create! + + invalid_id = 2394823094892348920348523452345 + assert_raise(ActiveRecord::RecordNotFound) { man.interests.find(invalid_id) } + + invalid_ids = [8432342, 2390102913, 2453245234523452] + assert_raise(ActiveRecord::RecordNotFound) { man.interests.find(invalid_ids) } + end + + def test_raise_record_not_found_error_when_no_ids_are_passed + man = Man.create! + + assert_raise(ActiveRecord::RecordNotFound) { man.interests.find() } + end + def test_trying_to_use_inverses_that_dont_exist_should_raise_an_error assert_raise(ActiveRecord::InverseOfAssociationNotFoundError) { Man.first.secret_interests } end diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index a06bacafca..95c571fd03 100644 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -245,7 +245,6 @@ class AssociationProxyTest < ActiveRecord::TestCase end class OverridingAssociationsTest < ActiveRecord::TestCase - class Person < ActiveRecord::Base; end class DifferentPerson < ActiveRecord::Base; end class PeopleList < ActiveRecord::Base diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 648596b828..387c741762 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -69,7 +69,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end def test_boolean_attributes - assert ! Topic.find(1).approved? + assert !Topic.find(1).approved? assert Topic.find(2).approved? end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 08223902c7..83fc0b48f9 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -21,7 +21,6 @@ require 'models/parrot' require 'models/person' require 'models/edge' require 'models/joke' -require 'models/bulb' require 'models/bird' require 'models/car' require 'models/bulb' @@ -1378,9 +1377,9 @@ class BasicsTest < ActiveRecord::TestCase UnloadablePost.send(:current_scope=, UnloadablePost.all) UnloadablePost.unloadable - assert_not_nil Thread.current[:UnloadablePost_current_scope] + assert_not_nil ActiveRecord::Scoping::ScopeRegistry.instance.value_for(:current_scope, "UnloadablePost") ActiveSupport::Dependencies.remove_unloadable_constants! - assert_nil Thread.current[:UnloadablePost_current_scope] + assert_nil ActiveRecord::Scoping::ScopeRegistry.instance.value_for(:current_scope, "UnloadablePost") ensure Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost) end diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index c645523905..b0b647cbf7 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -96,25 +96,24 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_order_by_grouped_field - c = Account.all.merge!(:group => :firm_id, :order => "firm_id").sum(:credit_limit) + c = Account.group(:firm_id).order("firm_id").sum(:credit_limit) assert_equal [1, 2, 6, 9], c.keys.compact end def test_should_order_by_calculation - c = Account.all.merge!(:group => :firm_id, :order => "sum_credit_limit desc, firm_id").sum(:credit_limit) + c = Account.group(:firm_id).order("sum_credit_limit desc, firm_id").sum(:credit_limit) assert_equal [105, 60, 53, 50, 50], c.keys.collect { |k| c[k] } assert_equal [6, 2, 9, 1], c.keys.compact end def test_should_limit_calculation - c = Account.all.merge!(:where => "firm_id IS NOT NULL", - :group => :firm_id, :order => "firm_id", :limit => 2).sum(:credit_limit) + c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id").limit(2).sum(:credit_limit) assert_equal [1, 2], c.keys.compact end def test_should_limit_calculation_with_offset - c = Account.all.merge!(:where => "firm_id IS NOT NULL", :group => :firm_id, - :order => "firm_id", :limit => 2, :offset => 1).sum(:credit_limit) + c = Account.where("firm_id IS NOT NULL").group(:firm_id).order("firm_id"). + limit(2).offset(1).sum(:credit_limit) assert_equal [2, 6], c.keys.compact end @@ -164,8 +163,7 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_group_by_summed_field_having_condition - c = Account.all.merge!(:group => :firm_id, - :having => 'sum(credit_limit) > 50').sum(:credit_limit) + c = Account.group(:firm_id).having('sum(credit_limit) > 50').sum(:credit_limit) assert_nil c[1] assert_equal 105, c[6] assert_equal 60, c[2] @@ -200,17 +198,15 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_group_by_summed_field_with_conditions - c = Account.all.merge!(:where => 'firm_id > 1', - :group => :firm_id).sum(:credit_limit) + c = Account.where('firm_id > 1').group(:firm_id).sum(:credit_limit) assert_nil c[1] assert_equal 105, c[6] assert_equal 60, c[2] end def test_should_group_by_summed_field_with_conditions_and_having - c = Account.all.merge!(:where => 'firm_id > 1', - :group => :firm_id, - :having => 'sum(credit_limit) > 60').sum(:credit_limit) + c = Account.where('firm_id > 1').group(:firm_id). + having('sum(credit_limit) > 60').sum(:credit_limit) assert_nil c[1] assert_equal 105, c[6] assert_nil c[2] @@ -322,7 +318,7 @@ class CalculationsTest < ActiveRecord::TestCase def test_should_count_scoped_select Account.update_all("credit_limit = NULL") - assert_equal 0, Account.all.merge!(:select => "credit_limit").count + assert_equal 0, Account.select("credit_limit").count end def test_should_count_scoped_select_with_options @@ -330,11 +326,11 @@ class CalculationsTest < ActiveRecord::TestCase Account.last.update_columns('credit_limit' => 49) Account.first.update_columns('credit_limit' => 51) - assert_equal 1, Account.all.merge!(:select => "credit_limit").where('credit_limit >= 50').count + assert_equal 1, Account.select("credit_limit").where('credit_limit >= 50').count end def test_should_count_manual_select_with_include - assert_equal 6, Account.all.merge!(:select => "DISTINCT accounts.id", :includes => :firm).count + assert_equal 6, Account.select("DISTINCT accounts.id").includes(:firm).count end def test_count_with_column_parameter @@ -366,7 +362,7 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_count_field_in_joined_table_with_group_by - c = Account.all.merge!(:group => 'accounts.firm_id', :joins => :firm).count('companies.id') + c = Account.group('accounts.firm_id').joins(:firm).count('companies.id') [1,6,2,9].each { |firm_id| assert c.keys.include?(firm_id) } end diff --git a/activerecord/test/cases/coders/yaml_column_test.rb b/activerecord/test/cases/coders/yaml_column_test.rb index b874adc081..b72c54f97b 100644 --- a/activerecord/test/cases/coders/yaml_column_test.rb +++ b/activerecord/test/cases/coders/yaml_column_test.rb @@ -43,10 +43,20 @@ module ActiveRecord assert_equal [], coder.load([]) end - def test_load_swallows_yaml_exceptions + def test_load_doesnt_swallow_yaml_exceptions coder = YAMLColumn.new bad_yaml = '--- {' - assert_equal bad_yaml, coder.load(bad_yaml) + assert_raises(Psych::SyntaxError) do + coder.load(bad_yaml) + end + end + + def test_load_doesnt_handle_undefined_class_or_module + coder = YAMLColumn.new + missing_class_yaml = '--- !ruby/object:DoesNotExistAndShouldntEver {}\n' + assert_raises(ArgumentError) do + coder.load(missing_class_yaml) + end end end end diff --git a/activerecord/test/cases/column_test.rb b/activerecord/test/cases/column_test.rb index adbe51f430..3a4f414ae8 100644 --- a/activerecord/test/cases/column_test.rb +++ b/activerecord/test/cases/column_test.rb @@ -6,6 +6,9 @@ module ActiveRecord class ColumnTest < ActiveRecord::TestCase def test_type_cast_boolean column = Column.new("field", nil, "boolean") + assert column.type_cast('').nil? + assert column.type_cast(nil).nil? + assert column.type_cast(true) assert column.type_cast(1) assert column.type_cast('1') @@ -15,15 +18,21 @@ module ActiveRecord assert column.type_cast('TRUE') assert column.type_cast('on') assert column.type_cast('ON') - assert !column.type_cast(false) - assert !column.type_cast(0) - assert !column.type_cast('0') - assert !column.type_cast('f') - assert !column.type_cast('F') - assert !column.type_cast('false') - assert !column.type_cast('FALSE') - assert !column.type_cast('off') - assert !column.type_cast('OFF') + + # explicitly check for false vs nil + assert_equal false, column.type_cast(false) + assert_equal false, column.type_cast(0) + assert_equal false, column.type_cast('0') + assert_equal false, column.type_cast('f') + assert_equal false, column.type_cast('F') + assert_equal false, column.type_cast('false') + assert_equal false, column.type_cast('FALSE') + assert_equal false, column.type_cast('off') + assert_equal false, column.type_cast('OFF') + assert_equal false, column.type_cast(' ') + assert_equal false, column.type_cast("\u3000\r\n") + assert_equal false, column.type_cast("\u0000") + assert_equal false, column.type_cast('SOMETHING RANDOM') end def test_type_cast_integer @@ -65,8 +74,9 @@ module ActiveRecord def test_type_cast_time column = Column.new("field", nil, "time") + assert_equal nil, column.type_cast(nil) assert_equal nil, column.type_cast('') - assert_equal nil, column.type_cast(' ') + assert_equal nil, column.type_cast('ABC') time_string = Time.now.utc.strftime("%T") assert_equal time_string, column.type_cast(time_string).strftime("%T") @@ -74,8 +84,10 @@ module ActiveRecord def test_type_cast_datetime_and_timestamp [Column.new("field", nil, "datetime"), Column.new("field", nil, "timestamp")].each do |column| + assert_equal nil, column.type_cast(nil) assert_equal nil, column.type_cast('') assert_equal nil, column.type_cast(' ') + assert_equal nil, column.type_cast('ABC') datetime_string = Time.now.utc.strftime("%FT%T") assert_equal datetime_string, column.type_cast(datetime_string).strftime("%FT%T") @@ -84,8 +96,10 @@ module ActiveRecord def test_type_cast_date column = Column.new("field", nil, "date") + assert_equal nil, column.type_cast(nil) assert_equal nil, column.type_cast('') - assert_equal nil, column.type_cast(' ') + assert_equal nil, column.type_cast(' ') + assert_equal nil, column.type_cast('ABC') date_string = Time.now.utc.strftime("%F") assert_equal date_string, column.type_cast(date_string).strftime("%F") diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index 99d54e7526..a9be132801 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -194,6 +194,10 @@ class InheritanceTest < ActiveRecord::TestCase assert_raise(ActiveRecord::SubclassNotFound) { Company.new(:type => 'Account') } end + def test_new_with_complex_inheritance + assert_nothing_raised { Client.new(type: 'VerySpecialClient') } + end + def test_new_with_autoload_paths path = File.expand_path('../../models/autoloadable', __FILE__) ActiveSupport::Dependencies.autoload_paths << path diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 572431ee87..db3bb56f1f 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -12,13 +12,13 @@ require 'models/minimalistic' require 'models/warehouse_thing' require 'models/parrot' require 'models/minivan' +require 'models/owner' require 'models/person' require 'models/pet' require 'models/toy' require 'rexml/document' class PersistencesTest < ActiveRecord::TestCase - fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts, :minivans, :pets, :toys # Oracle UPDATE does not support ORDER BY diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 9ca980fdf6..34ecdb3cc9 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -1,10 +1,12 @@ require "cases/helper" require 'models/post' require 'models/comment' +require 'models/author' +require 'models/rating' module ActiveRecord class RelationTest < ActiveRecord::TestCase - fixtures :posts, :comments + fixtures :posts, :comments, :authors class FakeKlass < Struct.new(:table_name, :name) end @@ -176,6 +178,13 @@ module ActiveRecord relation.merge!(where: ['foo = ?', 'bar']) assert_equal ['foo = bar'], relation.where_values end + + def test_relation_merging_with_merged_joins + special_comments_with_ratings = SpecialComment.joins(:ratings) + posts_with_special_comments_with_ratings = Post.group("posts.id").joins(:special_comments).merge(special_comments_with_ratings) + assert_equal 3, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count.length + end + end class RelationMutationTest < ActiveSupport::TestCase diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 6e03a2bd67..a48ae1036f 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -177,10 +177,10 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_schema_dumps_index_columns_in_right_order index_definition = standard_dump.split(/\n/).grep(/add_index.*companies/).first.strip - if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) or current_adapter?(:PostgreSQLAdapter) - assert_equal 'add_index "companies", ["firm_id", "type", "rating"], name: "company_index", using: :btree', index_definition - else - assert_equal 'add_index "companies", ["firm_id", "type", "rating"], name: "company_index"', index_definition + if current_adapter?(:MysqlAdapter) || current_adapter?(:Mysql2Adapter) || current_adapter?(:PostgreSQLAdapter) + assert_equal 'add_index "companies", ["firm_id", "type", "rating"], name: "company_index", using: :btree', index_definition + else + assert_equal 'add_index "companies", ["firm_id", "type", "rating"], name: "company_index"', index_definition end end @@ -188,7 +188,7 @@ class SchemaDumperTest < ActiveRecord::TestCase index_definition = standard_dump.split(/\n/).grep(/add_index.*company_partial_index/).first.strip if current_adapter?(:PostgreSQLAdapter) assert_equal 'add_index "companies", ["firm_id", "type"], name: "company_partial_index", where: "(rating > 10)", using: :btree', index_definition - elsif current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) + elsif current_adapter?(:MysqlAdapter) || current_adapter?(:Mysql2Adapter) assert_equal 'add_index "companies", ["firm_id", "type"], name: "company_partial_index", using: :btree', index_definition else assert_equal 'add_index "companies", ["firm_id", "type"], name: "company_partial_index"', index_definition @@ -242,6 +242,11 @@ class SchemaDumperTest < ActiveRecord::TestCase end if current_adapter?(:PostgreSQLAdapter) + def test_schema_dump_includes_bigint_default + output = standard_dump + assert_match %r{t.integer\s+"bigint_default",\s+limit: 8,\s+default: 0}, output + end + def test_schema_dump_includes_extensions connection = ActiveRecord::Base.connection skip unless connection.supports_extensions? diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb index e2af66ff9d..5a65ad5dfa 100644 --- a/activerecord/test/cases/relation_scoping_test.rb +++ b/activerecord/test/cases/scoping/default_scoping_test.rb @@ -1,334 +1,6 @@ -require "cases/helper" +require 'cases/helper' require 'models/post' -require 'models/author' require 'models/developer' -require 'models/project' -require 'models/comment' -require 'models/category' -require 'models/person' -require 'models/reference' - -class RelationScopingTest < ActiveRecord::TestCase - fixtures :authors, :developers, :projects, :comments, :posts, :developers_projects - - def test_reverse_order - assert_equal Developer.order("id DESC").to_a.reverse, Developer.order("id DESC").reverse_order - end - - def test_reverse_order_with_arel_node - assert_equal Developer.order("id DESC").to_a.reverse, Developer.order(Developer.arel_table[:id].desc).reverse_order - end - - def test_reverse_order_with_multiple_arel_nodes - assert_equal Developer.order("id DESC").order("name DESC").to_a.reverse, Developer.order(Developer.arel_table[:id].desc).order(Developer.arel_table[:name].desc).reverse_order - end - - def test_reverse_order_with_arel_nodes_and_strings - assert_equal Developer.order("id DESC").order("name DESC").to_a.reverse, Developer.order("id DESC").order(Developer.arel_table[:name].desc).reverse_order - end - - def test_double_reverse_order_produces_original_order - assert_equal Developer.order("name DESC"), Developer.order("name DESC").reverse_order.reverse_order - end - - def test_scoped_find - Developer.where("name = 'David'").scoping do - assert_nothing_raised { Developer.find(1) } - end - end - - def test_scoped_find_first - developer = Developer.find(10) - Developer.where("salary = 100000").scoping do - assert_equal developer, Developer.order("name").first - end - end - - def test_scoped_find_last - highest_salary = Developer.order("salary DESC").first - - Developer.order("salary").scoping do - assert_equal highest_salary, Developer.last - end - end - - def test_scoped_find_last_preserves_scope - lowest_salary = Developer.order("salary ASC").first - highest_salary = Developer.order("salary DESC").first - - Developer.order("salary").scoping do - assert_equal highest_salary, Developer.last - assert_equal lowest_salary, Developer.first - end - end - - def test_scoped_find_combines_and_sanitizes_conditions - Developer.where("salary = 9000").scoping do - assert_equal developers(:poor_jamis), Developer.where("name = 'Jamis'").first - end - end - - def test_scoped_find_all - Developer.where("name = 'David'").scoping do - assert_equal [developers(:david)], Developer.all - end - end - - def test_scoped_find_select - Developer.select("id, name").scoping do - developer = Developer.where("name = 'David'").first - assert_equal "David", developer.name - assert !developer.has_attribute?(:salary) - end - end - - def test_scope_select_concatenates - Developer.select("id, name").scoping do - developer = Developer.select('salary').where("name = 'David'").first - assert_equal 80000, developer.salary - assert developer.has_attribute?(:id) - assert developer.has_attribute?(:name) - assert developer.has_attribute?(:salary) - end - end - - def test_scoped_count - Developer.where("name = 'David'").scoping do - assert_equal 1, Developer.count - end - - Developer.where('salary = 100000').scoping do - assert_equal 8, Developer.count - assert_equal 1, Developer.where("name LIKE 'fixture_1%'").count - end - end - - def test_scoped_find_include - # with the include, will retrieve only developers for the given project - scoped_developers = Developer.includes(:projects).scoping do - Developer.where('projects.id' => 2).to_a - end - assert scoped_developers.include?(developers(:david)) - assert !scoped_developers.include?(developers(:jamis)) - assert_equal 1, scoped_developers.size - end - - def test_scoped_find_joins - scoped_developers = Developer.joins('JOIN developers_projects ON id = developer_id').scoping do - Developer.where('developers_projects.project_id = 2').to_a - 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_create_with_where - new_comment = VerySpecialComment.where(:post_id => 1).scoping do - VerySpecialComment.create :body => "Wonderful world" - end - - assert_equal 1, new_comment.post_id - assert Post.find(1).comments.include?(new_comment) - end - - def test_scoped_create_with_create_with - new_comment = VerySpecialComment.create_with(:post_id => 1).scoping do - VerySpecialComment.create :body => "Wonderful world" - end - - assert_equal 1, new_comment.post_id - assert Post.find(1).comments.include?(new_comment) - end - - def test_scoped_create_with_create_with_has_higher_priority - new_comment = VerySpecialComment.where(:post_id => 2).create_with(:post_id => 1).scoping do - VerySpecialComment.create :body => "Wonderful world" - end - - assert_equal 1, new_comment.post_id - assert Post.find(1).comments.include?(new_comment) - end - - def test_ensure_that_method_scoping_is_correctly_restored - begin - Developer.where("name = 'Jamis'").scoping do - raise "an exception" - end - rescue - end - - assert !Developer.all.where_values.include?("name = 'Jamis'") - end - - def test_default_scope_filters_on_joins - assert_equal 1, DeveloperFilteredOnJoins.all.count - assert_equal DeveloperFilteredOnJoins.all.first, developers(:david).becomes(DeveloperFilteredOnJoins) - end - - def test_update_all_default_scope_filters_on_joins - DeveloperFilteredOnJoins.update_all(:salary => 65000) - assert_equal 65000, Developer.find(developers(:david).id).salary - - # has not changed jamis - assert_not_equal 65000, Developer.find(developers(:jamis).id).salary - end - - def test_delete_all_default_scope_filters_on_joins - assert_not_equal [], DeveloperFilteredOnJoins.all - - DeveloperFilteredOnJoins.delete_all() - - assert_equal [], DeveloperFilteredOnJoins.all - assert_not_equal [], Developer.all - end -end - -class NestedRelationScopingTest < ActiveRecord::TestCase - fixtures :authors, :developers, :projects, :comments, :posts - - def test_merge_options - Developer.where('salary = 80000').scoping do - Developer.limit(10).scoping do - devs = Developer.all - assert_match '(salary = 80000)', devs.to_sql - assert_equal 10, devs.taken - end - end - end - - def test_merge_inner_scope_has_priority - Developer.limit(5).scoping do - Developer.limit(10).scoping do - assert_equal 10, Developer.all.size - end - end - end - - def test_replace_options - Developer.where(:name => 'David').scoping do - Developer.unscoped do - assert_equal 'Jamis', Developer.where(:name => 'Jamis').first[:name] - end - - assert_equal 'David', Developer.first[:name] - end - end - - def test_three_level_nested_exclusive_scoped_find - Developer.where("name = 'Jamis'").scoping do - assert_equal 'Jamis', Developer.first.name - - Developer.unscoped.where("name = 'David'") do - assert_equal 'David', Developer.first.name - - Developer.unscoped.where("name = 'Maiha'") do - assert_equal nil, Developer.first - end - - # ensure that scoping is restored - assert_equal 'David', Developer.first.name - end - - # ensure that scoping is restored - assert_equal 'Jamis', Developer.first.name - end - end - - def test_nested_scoped_create - comment = Comment.create_with(:post_id => 1).scoping do - Comment.create_with(:post_id => 2).scoping do - Comment.create :body => "Hey guys, nested scopes are broken. Please fix!" - end - end - - assert_equal 2, comment.post_id - end - - def test_nested_exclusive_scope_for_create - comment = Comment.create_with(:body => "Hey guys, nested scopes are broken. Please fix!").scoping do - Comment.unscoped.create_with(:post_id => 1).scoping do - assert Comment.new.body.blank? - Comment.create :body => "Hey guys" - end - end - - assert_equal 1, comment.post_id - assert_equal 'Hey guys', comment.body - end -end - -class HasManyScopingTest< ActiveRecord::TestCase - fixtures :comments, :posts, :people, :references - - def setup - @welcome = Post.find(1) - end - - def test_forwarding_of_static_methods - assert_equal 'a comment...', Comment.what_are_you - assert_equal 'a comment...', @welcome.comments.what_are_you - end - - def test_forwarding_to_scoped - assert_equal 4, Comment.search_by_type('Comment').size - assert_equal 2, @welcome.comments.search_by_type('Comment').size - end - - def test_nested_scope_finder - Comment.where('1=0').scoping do - assert_equal 0, @welcome.comments.count - assert_equal 'a comment...', @welcome.comments.what_are_you - end - - Comment.where('1=1').scoping do - assert_equal 2, @welcome.comments.count - assert_equal 'a comment...', @welcome.comments.what_are_you - end - end - - def test_should_maintain_default_scope_on_associations - magician = BadReference.find(1) - assert_equal [magician], people(:michael).bad_references - end - - def test_should_default_scope_on_associations_is_overridden_by_association_conditions - 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 - michael = Person.where(:id => people(:michael).id).includes(:bad_references).first - magician = BadReference.find(1) - assert_equal [magician], michael.bad_references - end -end - -class HasAndBelongsToManyScopingTest< ActiveRecord::TestCase - fixtures :posts, :categories, :categories_posts - - def setup - @welcome = Post.find(1) - end - - def test_forwarding_of_static_methods - assert_equal 'a category...', Category.what_are_you - assert_equal 'a category...', @welcome.categories.what_are_you - end - - def test_nested_scope_finder - Category.where('1=0').scoping do - assert_equal 0, @welcome.categories.count - assert_equal 'a category...', @welcome.categories.what_are_you - end - - Category.where('1=1').scoping do - assert_equal 2, @welcome.categories.count - assert_equal 'a category...', @welcome.categories.what_are_you - end - end -end class DefaultScopingTest < ActiveRecord::TestCase fixtures :developers, :posts diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb index 1eb3bc4177..afe32af1d1 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/scoping/named_scoping_test.rb @@ -6,7 +6,7 @@ require 'models/reply' require 'models/author' require 'models/developer' -class NamedScopeTest < ActiveRecord::TestCase +class NamedScopingTest < ActiveRecord::TestCase fixtures :posts, :authors, :topics, :comments, :author_addresses def test_implements_enumerable @@ -459,4 +459,9 @@ class NamedScopeTest < ActiveRecord::TestCase end assert_equal [posts(:welcome).title], klass.all.map(&:title) end + + def test_subclass_merges_scopes_properly + assert_equal 1, SpecialComment.where(body: 'go crazy').created.count + end + end diff --git a/activerecord/test/cases/scoping/relation_scoping_test.rb b/activerecord/test/cases/scoping/relation_scoping_test.rb new file mode 100644 index 0000000000..0018fc06f2 --- /dev/null +++ b/activerecord/test/cases/scoping/relation_scoping_test.rb @@ -0,0 +1,331 @@ +require "cases/helper" +require 'models/post' +require 'models/author' +require 'models/developer' +require 'models/project' +require 'models/comment' +require 'models/category' +require 'models/person' +require 'models/reference' + +class RelationScopingTest < ActiveRecord::TestCase + fixtures :authors, :developers, :projects, :comments, :posts, :developers_projects + + def test_reverse_order + assert_equal Developer.order("id DESC").to_a.reverse, Developer.order("id DESC").reverse_order + end + + def test_reverse_order_with_arel_node + assert_equal Developer.order("id DESC").to_a.reverse, Developer.order(Developer.arel_table[:id].desc).reverse_order + end + + def test_reverse_order_with_multiple_arel_nodes + assert_equal Developer.order("id DESC").order("name DESC").to_a.reverse, Developer.order(Developer.arel_table[:id].desc).order(Developer.arel_table[:name].desc).reverse_order + end + + def test_reverse_order_with_arel_nodes_and_strings + assert_equal Developer.order("id DESC").order("name DESC").to_a.reverse, Developer.order("id DESC").order(Developer.arel_table[:name].desc).reverse_order + end + + def test_double_reverse_order_produces_original_order + assert_equal Developer.order("name DESC"), Developer.order("name DESC").reverse_order.reverse_order + end + + def test_scoped_find + Developer.where("name = 'David'").scoping do + assert_nothing_raised { Developer.find(1) } + end + end + + def test_scoped_find_first + developer = Developer.find(10) + Developer.where("salary = 100000").scoping do + assert_equal developer, Developer.order("name").first + end + end + + def test_scoped_find_last + highest_salary = Developer.order("salary DESC").first + + Developer.order("salary").scoping do + assert_equal highest_salary, Developer.last + end + end + + def test_scoped_find_last_preserves_scope + lowest_salary = Developer.order("salary ASC").first + highest_salary = Developer.order("salary DESC").first + + Developer.order("salary").scoping do + assert_equal highest_salary, Developer.last + assert_equal lowest_salary, Developer.first + end + end + + def test_scoped_find_combines_and_sanitizes_conditions + Developer.where("salary = 9000").scoping do + assert_equal developers(:poor_jamis), Developer.where("name = 'Jamis'").first + end + end + + def test_scoped_find_all + Developer.where("name = 'David'").scoping do + assert_equal [developers(:david)], Developer.all + end + end + + def test_scoped_find_select + Developer.select("id, name").scoping do + developer = Developer.where("name = 'David'").first + assert_equal "David", developer.name + assert !developer.has_attribute?(:salary) + end + end + + def test_scope_select_concatenates + Developer.select("id, name").scoping do + developer = Developer.select('salary').where("name = 'David'").first + assert_equal 80000, developer.salary + assert developer.has_attribute?(:id) + assert developer.has_attribute?(:name) + assert developer.has_attribute?(:salary) + end + end + + def test_scoped_count + Developer.where("name = 'David'").scoping do + assert_equal 1, Developer.count + end + + Developer.where('salary = 100000').scoping do + assert_equal 8, Developer.count + assert_equal 1, Developer.where("name LIKE 'fixture_1%'").count + end + end + + def test_scoped_find_include + # with the include, will retrieve only developers for the given project + scoped_developers = Developer.includes(:projects).scoping do + Developer.where('projects.id' => 2).to_a + end + assert scoped_developers.include?(developers(:david)) + assert !scoped_developers.include?(developers(:jamis)) + assert_equal 1, scoped_developers.size + end + + def test_scoped_find_joins + scoped_developers = Developer.joins('JOIN developers_projects ON id = developer_id').scoping do + Developer.where('developers_projects.project_id = 2').to_a + 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_create_with_where + new_comment = VerySpecialComment.where(:post_id => 1).scoping do + VerySpecialComment.create :body => "Wonderful world" + end + + assert_equal 1, new_comment.post_id + assert Post.find(1).comments.include?(new_comment) + end + + def test_scoped_create_with_create_with + new_comment = VerySpecialComment.create_with(:post_id => 1).scoping do + VerySpecialComment.create :body => "Wonderful world" + end + + assert_equal 1, new_comment.post_id + assert Post.find(1).comments.include?(new_comment) + end + + def test_scoped_create_with_create_with_has_higher_priority + new_comment = VerySpecialComment.where(:post_id => 2).create_with(:post_id => 1).scoping do + VerySpecialComment.create :body => "Wonderful world" + end + + assert_equal 1, new_comment.post_id + assert Post.find(1).comments.include?(new_comment) + end + + def test_ensure_that_method_scoping_is_correctly_restored + begin + Developer.where("name = 'Jamis'").scoping do + raise "an exception" + end + rescue + end + + assert !Developer.all.where_values.include?("name = 'Jamis'") + end + + def test_default_scope_filters_on_joins + assert_equal 1, DeveloperFilteredOnJoins.all.count + assert_equal DeveloperFilteredOnJoins.all.first, developers(:david).becomes(DeveloperFilteredOnJoins) + end + + def test_update_all_default_scope_filters_on_joins + DeveloperFilteredOnJoins.update_all(:salary => 65000) + assert_equal 65000, Developer.find(developers(:david).id).salary + + # has not changed jamis + assert_not_equal 65000, Developer.find(developers(:jamis).id).salary + end + + def test_delete_all_default_scope_filters_on_joins + assert_not_equal [], DeveloperFilteredOnJoins.all + + DeveloperFilteredOnJoins.delete_all() + + assert_equal [], DeveloperFilteredOnJoins.all + assert_not_equal [], Developer.all + end +end + +class NestedRelationScopingTest < ActiveRecord::TestCase + fixtures :authors, :developers, :projects, :comments, :posts + + def test_merge_options + Developer.where('salary = 80000').scoping do + Developer.limit(10).scoping do + devs = Developer.all + assert_match '(salary = 80000)', devs.to_sql + assert_equal 10, devs.taken + end + end + end + + def test_merge_inner_scope_has_priority + Developer.limit(5).scoping do + Developer.limit(10).scoping do + assert_equal 10, Developer.all.size + end + end + end + + def test_replace_options + Developer.where(:name => 'David').scoping do + Developer.unscoped do + assert_equal 'Jamis', Developer.where(:name => 'Jamis').first[:name] + end + + assert_equal 'David', Developer.first[:name] + end + end + + def test_three_level_nested_exclusive_scoped_find + Developer.where("name = 'Jamis'").scoping do + assert_equal 'Jamis', Developer.first.name + + Developer.unscoped.where("name = 'David'") do + assert_equal 'David', Developer.first.name + + Developer.unscoped.where("name = 'Maiha'") do + assert_equal nil, Developer.first + end + + # ensure that scoping is restored + assert_equal 'David', Developer.first.name + end + + # ensure that scoping is restored + assert_equal 'Jamis', Developer.first.name + end + end + + def test_nested_scoped_create + comment = Comment.create_with(:post_id => 1).scoping do + Comment.create_with(:post_id => 2).scoping do + Comment.create :body => "Hey guys, nested scopes are broken. Please fix!" + end + end + + assert_equal 2, comment.post_id + end + + def test_nested_exclusive_scope_for_create + comment = Comment.create_with(:body => "Hey guys, nested scopes are broken. Please fix!").scoping do + Comment.unscoped.create_with(:post_id => 1).scoping do + assert Comment.new.body.blank? + Comment.create :body => "Hey guys" + end + end + + assert_equal 1, comment.post_id + assert_equal 'Hey guys', comment.body + end +end + +class HasManyScopingTest< ActiveRecord::TestCase + fixtures :comments, :posts, :people, :references + + def setup + @welcome = Post.find(1) + end + + def test_forwarding_of_static_methods + assert_equal 'a comment...', Comment.what_are_you + assert_equal 'a comment...', @welcome.comments.what_are_you + end + + def test_forwarding_to_scoped + assert_equal 4, Comment.search_by_type('Comment').size + assert_equal 2, @welcome.comments.search_by_type('Comment').size + end + + def test_nested_scope_finder + Comment.where('1=0').scoping do + assert_equal 0, @welcome.comments.count + assert_equal 'a comment...', @welcome.comments.what_are_you + end + + Comment.where('1=1').scoping do + assert_equal 2, @welcome.comments.count + assert_equal 'a comment...', @welcome.comments.what_are_you + end + end + + def test_should_maintain_default_scope_on_associations + magician = BadReference.find(1) + assert_equal [magician], people(:michael).bad_references + end + + def test_should_default_scope_on_associations_is_overridden_by_association_conditions + 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 + michael = Person.where(:id => people(:michael).id).includes(:bad_references).first + magician = BadReference.find(1) + assert_equal [magician], michael.bad_references + end +end + +class HasAndBelongsToManyScopingTest< ActiveRecord::TestCase + fixtures :posts, :categories, :categories_posts + + def setup + @welcome = Post.find(1) + end + + def test_forwarding_of_static_methods + assert_equal 'a category...', Category.what_are_you + assert_equal 'a category...', @welcome.categories.what_are_you + end + + def test_nested_scope_finder + Category.where('1=0').scoping do + assert_equal 0, @welcome.categories.count + assert_equal 'a category...', @welcome.categories.what_are_you + end + + Category.where('1=1').scoping do + assert_equal 2, @welcome.categories.count + assert_equal 'a category...', @welcome.categories.what_are_you + end + end +end diff --git a/activerecord/test/cases/statement_cache_test.rb b/activerecord/test/cases/statement_cache_test.rb new file mode 100644 index 0000000000..76da49707f --- /dev/null +++ b/activerecord/test/cases/statement_cache_test.rb @@ -0,0 +1,64 @@ +require 'cases/helper' +require 'models/book' +require 'models/liquid' +require 'models/molecule' +require 'models/electron' + +module ActiveRecord + class StatementCacheTest < ActiveRecord::TestCase + def setup + @connection = ActiveRecord::Base.connection + end + + def test_statement_cache_with_simple_statement + cache = ActiveRecord::StatementCache.new do + Book.where(name: "my book").where("author_id > 3") + end + + Book.create(name: "my book", author_id: 4) + + books = cache.execute + assert_equal "my book", books[0].name + end + + def test_statement_cache_with_nil_statement_raises_error + assert_raise(ArgumentError) do + ActiveRecord::StatementCache.new do + nil + end + end + end + + def test_statement_cache_with_complex_statement + cache = ActiveRecord::StatementCache.new do + Liquid.joins(:molecules => :electrons).where('molecules.name' => 'dioxane', 'electrons.name' => 'lepton') + end + + salty = Liquid.create(name: 'salty') + molecule = salty.molecules.create(name: 'dioxane') + molecule.electrons.create(name: 'lepton') + + liquids = cache.execute + assert_equal "salty", liquids[0].name + end + + def test_statement_cache_values_differ + cache = ActiveRecord::StatementCache.new do + Book.where(name: "my book") + end + + 3.times do + Book.create(name: "my book") + end + + first_books = cache.execute + + 3.times do + Book.create(name: "my book") + end + + additional_books = cache.execute + assert first_books != additional_books + end + end +end diff --git a/activerecord/test/cases/tasks/firebird_rake_test.rb b/activerecord/test/cases/tasks/firebird_rake_test.rb new file mode 100644 index 0000000000..c54989ae34 --- /dev/null +++ b/activerecord/test/cases/tasks/firebird_rake_test.rb @@ -0,0 +1,100 @@ +require 'cases/helper' + +unless defined?(FireRuby::Database) +module FireRuby + module Database; end +end +end + +module ActiveRecord + module FirebirdSetupper + def setup + @database = 'db.firebird' + @connection = stub :connection + @configuration = { + 'adapter' => 'firebird', + 'database' => @database + } + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + + @tasks = Class.new(ActiveRecord::Tasks::FirebirdDatabaseTasks) do + def initialize(configuration) + ActiveSupport::Deprecation.silence { super } + end + end + ActiveRecord::Tasks::DatabaseTasks.stubs(:class_for_adapter).returns(@tasks) unless defined? ActiveRecord::ConnectionAdapters::FirebirdAdapter + end + end + + class FirebirdDBCreateTest < ActiveRecord::TestCase + include FirebirdSetupper + + def test_db_retrieves_create + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end + assert_match(/not supported/, message) + end + end + + class FirebirdDBDropTest < ActiveRecord::TestCase + include FirebirdSetupper + + def test_db_retrieves_drop + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + assert_match(/not supported/, message) + end + end + + class FirebirdDBCharsetAndCollationTest < ActiveRecord::TestCase + include FirebirdSetupper + + def test_db_retrieves_collation + assert_raise NoMethodError do + ActiveRecord::Tasks::DatabaseTasks.collation @configuration + end + end + + def test_db_retrieves_charset + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.charset @configuration + end + assert_match(/not supported/, message) + end + end + + class FirebirdStructureDumpTest < ActiveRecord::TestCase + include FirebirdSetupper + + def setup + super + FireRuby::Database.stubs(:db_string_for).returns(@database) + end + + def test_structure_dump + filename = "filebird.sql" + Kernel.expects(:system).with("isql -a #{@database} > #{filename}") + + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + end + end + + class FirebirdStructureLoadTest < ActiveRecord::TestCase + include FirebirdSetupper + + def setup + super + FireRuby::Database.stubs(:db_string_for).returns(@database) + end + + def test_structure_load + filename = "firebird.sql" + Kernel.expects(:system).with("isql -i #{filename} #{@database}") + + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + end + end +end diff --git a/activerecord/test/cases/tasks/oracle_rake_test.rb b/activerecord/test/cases/tasks/oracle_rake_test.rb new file mode 100644 index 0000000000..5f840febbc --- /dev/null +++ b/activerecord/test/cases/tasks/oracle_rake_test.rb @@ -0,0 +1,93 @@ +require 'cases/helper' + +module ActiveRecord + module OracleSetupper + def setup + @database = 'db.oracle' + @connection = stub :connection + @configuration = { + 'adapter' => 'oracle', + 'database' => @database + } + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + + @tasks = Class.new(ActiveRecord::Tasks::OracleDatabaseTasks) do + def initialize(configuration) + ActiveSupport::Deprecation.silence { super } + end + end + ActiveRecord::Tasks::DatabaseTasks.stubs(:class_for_adapter).returns(@tasks) unless defined? ActiveRecord::ConnectionAdapters::OracleAdapter + end + end + + class OracleDBCreateTest < ActiveRecord::TestCase + include OracleSetupper + + def test_db_retrieves_create + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end + assert_match(/not supported/, message) + end + end + + class OracleDBDropTest < ActiveRecord::TestCase + include OracleSetupper + + def test_db_retrieves_drop + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + assert_match(/not supported/, message) + end + end + + class OracleDBCharsetAndCollationTest < ActiveRecord::TestCase + include OracleSetupper + + def test_db_retrieves_collation + assert_raise NoMethodError do + ActiveRecord::Tasks::DatabaseTasks.collation @configuration + end + end + + def test_db_retrieves_charset + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.charset @configuration + end + assert_match(/not supported/, message) + end + end + + class OracleStructureDumpTest < ActiveRecord::TestCase + include OracleSetupper + + def setup + super + @connection.stubs(:structure_dump).returns("select sysdate from dual;") + end + + def test_structure_dump + filename = "oracle.sql" + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + assert File.exists?(filename) + ensure + FileUtils.rm_f(filename) + end + end + + class OracleStructureLoadTest < ActiveRecord::TestCase + include OracleSetupper + + def test_structure_load + filename = "oracle.sql" + + open(filename, 'w') { |f| f.puts("select sysdate from dual;") } + @connection.stubs(:execute).with("select sysdate from dual;\n") + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + ensure + FileUtils.rm_f(filename) + end + end +end diff --git a/activerecord/test/cases/tasks/postgresql_rake_test.rb b/activerecord/test/cases/tasks/postgresql_rake_test.rb index 3006a87589..7e7a469edd 100644 --- a/activerecord/test/cases/tasks/postgresql_rake_test.rb +++ b/activerecord/test/cases/tasks/postgresql_rake_test.rb @@ -225,7 +225,7 @@ module ActiveRecord Kernel.stubs(:system) end - def test_structure_dump + def test_structure_load filename = "awesome-file.sql" Kernel.expects(:system).with("psql -f #{filename} my-app-db") diff --git a/activerecord/test/cases/tasks/sqlserver_rake_test.rb b/activerecord/test/cases/tasks/sqlserver_rake_test.rb new file mode 100644 index 0000000000..0f1264b8ce --- /dev/null +++ b/activerecord/test/cases/tasks/sqlserver_rake_test.rb @@ -0,0 +1,87 @@ +require 'cases/helper' + +module ActiveRecord + module SqlserverSetupper + def setup + @database = 'db.sqlserver' + @connection = stub :connection + @configuration = { + 'adapter' => 'sqlserver', + 'database' => @database, + 'host' => 'localhost', + 'username' => 'username', + 'password' => 'password', + } + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + + @tasks = Class.new(ActiveRecord::Tasks::SqlserverDatabaseTasks) do + def initialize(configuration) + ActiveSupport::Deprecation.silence { super } + end + end + ActiveRecord::Tasks::DatabaseTasks.stubs(:class_for_adapter).returns(@tasks) unless defined? ActiveRecord::ConnectionAdapters::SQLServerAdapter + end + end + + class SqlserverDBCreateTest < ActiveRecord::TestCase + include SqlserverSetupper + + def test_db_retrieves_create + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end + assert_match(/not supported/, message) + end + end + + class SqlserverDBDropTest < ActiveRecord::TestCase + include SqlserverSetupper + + def test_db_retrieves_drop + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end + assert_match(/not supported/, message) + end + end + + class SqlserverDBCharsetAndCollationTest < ActiveRecord::TestCase + include SqlserverSetupper + + def test_db_retrieves_collation + assert_raise NoMethodError do + ActiveRecord::Tasks::DatabaseTasks.collation @configuration + end + end + + def test_db_retrieves_charset + message = capture(:stderr) do + ActiveRecord::Tasks::DatabaseTasks.charset @configuration + end + assert_match(/not supported/, message) + end + end + + class SqlserverStructureDumpTest < ActiveRecord::TestCase + include SqlserverSetupper + + def test_structure_dump + filename = "sqlserver.sql" + Kernel.expects(:system).with("smoscript -s localhost -d #{@database} -u username -p password -f #{filename} -A -U") + + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + end + end + + class SqlserverStructureLoadTest < ActiveRecord::TestCase + include SqlserverSetupper + + def test_structure_load + filename = "sqlserver.sql" + Kernel.expects(:system).with("sqlcmd -S localhost -d #{@database} -U username -P password -i #{filename}") + + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + end + end +end diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb index 777a2b70dd..9d84f64c96 100644 --- a/activerecord/test/cases/timestamp_test.rb +++ b/activerecord/test/cases/timestamp_test.rb @@ -176,6 +176,52 @@ class TimestampTest < ActiveRecord::TestCase assert_not_equal time, owner.updated_at end + def test_changing_parent_of_a_record_touches_both_new_and_old_parent_record + klass = Class.new(ActiveRecord::Base) do + def self.name; 'Toy'; end + belongs_to :pet, touch: true + end + + toy1 = klass.find(1) + old_pet = toy1.pet + + toy2 = klass.find(2) + new_pet = toy2.pet + time = 3.days.ago.at_beginning_of_hour + + old_pet.update_columns(updated_at: time) + new_pet.update_columns(updated_at: time) + + toy1.pet = new_pet + toy1.save! + + old_pet.reload + new_pet.reload + + assert_not_equal time, new_pet.updated_at + assert_not_equal time, old_pet.updated_at + end + + def test_clearing_association_touches_the_old_record + klass = Class.new(ActiveRecord::Base) do + def self.name; 'Toy'; end + belongs_to :pet, touch: true + end + + toy = klass.find(1) + pet = toy.pet + time = 3.days.ago.at_beginning_of_hour + + pet.update_columns(updated_at: time) + + toy.pet = nil + toy.save! + + pet.reload + + assert_not_equal time, pet.updated_at + end + def test_timestamp_attributes_for_create toy = Toy.first assert_equal toy.send(:timestamp_attributes_for_create), [:created_at, :created_on] diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb index 766a5c0c90..9485de88a6 100644 --- a/activerecord/test/cases/transaction_callbacks_test.rb +++ b/activerecord/test/cases/transaction_callbacks_test.rb @@ -281,38 +281,6 @@ class TransactionCallbacksTest < ActiveRecord::TestCase end end - -class SaveFromAfterCommitBlockTest < ActiveRecord::TestCase - self.use_transactional_fixtures = false - - class TopicWithSaveInCallback < ActiveRecord::Base - self.table_name = :topics - after_commit :cache_topic, :on => :create - after_commit :call_update, :on => :update - attr_accessor :cached, :record_updated - - def call_update - self.record_updated = true - end - - def cache_topic - unless cached - self.cached = true - self.save - else - self.cached = false - end - end - end - - def test_after_commit_in_save - topic = TopicWithSaveInCallback.new() - topic.save - assert_equal true, topic.cached - assert_equal true, topic.record_updated - end -end - class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase self.use_transactional_fixtures = false diff --git a/activerecord/test/fixtures/pets.yml b/activerecord/test/fixtures/pets.yml index a1601a53f0..2ec4f53e6d 100644 --- a/activerecord/test/fixtures/pets.yml +++ b/activerecord/test/fixtures/pets.yml @@ -12,3 +12,8 @@ mochi: pet_id: 3 name: mochi owner_id: 2 + +bulbul: + pet_id: 4 + name: bulbul + owner_id: 1 diff --git a/activerecord/test/fixtures/toys.yml b/activerecord/test/fixtures/toys.yml index 037e335e0a..ae9044ec62 100644 --- a/activerecord/test/fixtures/toys.yml +++ b/activerecord/test/fixtures/toys.yml @@ -2,3 +2,13 @@ bone: toy_id: 1 name: Bone pet_id: 1 + +doll: + toy_id: 2 + name: Doll + pet_id: 2 + +bulbuli: + toy_id: 3 + name: Bulbuli + pet_id: 4 diff --git a/activerecord/test/models/owner.rb b/activerecord/test/models/owner.rb index fea55f4535..1c7ed4aa3e 100644 --- a/activerecord/test/models/owner.rb +++ b/activerecord/test/models/owner.rb @@ -1,5 +1,5 @@ class Owner < ActiveRecord::Base self.primary_key = :owner_id - has_many :pets + has_many :pets, -> { order 'pets.name desc' } has_many :toys, :through => :pets end diff --git a/activerecord/test/models/pet.rb b/activerecord/test/models/pet.rb index 3cd5bceed5..f7970d7aab 100644 --- a/activerecord/test/models/pet.rb +++ b/activerecord/test/models/pet.rb @@ -1,5 +1,4 @@ class Pet < ActiveRecord::Base - attr_accessor :current_user self.primary_key = :pet_id @@ -13,5 +12,4 @@ class Pet < ActiveRecord::Base after_destroy do |record| Pet.after_destroy_output = record.current_user end - end diff --git a/activerecord/test/schema/mysql2_specific_schema.rb b/activerecord/test/schema/mysql2_specific_schema.rb index 1b1457ab9c..a9a6514c9d 100644 --- a/activerecord/test/schema/mysql2_specific_schema.rb +++ b/activerecord/test/schema/mysql2_specific_schema.rb @@ -52,7 +52,7 @@ SQL ActiveRecord::Base.connection.execute <<-SQL CREATE TABLE enum_tests ( - enum_column ENUM('true','false') + enum_column ENUM('text','blob','tiny','medium','long') ) SQL end diff --git a/activerecord/test/schema/mysql_specific_schema.rb b/activerecord/test/schema/mysql_specific_schema.rb index ecdce1519b..f2cffca52c 100644 --- a/activerecord/test/schema/mysql_specific_schema.rb +++ b/activerecord/test/schema/mysql_specific_schema.rb @@ -63,7 +63,7 @@ SQL ActiveRecord::Base.connection.execute <<-SQL CREATE TABLE enum_tests ( - enum_column ENUM('true','false') + enum_column ENUM('text','blob','tiny','medium','long') ) SQL diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb index d8271ac8d1..6b7012a172 100644 --- a/activerecord/test/schema/postgresql_specific_schema.rb +++ b/activerecord/test/schema/postgresql_specific_schema.rb @@ -32,6 +32,7 @@ ActiveRecord::Schema.define do char3 text default 'a text field', positive_integer integer default 1, negative_integer integer default -1, + bigint_default bigint default 0::bigint, decimal_number decimal(3,2) default 2.78, multiline_default text DEFAULT '--- [] |