diff options
Diffstat (limited to 'activerecord/test')
13 files changed, 144 insertions, 99 deletions
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index 070fca240f..601d575c0e 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -216,6 +216,15 @@ module ActiveRecord assert result.is_a?(ActiveRecord::Result) end + if ActiveRecord::Base.connection.prepared_statements + def test_select_all_with_legacy_binds + post = Post.create!(title: "foo", body: "bar") + expected = @connection.select_all("SELECT * FROM posts WHERE id = #{post.id}") + result = @connection.select_all("SELECT * FROM posts WHERE id = #{Arel::Nodes::BindParam.new.to_sql}", nil, [[nil, post.id]]) + assert_equal expected.to_hash, result.to_hash + end + end + def test_select_methods_passing_a_association_relation author = Author.create!(name: "john") Post.create!(author: author, title: "foo", body: "bar") diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb index fdd7b0157a..2179d1294c 100644 --- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb @@ -260,8 +260,7 @@ module ActiveRecord def test_tables_logs_name sql = <<-SQL - SELECT name FROM sqlite_master - WHERE type = 'table' AND name <> 'sqlite_sequence' + SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence' AND type IN ('table') SQL assert_logged [[sql.squish, "SCHEMA", []]] do @conn.tables @@ -279,8 +278,7 @@ module ActiveRecord def test_table_exists_logs_name with_example_table do sql = <<-SQL - SELECT name FROM sqlite_master - WHERE type = 'table' AND name <> 'sqlite_sequence' AND name = 'ex' + SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence' AND name = 'ex' AND type IN ('table') SQL assert_logged [[sql.squish, "SCHEMA", []]] do assert @conn.table_exists?("ex") diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 5875a1871f..5b08ba1358 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -116,6 +116,26 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase ActiveRecord::Base.belongs_to_required_by_default = original_value end + def test_default + david = developers(:david) + jamis = developers(:jamis) + + model = Class.new(ActiveRecord::Base) do + self.table_name = "ships" + def self.name; "Temp"; end + belongs_to :developer, default: -> { david } + end + + ship = model.create! + assert_equal david, ship.developer + + ship = model.create!(developer: jamis) + assert_equal jamis, ship.developer + + ship.update!(developer: nil) + assert_equal david, ship.developer + end + def test_default_scope_on_relations_is_not_cached counter = 0 diff --git a/activerecord/test/cases/associations/extension_test.rb b/activerecord/test/cases/associations/extension_test.rb index 974a3080d4..87d842f21d 100644 --- a/activerecord/test/cases/associations/extension_test.rb +++ b/activerecord/test/cases/associations/extension_test.rb @@ -36,6 +36,11 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase assert_equal comments(:greetings), posts(:welcome).comments.not_again.find_most_recent end + def test_extension_with_dirty_target + comment = posts(:welcome).comments.build(body: "New comment") + assert_equal comment, posts(:welcome).comments.with_content("New comment") + end + def test_marshalling_extensions david = developers(:david) assert_equal projects(:action_controller), david.projects.find_most_recent diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 14f515fa1c..173063e068 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -1903,7 +1903,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_calling_many_on_loaded_association_should_not_use_query firm = companies(:first_firm) - firm.clients.collect # force load + firm.clients.load # force load assert_no_queries { assert firm.clients.many? } end @@ -1942,7 +1942,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_calling_none_on_loaded_association_should_not_use_query firm = companies(:first_firm) - firm.clients.collect # force load + firm.clients.load # force load assert_no_queries { assert ! firm.clients.none? } end @@ -1977,7 +1977,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_calling_one_on_loaded_association_should_not_use_query firm = companies(:first_firm) - firm.clients.collect # force load + firm.clients.load # force load assert_no_queries { assert ! firm.clients.one? } end diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index c13a962e3e..f9eccfbda1 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -349,13 +349,14 @@ class DirtyTest < ActiveRecord::TestCase def test_partial_update_with_optimistic_locking person = Person.new(first_name: "foo") - old_lock_version = person.lock_version with_partial_writes Person, false do assert_queries(2) { 2.times { person.save! } } Person.where(id: person.id).update_all(first_name: "baz") end + old_lock_version = person.lock_version + with_partial_writes Person, true do assert_queries(0) { 2.times { person.save! } } assert_equal old_lock_version, person.reload.lock_version diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index 23095618a4..3a3b8e51f9 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -247,17 +247,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal "new title2", t2.title end - def test_lock_without_default_should_update_with_lock_col - t1 = LockWithoutDefault.create(title: "title1", lock_version: 6) - - assert_equal 6, t1.lock_version - - t1.update(lock_version: 0) - t1.reload - - assert_equal 0, t1.lock_version - end - def test_lock_without_default_queries_count t1 = LockWithoutDefault.create(title: "title1") @@ -270,12 +259,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal "title2", t1.title assert_equal 1, t1.lock_version - assert_queries(1) { t1.update(title: "title3", lock_version: 6) } - - t1.reload - assert_equal "title3", t1.title - assert_equal 6, t1.lock_version - t2 = LockWithoutDefault.new(title: "title1") assert_queries(1) { t2.save! } @@ -321,17 +304,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal "new title2", t2.title end - def test_lock_with_custom_column_without_default_should_update_with_lock_col - t1 = LockWithCustomColumnWithoutDefault.create(title: "title1", custom_lock_version: 6) - - assert_equal 6, t1.custom_lock_version - - t1.update(custom_lock_version: 0) - t1.reload - - assert_equal 0, t1.custom_lock_version - end - def test_lock_with_custom_column_without_default_queries_count t1 = LockWithCustomColumnWithoutDefault.create(title: "title1") @@ -344,12 +316,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal "title2", t1.title assert_equal 1, t1.custom_lock_version - assert_queries(1) { t1.update(title: "title3", custom_lock_version: 6) } - - t1.reload - assert_equal "title3", t1.title - assert_equal 6, t1.custom_lock_version - t2 = LockWithCustomColumnWithoutDefault.new(title: "title1") assert_queries(1) { t2.save! } diff --git a/activerecord/test/cases/relation/delegation_test.rb b/activerecord/test/cases/relation/delegation_test.rb index 49d4aeafc9..8cb7b82015 100644 --- a/activerecord/test/cases/relation/delegation_test.rb +++ b/activerecord/test/cases/relation/delegation_test.rb @@ -33,7 +33,7 @@ module ActiveRecord :map, :none?, :one?, :partition, :reject, :reverse, :sample, :second, :sort, :sort_by, :third, :to_ary, :to_set, :to_xml, :to_yaml, :join, - :in_groups, :in_groups_of, :to_sentence, :to_formatted_s + :in_groups, :in_groups_of, :to_sentence, :to_formatted_s, :as_json ] ARRAY_DELEGATES.each do |method| diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 0c94e891eb..e17cb1795e 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -112,7 +112,7 @@ class RelationTest < ActiveRecord::TestCase def test_loaded_first topics = Topic.all.order("id ASC") - topics.to_a # force load + topics.load # force load assert_no_queries do assert_equal "The First Topic", topics.first.title @@ -123,7 +123,7 @@ class RelationTest < ActiveRecord::TestCase def test_loaded_first_with_limit topics = Topic.all.order("id ASC") - topics.to_a # force load + topics.load # force load assert_no_queries do assert_equal ["The First Topic", @@ -136,7 +136,7 @@ class RelationTest < ActiveRecord::TestCase def test_first_get_more_than_available topics = Topic.all.order("id ASC") unloaded_first = topics.first(10) - topics.to_a # force load + topics.load # force load assert_no_queries do loaded_first = topics.first(10) @@ -218,17 +218,34 @@ class RelationTest < ActiveRecord::TestCase assert_equal topics(:fifth).title, topics.first.title end - def test_finding_with_reverted_assoc_order + def test_finding_with_arel_assoc_order + topics = Topic.order(Arel.sql("id") => :desc) + assert_equal 5, topics.to_a.size + assert_equal topics(:fifth).title, topics.first.title + end + + def test_finding_with_reversed_assoc_order topics = Topic.order(id: :asc).reverse_order assert_equal 5, topics.to_a.size assert_equal topics(:fifth).title, topics.first.title end + def test_finding_with_reversed_arel_assoc_order + topics = Topic.order(Arel.sql("id") => :asc).reverse_order + assert_equal 5, topics.to_a.size + assert_equal topics(:fifth).title, topics.first.title + end + def test_reverse_order_with_function topics = Topic.order("length(title)").reverse_order assert_equal topics(:second).title, topics.first.title end + def test_reverse_arel_assoc_order_with_function + topics = Topic.order(Arel.sql("length(title)") => :asc).reverse_order + assert_equal topics(:second).title, topics.first.title + end + def test_reverse_order_with_function_other_predicates topics = Topic.order("author_name, length(title), id").reverse_order assert_equal topics(:second).title, topics.first.title @@ -251,6 +268,12 @@ class RelationTest < ActiveRecord::TestCase end end + def test_reverse_arel_assoc_order_with_multiargument_function + assert_nothing_raised do + Topic.order(Arel.sql("REPLACE(title, '', '')") => :asc).reverse_order + end + end + def test_reverse_order_with_nulls_first_or_last assert_raises(ActiveRecord::IrreversibleOrderError) do Topic.order("title NULLS FIRST").reverse_order @@ -1132,7 +1155,7 @@ class RelationTest < ActiveRecord::TestCase assert ! posts.loaded? best_posts = posts.where(comments_count: 0) - best_posts.to_a # force load + best_posts.load # force load assert_no_queries { assert_equal 9, best_posts.size } end @@ -1143,7 +1166,7 @@ class RelationTest < ActiveRecord::TestCase assert ! posts.loaded? best_posts = posts.where(comments_count: 0) - best_posts.to_a # force load + best_posts.load # force load assert_no_queries { assert_equal 9, best_posts.size } end @@ -1153,7 +1176,7 @@ class RelationTest < ActiveRecord::TestCase assert_no_queries { assert_equal 0, posts.size } assert ! posts.loaded? - posts.to_a # force load + posts.load # force load assert_no_queries { assert_equal 0, posts.size } end @@ -1182,7 +1205,7 @@ class RelationTest < ActiveRecord::TestCase assert ! no_posts.loaded? best_posts = posts.where(comments_count: 0) - best_posts.to_a # force load + best_posts.load # force load assert_no_queries { assert_equal false, best_posts.empty? } end @@ -1947,6 +1970,14 @@ class RelationTest < ActiveRecord::TestCase assert_equal p2.first.comments, comments end + def test_unscope_specific_where_value + posts = Post.where(title: "Welcome to the weblog", body: "Such a lovely day") + + assert_equal 1, posts.count + assert_equal 1, posts.unscope(where: :title).count + assert_equal 1, posts.unscope(where: :body).count + end + def test_unscope_removes_binds left = Post.where(id: Arel::Nodes::BindParam.new) column = Post.columns_hash["id"] diff --git a/activerecord/test/cases/scoping/default_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb index 14fb2fbbfa..a6c22ac672 100644 --- a/activerecord/test/cases/scoping/default_scoping_test.rb +++ b/activerecord/test/cases/scoping/default_scoping_test.rb @@ -10,8 +10,6 @@ require "concurrent/atomic/cyclic_barrier" class DefaultScopingTest < ActiveRecord::TestCase fixtures :developers, :posts, :comments - self.use_transactional_tests = false - def test_default_scope expected = Developer.all.merge!(order: "salary DESC").to_a.collect(&:salary) received = DeveloperOrderedBySalary.all.collect(&:salary) @@ -61,17 +59,6 @@ class DefaultScopingTest < ActiveRecord::TestCase assert_equal "Jamis", DeveloperCalledJamis.create!.name end - unless in_memory_db? - def test_default_scoping_with_threads - 2.times do - Thread.new { - assert_includes DeveloperOrderedBySalary.all.to_sql, "salary DESC" - DeveloperOrderedBySalary.connection.close - }.join - end - end - end - def test_default_scope_with_inheritance wheres = InheritedPoorDeveloperCalledJamis.all.where_values_hash assert_equal "Jamis", wheres["name"] @@ -435,29 +422,6 @@ class DefaultScopingTest < ActiveRecord::TestCase assert_equal comment, CommentWithDefaultScopeReferencesAssociation.find_by(id: comment.id) end - unless in_memory_db? - def test_default_scope_is_threadsafe - threads = [] - assert_not_equal 1, ThreadsafeDeveloper.unscoped.count - - barrier_1 = Concurrent::CyclicBarrier.new(2) - barrier_2 = Concurrent::CyclicBarrier.new(2) - - threads << Thread.new do - Thread.current[:default_scope_delay] = -> { barrier_1.wait; barrier_2.wait } - assert_equal 1, ThreadsafeDeveloper.all.to_a.count - ThreadsafeDeveloper.connection.close - end - threads << Thread.new do - Thread.current[:default_scope_delay] = -> { barrier_2.wait } - barrier_1.wait - assert_equal 1, ThreadsafeDeveloper.all.to_a.count - ThreadsafeDeveloper.connection.close - end - threads.each(&:join) - end - end - test "additional conditions are ANDed with the default scope" do scope = DeveloperCalledJamis.where(name: "David") assert_equal 2, scope.where_clause.ast.children.length @@ -506,3 +470,37 @@ class DefaultScopingTest < ActiveRecord::TestCase assert_match gender_pattern, Lion.female.to_sql end end + +class DefaultScopingWithThreadTest < ActiveRecord::TestCase + self.use_transactional_tests = false + + def test_default_scoping_with_threads + 2.times do + Thread.new { + assert_includes DeveloperOrderedBySalary.all.to_sql, "salary DESC" + DeveloperOrderedBySalary.connection.close + }.join + end + end + + def test_default_scope_is_threadsafe + threads = [] + assert_not_equal 1, ThreadsafeDeveloper.unscoped.count + + barrier_1 = Concurrent::CyclicBarrier.new(2) + barrier_2 = Concurrent::CyclicBarrier.new(2) + + threads << Thread.new do + Thread.current[:default_scope_delay] = -> { barrier_1.wait; barrier_2.wait } + assert_equal 1, ThreadsafeDeveloper.all.to_a.count + ThreadsafeDeveloper.connection.close + end + threads << Thread.new do + Thread.current[:default_scope_delay] = -> { barrier_2.wait } + barrier_1.wait + assert_equal 1, ThreadsafeDeveloper.all.to_a.count + ThreadsafeDeveloper.connection.close + end + threads.each(&:join) + end +end unless in_memory_db? diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb index d261fd5321..0c2cffe0d3 100644 --- a/activerecord/test/cases/scoping/named_scoping_test.rb +++ b/activerecord/test/cases/scoping/named_scoping_test.rb @@ -23,8 +23,8 @@ class NamedScopingTest < ActiveRecord::TestCase all_posts = Topic.base assert_queries(1) do - all_posts.collect - all_posts.collect + all_posts.collect { true } + all_posts.collect { true } end end @@ -167,7 +167,7 @@ class NamedScopingTest < ActiveRecord::TestCase def test_first_and_last_should_not_use_query_when_results_are_loaded topics = Topic.base - topics.reload # force load + topics.load # force load assert_no_queries do topics.first topics.last @@ -178,7 +178,7 @@ class NamedScopingTest < ActiveRecord::TestCase topics = Topic.base assert_queries(2) do topics.empty? # use count query - topics.collect # force load + topics.load # force load topics.empty? # use loaded (no query) end end @@ -187,7 +187,7 @@ class NamedScopingTest < ActiveRecord::TestCase topics = Topic.base assert_queries(2) do topics.any? # use count query - topics.collect # force load + topics.load # force load topics.any? # use loaded (no query) end end @@ -203,7 +203,7 @@ class NamedScopingTest < ActiveRecord::TestCase def test_any_should_not_fire_query_if_scope_loaded topics = Topic.base - topics.collect # force load + topics.load # force load assert_no_queries { assert topics.any? } end @@ -217,7 +217,7 @@ class NamedScopingTest < ActiveRecord::TestCase topics = Topic.base assert_queries(2) do topics.many? # use count query - topics.collect # force load + topics.load # force load topics.many? # use loaded (no query) end end @@ -233,7 +233,7 @@ class NamedScopingTest < ActiveRecord::TestCase def test_many_should_not_fire_query_if_scope_loaded topics = Topic.base - topics.collect # force load + topics.load # force load assert_no_queries { assert topics.many? } end @@ -384,7 +384,7 @@ class NamedScopingTest < ActiveRecord::TestCase def test_size_should_use_length_when_results_are_loaded topics = Topic.base - topics.reload # force load + topics.load # force load assert_no_queries do topics.size # use loaded (no query) end diff --git a/activerecord/test/cases/tasks/postgresql_rake_test.rb b/activerecord/test/cases/tasks/postgresql_rake_test.rb index a23100c32a..512388af6b 100644 --- a/activerecord/test/cases/tasks/postgresql_rake_test.rb +++ b/activerecord/test/cases/tasks/postgresql_rake_test.rb @@ -217,17 +217,21 @@ if current_adapter?(:PostgreSQLAdapter) class PostgreSQLStructureDumpTest < ActiveRecord::TestCase def setup - @connection = stub(structure_dump: true) + @connection = stub(schema_search_path: nil, structure_dump: true) @configuration = { "adapter" => "postgresql", "database" => "my-app-db" } - @filename = "awesome-file.sql" + @filename = "/tmp/awesome-file.sql" + FileUtils.touch(@filename) ActiveRecord::Base.stubs(:connection).returns(@connection) ActiveRecord::Base.stubs(:establish_connection).returns(true) Kernel.stubs(:system) - File.stubs(:open) + end + + def teardown + FileUtils.rm_f(@filename) end def test_structure_dump @@ -236,6 +240,15 @@ if current_adapter?(:PostgreSQLAdapter) ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) end + def test_structure_dump_header_comments_removed + Kernel.stubs(:system).returns(true) + File.write(@filename, "-- header comment\n\n-- more header comment\n statement \n-- lower comment\n") + + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + + assert_equal [" statement \n", "-- lower comment\n"], File.readlines(@filename).first(2) + end + def test_structure_dump_with_extra_flags expected_command = ["pg_dump", "-s", "-x", "-O", "-f", @filename, "--noop", "my-app-db"] diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index e74aedb814..a2028b3eb9 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -59,6 +59,10 @@ class Post < ActiveRecord::Base def the_association proxy_association end + + def with_content(content) + self.detect { |comment| comment.body == content } + end end has_many :comments_with_extend, extend: NamedExtension, class_name: "Comment", foreign_key: "post_id" do |