aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb40
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handler_test.rb5
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb42
-rw-r--r--activerecord/test/cases/database_selector_test.rb48
-rw-r--r--activerecord/test/cases/fixtures_test.rb2
-rw-r--r--activerecord/test/cases/query_cache_test.rb38
-rw-r--r--activerecord/test/cases/relation/delegation_test.rb10
-rw-r--r--activerecord/test/cases/relations_test.rb15
-rw-r--r--activerecord/test/cases/scoping/named_scoping_test.rb10
-rw-r--r--activerecord/test/config.example.yml6
-rw-r--r--activerecord/test/models/topic.rb7
-rw-r--r--activerecord/test/support/connection.rb1
12 files changed, 200 insertions, 24 deletions
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 2f090d9862..4c9e4d0ad2 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -1224,12 +1224,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
def test_has_many_without_counter_cache_option
# Ship has a conventionally named `treasures_count` column, but the counter_cache
# option is not given on the association.
- ship = Ship.create(name: "Countless", treasures_count: 10)
+ ship = Ship.create!(name: "Countless", treasures_count: 10)
assert_not_predicate Ship.reflect_on_association(:treasures), :has_cached_counter?
# Count should come from sql count() of treasures rather than treasures_count attribute
- assert_equal ship.treasures.size, 0
+ assert_queries(1) do
+ assert_equal ship.treasures.size, 0
+ assert_predicate ship.treasures, :loaded?
+ end
assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed" do
ship.treasures.create(name: "Gold")
@@ -1350,6 +1353,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
post = posts(:welcome)
assert_no_queries do
assert_not_empty post.comments
+ assert_equal 2, post.comments.size
+ assert_not_predicate post.comments, :loaded?
+ end
+ post = posts(:misc_by_bob)
+ assert_no_queries do
+ assert_empty post.comments
+ assert_predicate post.comments, :loaded?
+ end
+ end
+
+ def test_empty_association_loading_with_counter_cache
+ post = posts(:misc_by_bob)
+ assert_no_queries do
+ assert_empty post.comments.to_a
end
end
@@ -1986,9 +2003,22 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_not_predicate company.clients, :loaded?
end
- def test_counter_cache_on_unloaded_association
- car = Car.create(name: "My AppliCar")
- assert_equal car.engines.size, 0
+ def test_zero_counter_cache_usage_on_unloaded_association
+ car = Car.create!(name: "My AppliCar")
+ assert_no_queries do
+ assert_equal car.engines.size, 0
+ assert_predicate car.engines, :loaded?
+ end
+ end
+
+ def test_counter_cache_on_new_record_unloaded_association
+ car = Car.new(name: "My AppliCar")
+ # Ensure no schema queries inside assertion
+ Engine.primary_key
+ assert_no_queries do
+ assert_equal car.engines.size, 0
+ assert_predicate car.engines, :loaded?
+ end
end
def test_get_ids_ignores_include_option
diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
index 51d0cc3d12..6282759a10 100644
--- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
@@ -382,6 +382,11 @@ module ActiveRecord
assert_not_nil ActiveRecord::Base.connection
assert_same klass2.connection, ActiveRecord::Base.connection
end
+
+ def test_default_handlers_are_writing_and_reading
+ assert_equal :writing, ActiveRecord::Base.writing_role
+ assert_equal :reading, ActiveRecord::Base.reading_role
+ end
end
end
end
diff --git a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
index 8988755d24..36591097b6 100644
--- a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
@@ -126,6 +126,30 @@ module ActiveRecord
ENV["RAILS_ENV"] = previous_env
end
+ def test_establish_connection_using_3_levels_config_with_non_default_handlers
+ previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "default_env"
+
+ config = {
+ "default_env" => {
+ "readonly" => { "adapter" => "sqlite3", "database" => "db/readonly.sqlite3" },
+ "primary" => { "adapter" => "sqlite3", "database" => "db/primary.sqlite3" }
+ }
+ }
+ @prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
+
+ ActiveRecord::Base.connects_to(database: { default: :primary, readonly: :readonly })
+
+ assert_not_nil pool = ActiveRecord::Base.connection_handlers[:default].retrieve_connection_pool("primary")
+ assert_equal "db/primary.sqlite3", pool.spec.config[:database]
+
+ assert_not_nil pool = ActiveRecord::Base.connection_handlers[:readonly].retrieve_connection_pool("primary")
+ assert_equal "db/readonly.sqlite3", pool.spec.config[:database]
+ ensure
+ ActiveRecord::Base.configurations = @prev_configs
+ ActiveRecord::Base.establish_connection(:arunit)
+ ENV["RAILS_ENV"] = previous_env
+ end
+
def test_switching_connections_with_database_url
previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "default_env"
previous_url, ENV["DATABASE_URL"] = ENV["DATABASE_URL"], "postgres://localhost/foo"
@@ -344,6 +368,24 @@ module ActiveRecord
assert_equal "No connection pool with 'primary' found for the 'reading' role.", error.message
end
+
+ def test_default_handlers_are_writing_and_reading
+ assert_equal :writing, ActiveRecord::Base.writing_role
+ assert_equal :reading, ActiveRecord::Base.reading_role
+ end
+
+ def test_an_application_can_change_the_default_handlers
+ old_writing = ActiveRecord::Base.writing_role
+ old_reading = ActiveRecord::Base.reading_role
+ ActiveRecord::Base.writing_role = :default
+ ActiveRecord::Base.reading_role = :readonly
+
+ assert_equal :default, ActiveRecord::Base.writing_role
+ assert_equal :readonly, ActiveRecord::Base.reading_role
+ ensure
+ ActiveRecord::Base.writing_role = old_writing
+ ActiveRecord::Base.reading_role = old_reading
+ end
end
end
end
diff --git a/activerecord/test/cases/database_selector_test.rb b/activerecord/test/cases/database_selector_test.rb
index 6142e223ce..4106a6ec46 100644
--- a/activerecord/test/cases/database_selector_test.rb
+++ b/activerecord/test/cases/database_selector_test.rb
@@ -95,6 +95,54 @@ module ActiveRecord
assert @session_store[:last_write]
end
+ def test_read_from_primary_with_options
+ resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session, delay: 5.seconds)
+
+ # Session should start empty
+ assert_nil @session_store[:last_write]
+
+ called = false
+ resolver.write do
+ assert ActiveRecord::Base.connected_to?(role: :writing)
+ called = true
+ end
+ assert called
+
+ # and be populated by the last write time
+ assert @session_store[:last_write]
+
+ read = false
+ resolver.read do
+ assert ActiveRecord::Base.connected_to?(role: :writing)
+ read = true
+ end
+ assert read
+ end
+
+ def test_read_from_replica_with_no_delay
+ resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session, delay: 0.seconds)
+
+ # Session should start empty
+ assert_nil @session_store[:last_write]
+
+ called = false
+ resolver.write do
+ assert ActiveRecord::Base.connected_to?(role: :writing)
+ called = true
+ end
+ assert called
+
+ # and be populated by the last write time
+ assert @session_store[:last_write]
+
+ read = false
+ resolver.read do
+ assert ActiveRecord::Base.connected_to?(role: :reading)
+ read = true
+ end
+ assert read
+ end
+
def test_the_middleware_chooses_writing_role_with_POST_request
middleware = ActiveRecord::Middleware::DatabaseSelector.new(lambda { |env|
assert ActiveRecord::Base.connected_to?(role: :writing)
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index 2fe4879fe6..b4f28fbfd6 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -924,7 +924,7 @@ class TransactionalFixturesOnConnectionNotification < ActiveRecord::TestCase
def lock_thread=(lock_thread); end
end.new
- assert_called_with(connection, :begin_transaction, [joinable: false]) do
+ assert_called_with(connection, :begin_transaction, [joinable: false, _lazy: false]) do
fire_connection_notification(connection)
end
end
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 04bbc7d136..eb32b690aa 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -502,6 +502,44 @@ class QueryCacheTest < ActiveRecord::TestCase
}.call({})
end
+ def test_clear_query_cache_is_called_on_all_connections
+ skip "with in memory db, reading role won't be able to see database on writing role" if in_memory_db?
+ with_temporary_connection_pool do
+ ActiveRecord::Base.connection_handlers = {
+ writing: ActiveRecord::Base.default_connection_handler,
+ reading: ActiveRecord::ConnectionAdapters::ConnectionHandler.new
+ }
+
+ ActiveRecord::Base.connected_to(role: :reading) do
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["arunit"])
+ end
+
+ mw = middleware { |env|
+ ActiveRecord::Base.connected_to(role: :reading) do
+ @topic = Topic.first
+ end
+
+ assert @topic
+
+ ActiveRecord::Base.connected_to(role: :writing) do
+ @topic.title = "It doesn't have to be crazy at work"
+ @topic.save!
+ end
+
+ assert_equal "It doesn't have to be crazy at work", @topic.title
+
+ ActiveRecord::Base.connected_to(role: :reading) do
+ @topic = Topic.first
+ assert_equal "It doesn't have to be crazy at work", @topic.title
+ end
+ }
+
+ mw.call({})
+ end
+ ensure
+ ActiveRecord::Base.connection_handlers = { writing: ActiveRecord::Base.default_connection_handler }
+ end
+
private
def with_temporary_connection_pool
diff --git a/activerecord/test/cases/relation/delegation_test.rb b/activerecord/test/cases/relation/delegation_test.rb
index b600c999a6..63ae438de3 100644
--- a/activerecord/test/cases/relation/delegation_test.rb
+++ b/activerecord/test/cases/relation/delegation_test.rb
@@ -5,7 +5,7 @@ require "models/post"
require "models/comment"
module ActiveRecord
- module ArrayDelegationTests
+ module DelegationTests
ARRAY_DELEGATES = [
:+, :-, :|, :&, :[], :shuffle,
:all?, :collect, :compact, :detect, :each, :each_cons, :each_with_index,
@@ -21,10 +21,14 @@ module ActiveRecord
assert_respond_to target, method
end
end
+
+ def test_not_respond_to_arel_method
+ assert_not_respond_to target, :exists
+ end
end
class DelegationAssociationTest < ActiveRecord::TestCase
- include ArrayDelegationTests
+ include DelegationTests
def target
Post.new.comments
@@ -32,7 +36,7 @@ module ActiveRecord
end
class DelegationRelationTest < ActiveRecord::TestCase
- include ArrayDelegationTests
+ include DelegationTests
def target
Comment.all
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index 756eeca35f..6b5b877260 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -480,21 +480,6 @@ class RelationTest < ActiveRecord::TestCase
assert_nothing_raised { Topic.reorder([]) }
end
- def test_respond_to_delegates_to_arel
- relation = Topic.all
- fake_arel = Struct.new(:responds) {
- def respond_to?(method, access = false)
- responds << [method, access]
- end
- }.new []
-
- relation.extend(Module.new { attr_accessor :arel })
- relation.arel = fake_arel
-
- relation.respond_to?(:matching_attributes)
- assert_equal [:matching_attributes, false], fake_arel.responds.first
- end
-
def test_respond_to_dynamic_finders
relation = Topic.all
diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb
index 418a2ae04e..27f9df295f 100644
--- a/activerecord/test/cases/scoping/named_scoping_test.rb
+++ b/activerecord/test/cases/scoping/named_scoping_test.rb
@@ -447,6 +447,16 @@ class NamedScopingTest < ActiveRecord::TestCase
assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).to_a.uniq
end
+ def test_chaining_doesnt_leak_conditions_to_another_scopes
+ expected = Topic.where(approved: false).where(id: Topic.children.select(:parent_id))
+ assert_equal expected.to_a, Topic.rejected.has_children.to_a
+ end
+
+ def test_nested_scoping
+ expected = Reply.approved
+ assert_equal expected.to_a, Topic.rejected.nested_scoping(expected)
+ end
+
def test_scopes_batch_finders
assert_equal 4, Topic.approved.count
diff --git a/activerecord/test/config.example.yml b/activerecord/test/config.example.yml
index 33962f9e5e..f5e3ac3c19 100644
--- a/activerecord/test/config.example.yml
+++ b/activerecord/test/config.example.yml
@@ -54,10 +54,16 @@ connections:
username: rails
encoding: utf8mb4
collation: utf8mb4_unicode_ci
+<% if ENV['MYSQL_HOST'] %>
+ host: <%= ENV['MYSQL_HOST'] %>
+<% end %>
arunit2:
username: rails
encoding: utf8mb4
collation: utf8mb4_general_ci
+<% if ENV['MYSQL_HOST'] %>
+ host: <%= ENV['MYSQL_HOST'] %>
+<% end %>
oracle:
arunit:
diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb
index a6a47687a2..fdb461ed7f 100644
--- a/activerecord/test/models/topic.rb
+++ b/activerecord/test/models/topic.rb
@@ -10,6 +10,9 @@ class Topic < ActiveRecord::Base
scope :approved, -> { where(approved: true) }
scope :rejected, -> { where(approved: false) }
+ scope :children, -> { where.not(parent_id: nil) }
+ scope :has_children, -> { where(id: Topic.children.select(:parent_id)) }
+
scope :scope_with_lambda, lambda { all }
scope :by_lifo, -> { where(author_name: "lifo") }
@@ -88,6 +91,10 @@ class Topic < ActiveRecord::Base
write_attribute(:approved, val)
end
+ def self.nested_scoping(scope)
+ scope.base
+ end
+
private
def default_written_on
diff --git a/activerecord/test/support/connection.rb b/activerecord/test/support/connection.rb
index 2a4fa53460..367309dd85 100644
--- a/activerecord/test/support/connection.rb
+++ b/activerecord/test/support/connection.rb
@@ -21,6 +21,7 @@ module ARTest
def self.connect
puts "Using #{connection_name}"
ActiveRecord::Base.logger = ActiveSupport::Logger.new("debug.log", 0, 100 * 1024 * 1024)
+ ActiveRecord::Base.connection_handlers = { ActiveRecord::Base.writing_role => ActiveRecord::Base.default_connection_handler }
ActiveRecord::Base.configurations = connection_config
ActiveRecord::Base.establish_connection :arunit
ARUnit2Model.establish_connection :arunit2