aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r--activerecord/test/cases/adapter_test.rb7
-rw-r--r--activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb26
-rw-r--r--activerecord/test/cases/adapters/postgresql/transaction_test.rb65
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb34
-rw-r--r--activerecord/test/cases/integration_test.rb6
-rw-r--r--activerecord/test/cases/migration/column_attributes_test.rb6
-rw-r--r--activerecord/test/cases/query_cache_test.rb38
-rw-r--r--activerecord/test/cases/relations_test.rb2
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb21
-rw-r--r--activerecord/test/cases/serialized_attribute_test.rb4
-rw-r--r--activerecord/test/cases/test_case.rb7
-rw-r--r--activerecord/test/cases/type/date_time_test.rb2
-rw-r--r--activerecord/test/cases/view_test.rb24
13 files changed, 179 insertions, 63 deletions
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 8fa0645b0f..cfbc8ab942 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -42,8 +42,10 @@ module ActiveRecord
def test_table_exists?
ActiveSupport::Deprecation.silence do
assert @connection.table_exists?("accounts")
- assert !@connection.table_exists?("nonexistingtable")
- assert !@connection.table_exists?(nil)
+ assert @connection.table_exists?(:accounts)
+ assert_not @connection.table_exists?("nonexistingtable")
+ assert_not @connection.table_exists?("'")
+ assert_not @connection.table_exists?(nil)
end
end
@@ -63,6 +65,7 @@ module ActiveRecord
assert @connection.data_source_exists?("accounts")
assert @connection.data_source_exists?(:accounts)
assert_not @connection.data_source_exists?("nonexistingtable")
+ assert_not @connection.data_source_exists?("'")
assert_not @connection.data_source_exists?(nil)
end
diff --git a/activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb b/activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb
new file mode 100644
index 0000000000..03b44feab6
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb
@@ -0,0 +1,26 @@
+require "cases/helper"
+
+class PostgresqlCaseInsensitiveTest < ActiveRecord::PostgreSQLTestCase
+ class Default < ActiveRecord::Base; end
+
+ def test_case_insensitiveness
+ connection = ActiveRecord::Base.connection
+ table = Default.arel_table
+
+ column = Default.columns_hash["char1"]
+ comparison = connection.case_insensitive_comparison table, :char1, column, nil
+ assert_match(/lower/i, comparison.to_sql)
+
+ column = Default.columns_hash["char2"]
+ comparison = connection.case_insensitive_comparison table, :char2, column, nil
+ assert_match(/lower/i, comparison.to_sql)
+
+ column = Default.columns_hash["char3"]
+ comparison = connection.case_insensitive_comparison table, :char3, column, nil
+ assert_match(/lower/i, comparison.to_sql)
+
+ column = Default.columns_hash["multiline_default"]
+ comparison = connection.case_insensitive_comparison table, :multiline_default, column, nil
+ assert_match(/lower/i, comparison.to_sql)
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/transaction_test.rb b/activerecord/test/cases/adapters/postgresql/transaction_test.rb
index d992e22305..c450524de8 100644
--- a/activerecord/test/cases/adapters/postgresql/transaction_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/transaction_test.rb
@@ -1,5 +1,6 @@
require "cases/helper"
require "support/connection_helper"
+require "concurrent/atomic/cyclic_barrier"
module ActiveRecord
class PostgresqlTransactionTest < ActiveRecord::PostgreSQLTestCase
@@ -27,32 +28,29 @@ module ActiveRecord
end
test "raises SerializationFailure when a serialization failure occurs" do
- with_warning_suppression do
- assert_raises(ActiveRecord::SerializationFailure) do
- thread = Thread.new do
- Sample.transaction isolation: :serializable do
- Sample.delete_all
+ assert_raises(ActiveRecord::SerializationFailure) do
+ before = Concurrent::CyclicBarrier.new(2)
+ after = Concurrent::CyclicBarrier.new(2)
- 10.times do |i|
- sleep 0.1
-
- Sample.create value: i
- end
+ thread = Thread.new do
+ with_warning_suppression do
+ Sample.transaction isolation: :serializable do
+ before.wait
+ Sample.create value: Sample.sum(:value)
+ after.wait
end
end
+ end
- sleep 0.1
-
- Sample.transaction isolation: :serializable do
- Sample.delete_all
-
- 10.times do |i|
- sleep 0.1
-
- Sample.create value: i
+ begin
+ with_warning_suppression do
+ Sample.transaction isolation: :serializable do
+ before.wait
+ Sample.create value: Sample.sum(:value)
+ after.wait
end
end
-
+ ensure
thread.join
end
end
@@ -61,26 +59,28 @@ module ActiveRecord
test "raises Deadlocked when a deadlock is encountered" do
with_warning_suppression do
assert_raises(ActiveRecord::Deadlocked) do
+ barrier = Concurrent::CyclicBarrier.new(2)
+
s1 = Sample.create value: 1
s2 = Sample.create value: 2
thread = Thread.new do
Sample.transaction do
s1.lock!
- sleep 1
+ barrier.wait
s2.update_attributes value: 1
end
end
- sleep 0.5
-
- Sample.transaction do
- s2.lock!
- sleep 1
- s1.update_attributes value: 2
+ begin
+ Sample.transaction do
+ s2.lock!
+ barrier.wait
+ s1.update_attributes value: 2
+ end
+ ensure
+ thread.join
end
-
- thread.join
end
end
end
@@ -88,10 +88,11 @@ module ActiveRecord
protected
def with_warning_suppression
- log_level = @connection.client_min_messages
- @connection.client_min_messages = "error"
+ log_level = ActiveRecord::Base.connection.client_min_messages
+ ActiveRecord::Base.connection.client_min_messages = "error"
yield
- @connection.client_min_messages = log_level
+ ensure
+ ActiveRecord::Base.connection.client_min_messages = log_level
end
end
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index fed59c2ab3..0ce67f971b 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -2461,9 +2461,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
end
test "double insertion of new object to association when same association used in the after create callback of a new object" do
- car = Car.create!
- car.bulbs << TrickyBulb.new
- assert_equal 1, car.bulbs.size
+ reset_callbacks(:save, Bulb) do
+ Bulb.after_save { |record| record.car.bulbs.to_a }
+ car = Car.create!
+ car.bulbs << Bulb.new
+ assert_equal 1, car.bulbs.size
+ end
end
def test_association_force_reload_with_only_true_is_deprecated
@@ -2510,9 +2513,34 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert_no_queries { car.bulb_ids }
end
+ def test_loading_association_in_validate_callback_doesnt_affect_persistence
+ reset_callbacks(:validation, Bulb) do
+ Bulb.after_validation { |m| m.car.bulbs.load }
+
+ car = Car.create!(name: "Car")
+ bulb = car.bulbs.create!
+
+ assert_equal [bulb], car.bulbs
+ end
+ end
+
private
def force_signal37_to_load_all_clients_of_firm
companies(:first_firm).clients_of_firm.load_target
end
+
+ def reset_callbacks(kind, klass)
+ old_callbacks = {}
+ old_callbacks[klass] = klass.send("_#{kind}_callbacks").dup
+ klass.subclasses.each do |subclass|
+ old_callbacks[subclass] = subclass.send("_#{kind}_callbacks").dup
+ end
+ yield
+ ensure
+ klass.send("_#{kind}_callbacks=", old_callbacks[klass])
+ klass.subclasses.each do |subclass|
+ subclass.send("_#{kind}_callbacks=", old_callbacks[subclass])
+ end
+ end
end
diff --git a/activerecord/test/cases/integration_test.rb b/activerecord/test/cases/integration_test.rb
index 766917b196..00457965d7 100644
--- a/activerecord/test/cases/integration_test.rb
+++ b/activerecord/test/cases/integration_test.rb
@@ -172,4 +172,10 @@ class IntegrationTest < ActiveRecord::TestCase
owner = owners(:blackbeard)
assert_equal "owners/#{owner.id}-#{owner.happy_at.utc.to_s(:usec)}", owner.cache_key(:updated_at, :happy_at)
end
+
+ def test_cache_key_when_named_timestamp_is_nil
+ owner = owners(:blackbeard)
+ owner.happy_at = nil
+ assert_equal "owners/#{owner.id}", owner.cache_key(:happy_at)
+ end
end
diff --git a/activerecord/test/cases/migration/column_attributes_test.rb b/activerecord/test/cases/migration/column_attributes_test.rb
index 03d781d3d2..48df931543 100644
--- a/activerecord/test/cases/migration/column_attributes_test.rb
+++ b/activerecord/test/cases/migration/column_attributes_test.rb
@@ -72,9 +72,7 @@ module ActiveRecord
assert_kind_of BigDecimal, row.wealth
# If this assert fails, that means the SELECT is broken!
- unless current_adapter?(:SQLite3Adapter)
- assert_equal correct_value, row.wealth
- end
+ assert_equal correct_value, row.wealth
# Reset to old state
TestModel.delete_all
@@ -165,7 +163,7 @@ module ActiveRecord
assert_raise(ActiveRecordError) { add_column :test_models, :integer_too_big, :integer, limit: 10 }
unless current_adapter?(:PostgreSQLAdapter)
- assert_raise(ActiveRecordError) { add_column :test_models, :text_too_big, :integer, limit: 0xfffffffff }
+ assert_raise(ActiveRecordError) { add_column :test_models, :text_too_big, :text, limit: 0xfffffffff }
end
end
end
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 7f7faca70d..4cd258695d 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -10,9 +10,30 @@ class QueryCacheTest < ActiveRecord::TestCase
fixtures :tasks, :topics, :categories, :posts, :categories_posts
- teardown do
+ class ShouldNotHaveExceptionsLogger < ActiveRecord::LogSubscriber
+ attr_reader :logger
+
+ def initialize
+ super
+ @logger = ::Logger.new File::NULL
+ @exception = false
+ end
+
+ def exception?
+ @exception
+ end
+
+ def sql(event)
+ super
+ rescue
+ @exception = true
+ end
+ end
+
+ def teardown
Task.connection.clear_query_cache
ActiveRecord::Base.connection.disable_query_cache!
+ super
end
def test_exceptional_middleware_clears_and_disables_cache_on_error
@@ -121,6 +142,19 @@ class QueryCacheTest < ActiveRecord::TestCase
end
end
+ def test_cache_does_not_raise_exceptions
+ logger = ShouldNotHaveExceptionsLogger.new
+ subscriber = ActiveSupport::Notifications.subscribe "sql.active_record", logger
+
+ ActiveRecord::Base.cache do
+ assert_queries(1) { Task.find(1); Task.find(1) }
+ end
+
+ assert_not_predicate logger, :exception?
+ ensure
+ ActiveSupport::Notifications.unsubscribe subscriber
+ end
+
def test_cache_is_flat
Task.cache do
assert_queries(1) { Topic.find(1); Topic.find(1); }
@@ -138,7 +172,7 @@ class QueryCacheTest < ActiveRecord::TestCase
assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
elsif current_adapter?(:SQLite3Adapter, :Mysql2Adapter, :PostgreSQLAdapter)
# Future versions of the sqlite3 adapter will return numeric
- assert_instance_of Fixnum, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
+ assert_instance_of 0.class, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
else
assert_instance_of String, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index dcaae5b462..2e18c43b1b 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -1522,7 +1522,7 @@ class RelationTest < ActiveRecord::TestCase
assert_equal Post.where(author_id: 1).to_a, author_posts.to_a
all_posts = relation.only(:limit)
- assert_equal Post.limit(1).to_a.first, all_posts.first
+ assert_equal Post.limit(1).to_a, all_posts.to_a
end
def test_anonymous_extension
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 57b1bc889a..ae3a5651a1 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -51,6 +51,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
output = standard_dump
assert_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
+ assert_no_match %r{(?<=, ) do \|t\|}, output
assert_no_match %r{create_table "schema_migrations"}, output
assert_no_match %r{create_table "ar_internal_metadata"}, output
end
@@ -183,8 +184,10 @@ class SchemaDumperTest < ActiveRecord::TestCase
def test_schema_dumps_index_columns_in_right_order
index_definition = standard_dump.split(/\n/).grep(/t\.index.*company_index/).first.strip
- if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)
- assert_equal 't.index ["firm_id", "type", "rating"], name: "company_index", using: :btree', index_definition
+ if current_adapter?(:PostgreSQLAdapter)
+ assert_equal 't.index ["firm_id", "type", "rating"], name: "company_index", order: { rating: :desc }, using: :btree', index_definition
+ elsif current_adapter?(:Mysql2Adapter)
+ assert_equal 't.index ["firm_id", "type", "rating"], name: "company_index", length: { type: 10 }, using: :btree', index_definition
else
assert_equal 't.index ["firm_id", "type", "rating"], name: "company_index"', index_definition
end
@@ -423,6 +426,13 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
t.datetime :datetime_with_default, default: "2014-06-05 07:17:04"
t.time :time_with_default, default: "07:17:04"
end
+
+ if current_adapter?(:PostgreSQLAdapter)
+ @connection.create_table :infinity_defaults, force: true do |t|
+ t.float :float_with_inf_default, default: Float::INFINITY
+ t.float :float_with_nan_default, default: Float::NAN
+ end
+ end
end
teardown do
@@ -438,4 +448,11 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
assert_match %r{t\.datetime\s+"datetime_with_default",\s+default: '2014-06-05 07:17:04'}, output
assert_match %r{t\.time\s+"time_with_default",\s+default: '2000-01-01 07:17:04'}, output
end
+
+ def test_schema_dump_with_float_column_infinity_default
+ skip unless current_adapter?(:PostgreSQLAdapter)
+ output = dump_table_schema('infinity_defaults')
+ assert_match %r{t\.float\s+"float_with_inf_default",\s+default: ::Float::INFINITY}, output
+ assert_match %r{t\.float\s+"float_with_nan_default",\s+default: ::Float::NAN}, output
+ end
end
diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb
index bebd856faf..8e9514de7c 100644
--- a/activerecord/test/cases/serialized_attribute_test.rb
+++ b/activerecord/test/cases/serialized_attribute_test.rb
@@ -313,8 +313,8 @@ class SerializedAttributeTest < ActiveRecord::TestCase
return if value.nil?
value.gsub(" encoded", "")
end
- type = Class.new(ActiveModel::Type::Value) do
- include ActiveModel::Type::Helpers::Mutable
+ type = Class.new(ActiveRecord::Type::Value) do
+ include ActiveRecord::Type::Helpers::Mutable
def serialize(value)
return if value.nil?
diff --git a/activerecord/test/cases/test_case.rb b/activerecord/test/cases/test_case.rb
index 60ac3e08a1..8eddc5a9ed 100644
--- a/activerecord/test/cases/test_case.rb
+++ b/activerecord/test/cases/test_case.rb
@@ -125,12 +125,9 @@ module ActiveRecord
end
def call(name, start, finish, message_id, values)
- sql = values[:sql]
-
- # FIXME: this seems bad. we should probably have a better way to indicate
- # the query was cached
- return if "CACHE" == values[:name]
+ return if values[:cached]
+ sql = values[:sql]
self.class.log_all << sql
self.class.log << sql unless ignore.match?(sql)
end
diff --git a/activerecord/test/cases/type/date_time_test.rb b/activerecord/test/cases/type/date_time_test.rb
index bc4900e1c2..6848619ece 100644
--- a/activerecord/test/cases/type/date_time_test.rb
+++ b/activerecord/test/cases/type/date_time_test.rb
@@ -3,7 +3,7 @@ require "models/task"
module ActiveRecord
module Type
- class IntegerTest < ActiveRecord::TestCase
+ class DateTimeTest < ActiveRecord::TestCase
def test_datetime_seconds_precision_applied_to_timestamp
skip "This test is invalid if subsecond precision isn't supported" unless subsecond_precision_supported?
p = Task.create!(starting: ::Time.now)
diff --git a/activerecord/test/cases/view_test.rb b/activerecord/test/cases/view_test.rb
index 0e38cee334..1f326d4b39 100644
--- a/activerecord/test/cases/view_test.rb
+++ b/activerecord/test/cases/view_test.rb
@@ -11,20 +11,21 @@ module ViewBehavior
end
class Ebook < ActiveRecord::Base
+ self.table_name = "ebooks'"
self.primary_key = "id"
end
def setup
super
@connection = ActiveRecord::Base.connection
- create_view "ebooks", <<-SQL
+ create_view "ebooks'", <<-SQL
SELECT id, name, status FROM books WHERE format = 'ebook'
SQL
end
def teardown
super
- drop_view "ebooks"
+ drop_view "ebooks'"
end
def test_reading
@@ -66,15 +67,20 @@ module ViewBehavior
def test_does_not_assume_id_column_as_primary_key
model = Class.new(ActiveRecord::Base) do
- self.table_name = "ebooks"
+ self.table_name = "ebooks'"
end
assert_nil model.primary_key
end
def test_does_not_dump_view_as_table
- schema = dump_table_schema "ebooks"
- assert_no_match %r{create_table "ebooks"}, schema
+ schema = dump_table_schema "ebooks'"
+ assert_no_match %r{create_table "ebooks'"}, schema
end
+
+ private
+ def quote_table_name(name)
+ @connection.quote_table_name(name)
+ end
end
if ActiveRecord::Base.connection.supports_views?
@@ -83,11 +89,11 @@ if ActiveRecord::Base.connection.supports_views?
private
def create_view(name, query)
- @connection.execute "CREATE VIEW #{name} AS #{query}"
+ @connection.execute "CREATE VIEW #{quote_table_name(name)} AS #{query}"
end
def drop_view(name)
- @connection.execute "DROP VIEW #{name}" if @connection.view_exists? name
+ @connection.execute "DROP VIEW #{quote_table_name(name)}" if @connection.view_exists? name
end
end
@@ -206,11 +212,11 @@ if ActiveRecord::Base.connection.respond_to?(:supports_materialized_views?) &&
private
def create_view(name, query)
- @connection.execute "CREATE MATERIALIZED VIEW #{name} AS #{query}"
+ @connection.execute "CREATE MATERIALIZED VIEW #{quote_table_name(name)} AS #{query}"
end
def drop_view(name)
- @connection.execute "DROP MATERIALIZED VIEW #{name}" if @connection.view_exists? name
+ @connection.execute "DROP MATERIALIZED VIEW #{quote_table_name(name)}" if @connection.view_exists? name
end
end
end