aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/adapters/postgresql
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases/adapters/postgresql')
-rw-r--r--activerecord/test/cases/adapters/postgresql/active_schema_test.rb31
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb187
-rw-r--r--activerecord/test/cases/adapters/postgresql/bit_string_test.rb19
-rw-r--r--activerecord/test/cases/adapters/postgresql/bytea_test.rb39
-rw-r--r--activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb28
-rw-r--r--activerecord/test/cases/adapters/postgresql/change_schema_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/cidr_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/citext_test.rb116
-rw-r--r--activerecord/test/cases/adapters/postgresql/collation_test.rb32
-rw-r--r--activerecord/test/cases/adapters/postgresql/composite_test.rb26
-rw-r--r--activerecord/test/cases/adapters/postgresql/connection_test.rb125
-rw-r--r--activerecord/test/cases/adapters/postgresql/datatype_test.rb31
-rw-r--r--activerecord/test/cases/adapters/postgresql/domain_test.rb12
-rw-r--r--activerecord/test/cases/adapters/postgresql/enum_test.rb14
-rw-r--r--activerecord/test/cases/adapters/postgresql/explain_test.rb18
-rw-r--r--activerecord/test/cases/adapters/postgresql/extension_migration_test.rb6
-rw-r--r--activerecord/test/cases/adapters/postgresql/full_text_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/geometric_test.rb105
-rw-r--r--activerecord/test/cases/adapters/postgresql/hstore_test.rb535
-rw-r--r--activerecord/test/cases/adapters/postgresql/infinity_test.rb12
-rw-r--r--activerecord/test/cases/adapters/postgresql/integer_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/json_test.rb201
-rw-r--r--activerecord/test/cases/adapters/postgresql/ltree_test.rb22
-rw-r--r--activerecord/test/cases/adapters/postgresql/money_test.rb28
-rw-r--r--activerecord/test/cases/adapters/postgresql/network_test.rb46
-rw-r--r--activerecord/test/cases/adapters/postgresql/numbers_test.rb12
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb206
-rw-r--r--activerecord/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb27
-rw-r--r--activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb22
-rw-r--r--activerecord/test/cases/adapters/postgresql/quoting_test.rb13
-rw-r--r--activerecord/test/cases/adapters/postgresql/range_test.rb107
-rw-r--r--activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb24
-rw-r--r--activerecord/test/cases/adapters/postgresql/rename_table_test.rb16
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb37
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_test.rb171
-rw-r--r--activerecord/test/cases/adapters/postgresql/serial_test.rb72
-rw-r--r--activerecord/test/cases/adapters/postgresql/statement_pool_test.rb22
-rw-r--r--activerecord/test/cases/adapters/postgresql/timestamp_test.rb28
-rw-r--r--activerecord/test/cases/adapters/postgresql/transaction_test.rb190
-rw-r--r--activerecord/test/cases/adapters/postgresql/type_lookup_test.rb24
-rw-r--r--activerecord/test/cases/adapters/postgresql/utils_test.rb20
-rw-r--r--activerecord/test/cases/adapters/postgresql/uuid_test.rb293
-rw-r--r--activerecord/test/cases/adapters/postgresql/xml_test.rb18
43 files changed, 1714 insertions, 1245 deletions
diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
index 439e2ce6f7..99c53dadeb 100644
--- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
@@ -1,4 +1,6 @@
-require 'cases/helper'
+# frozen_string_literal: true
+
+require "cases/helper"
class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
def setup
@@ -15,12 +17,12 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
def test_create_database_with_encoding
assert_equal %(CREATE DATABASE "matt" ENCODING = 'utf8'), create_database(:matt)
- assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, :encoding => :latin1)
- assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, 'encoding' => :latin1)
+ assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, encoding: :latin1)
+ assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, "encoding" => :latin1)
end
def test_create_database_with_collation_and_ctype
- assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'UTF8' LC_COLLATE = 'ja_JP.UTF8' LC_CTYPE = 'ja_JP.UTF8'), create_database(:aimonetti, :encoding => :"UTF8", :collation => :"ja_JP.UTF8", :ctype => :"ja_JP.UTF8")
+ assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'UTF8' LC_COLLATE = 'ja_JP.UTF8' LC_CTYPE = 'ja_JP.UTF8'), create_database(:aimonetti, encoding: :"UTF8", collation: :"ja_JP.UTF8", ctype: :"ja_JP.UTF8")
end
def test_add_index
@@ -31,14 +33,18 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
assert_equal expected, add_index(:people, :last_name, unique: true, where: "state = 'active'")
expected = %(CREATE UNIQUE INDEX "index_people_on_lower_last_name" ON "people" (lower(last_name)))
- assert_equal expected, add_index(:people, 'lower(last_name)', unique: true)
+ assert_equal expected, add_index(:people, "lower(last_name)", unique: true)
expected = %(CREATE UNIQUE INDEX "index_people_on_last_name_varchar_pattern_ops" ON "people" (last_name varchar_pattern_ops))
- assert_equal expected, add_index(:people, 'last_name varchar_pattern_ops', unique: true)
+ assert_equal expected, add_index(:people, "last_name varchar_pattern_ops", unique: true)
expected = %(CREATE INDEX CONCURRENTLY "index_people_on_last_name" ON "people" ("last_name"))
assert_equal expected, add_index(:people, :last_name, algorithm: :concurrently)
+ expected = %(CREATE INDEX "index_people_on_last_name_and_first_name" ON "people" ("last_name" DESC, "first_name" ASC))
+ assert_equal expected, add_index(:people, [:last_name, :first_name], order: { last_name: :desc, first_name: :asc })
+ assert_equal expected, add_index(:people, ["last_name", :first_name], order: { last_name: :desc, "first_name" => :asc })
+
%w(gin gist hash btree).each do |type|
expected = %(CREATE INDEX "index_people_on_last_name" ON "people" USING #{type} ("last_name"))
assert_equal expected, add_index(:people, :last_name, using: type)
@@ -50,9 +56,12 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
assert_equal expected, add_index(:people, :last_name, using: type, unique: true, where: "state = 'active'")
expected = %(CREATE UNIQUE INDEX "index_people_on_lower_last_name" ON "people" USING #{type} (lower(last_name)))
- assert_equal expected, add_index(:people, 'lower(last_name)', using: type, unique: true)
+ assert_equal expected, add_index(:people, "lower(last_name)", using: type, unique: true)
end
+ expected = %(CREATE INDEX "index_people_on_last_name" ON "people" USING gist ("last_name" bpchar_pattern_ops))
+ assert_equal expected, add_index(:people, :last_name, using: :gist, opclass: { last_name: :bpchar_pattern_ops })
+
assert_raise ArgumentError do
add_index(:people, :last_name, algorithm: :copy)
end
@@ -63,7 +72,7 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
def test_remove_index
# remove_index calls index_name_for_remove which can't work since execute is stubbed
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_for_remove) do |*|
- 'index_people_on_last_name'
+ "index_people_on_last_name"
end
expected = %(DROP INDEX CONCURRENTLY "index_people_on_last_name")
@@ -81,6 +90,12 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
assert_equal expected, remove_index(:people, name: "index_people_on_last_name", algorithm: :concurrently)
end
+ def test_remove_index_with_wrong_option
+ assert_raises ArgumentError do
+ remove_index(:people, coulmn: :last_name)
+ end
+ end
+
private
def method_missing(method_symbol, *arguments)
ActiveRecord::Base.connection.send(method_symbol, *arguments)
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 380a90d765..0e9e86f425 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -1,63 +1,100 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
include InTimeZone
class PgArray < ActiveRecord::Base
- self.table_name = 'pg_arrays'
+ self.table_name = "pg_arrays"
end
def setup
@connection = ActiveRecord::Base.connection
- enable_extension!('hstore', @connection)
+ enable_extension!("hstore", @connection)
@connection.transaction do
- @connection.create_table('pg_arrays') do |t|
- t.string 'tags', array: true
- t.integer 'ratings', array: true
+ @connection.create_table("pg_arrays") do |t|
+ t.string "tags", array: true, limit: 255
+ t.integer "ratings", array: true
t.datetime :datetimes, array: true
t.hstore :hstores, array: true
+ t.decimal :decimals, array: true, default: [], precision: 10, scale: 2
+ t.timestamp :timestamps, array: true, default: [], precision: 6
end
end
PgArray.reset_column_information
- @column = PgArray.columns_hash['tags']
+ @column = PgArray.columns_hash["tags"]
@type = PgArray.type_for_attribute("tags")
end
teardown do
- @connection.drop_table 'pg_arrays', if_exists: true
- disable_extension!('hstore', @connection)
+ @connection.drop_table "pg_arrays", if_exists: true
+ disable_extension!("hstore", @connection)
end
def test_column
assert_equal :string, @column.type
- assert_equal "character varying", @column.sql_type
+ assert_equal "character varying(255)", @column.sql_type
assert @column.array?
assert_not @type.binary?
- ratings_column = PgArray.columns_hash['ratings']
+ ratings_column = PgArray.columns_hash["ratings"]
assert_equal :integer, ratings_column.type
assert ratings_column.array?
end
+ def test_not_compatible_with_serialize_array
+ new_klass = Class.new(PgArray) do
+ serialize :tags, Array
+ end
+ assert_raises(ActiveRecord::AttributeMethods::Serialization::ColumnNotSerializableError) do
+ new_klass.new
+ end
+ end
+
+ class MyTags
+ def initialize(tags); @tags = tags end
+ def to_a; @tags end
+ def self.load(tags); new(tags) end
+ def self.dump(object); object.to_a end
+ end
+
+ def test_array_with_serialized_attributes
+ new_klass = Class.new(PgArray) do
+ serialize :tags, MyTags
+ end
+
+ new_klass.create!(tags: MyTags.new(["one", "two"]))
+ record = new_klass.first
+
+ assert_instance_of MyTags, record.tags
+ assert_equal ["one", "two"], record.tags.to_a
+
+ record.tags = MyTags.new(["three", "four"])
+ record.save!
+
+ assert_equal ["three", "four"], record.reload.tags.to_a
+ end
+
def test_default
- @connection.add_column 'pg_arrays', 'score', :integer, array: true, default: [4, 4, 2]
+ @connection.add_column "pg_arrays", "score", :integer, array: true, default: [4, 4, 2]
PgArray.reset_column_information
- assert_equal([4, 4, 2], PgArray.column_defaults['score'])
+ assert_equal([4, 4, 2], PgArray.column_defaults["score"])
assert_equal([4, 4, 2], PgArray.new.score)
ensure
PgArray.reset_column_information
end
def test_default_strings
- @connection.add_column 'pg_arrays', 'names', :string, array: true, default: ["foo", "bar"]
+ @connection.add_column "pg_arrays", "names", :string, array: true, default: ["foo", "bar"]
PgArray.reset_column_information
- assert_equal(["foo", "bar"], PgArray.column_defaults['names'])
+ assert_equal(["foo", "bar"], PgArray.column_defaults["names"])
assert_equal(["foo", "bar"], PgArray.new.names)
ensure
PgArray.reset_column_information
@@ -68,10 +105,10 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
@connection.change_column :pg_arrays, :snippets, :text, array: true, default: []
PgArray.reset_column_information
- column = PgArray.columns_hash['snippets']
+ column = PgArray.columns_hash["snippets"]
assert_equal :text, column.type
- assert_equal [], PgArray.column_defaults['snippets']
+ assert_equal [], PgArray.column_defaults["snippets"]
assert column.array?
end
@@ -88,17 +125,17 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
@connection.change_column_default :pg_arrays, :tags, []
PgArray.reset_column_information
- assert_equal [], PgArray.column_defaults['tags']
+ assert_equal [], PgArray.column_defaults["tags"]
end
def test_type_cast_array
- assert_equal(['1', '2', '3'], @type.deserialize('{1,2,3}'))
- assert_equal([], @type.deserialize('{}'))
- assert_equal([nil], @type.deserialize('{NULL}'))
+ assert_equal(["1", "2", "3"], @type.deserialize("{1,2,3}"))
+ assert_equal([], @type.deserialize("{}"))
+ assert_equal([nil], @type.deserialize("{NULL}"))
end
def test_type_cast_integers
- x = PgArray.new(ratings: ['1', '2'])
+ x = PgArray.new(ratings: ["1", "2"])
assert_equal([1, 2], x.ratings)
@@ -110,22 +147,23 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
def test_schema_dump_with_shorthand
output = dump_table_schema "pg_arrays"
- assert_match %r[t\.string\s+"tags",\s+array: true], output
+ assert_match %r[t\.string\s+"tags",\s+limit: 255,\s+array: true], output
assert_match %r[t\.integer\s+"ratings",\s+array: true], output
+ assert_match %r[t\.decimal\s+"decimals",\s+precision: 10,\s+scale: 2,\s+default: \[\],\s+array: true], output
end
def test_select_with_strings
@connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')"
x = PgArray.first
- assert_equal(['1','2','3'], x.tags)
+ assert_equal(["1", "2", "3"], x.tags)
end
def test_rewrite_with_strings
@connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')"
x = PgArray.first
- x.tags = ['1','2','3','4']
+ x.tags = ["1", "2", "3", "4"]
x.save!
- assert_equal ['1','2','3','4'], x.reload.tags
+ assert_equal ["1", "2", "3", "4"], x.reload.tags
end
def test_select_with_integers
@@ -137,25 +175,25 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
def test_rewrite_with_integers
@connection.execute "insert into pg_arrays (ratings) VALUES ('{1,2,3}')"
x = PgArray.first
- x.ratings = [2, '3', 4]
+ x.ratings = [2, "3", 4]
x.save!
assert_equal [2, 3, 4], x.reload.ratings
end
def test_multi_dimensional_with_strings
- assert_cycle(:tags, [[['1'], ['2']], [['2'], ['3']]])
+ assert_cycle(:tags, [[["1"], ["2"]], [["2"], ["3"]]])
end
def test_with_empty_strings
- assert_cycle(:tags, [ '1', '2', '', '4', '', '5' ])
+ assert_cycle(:tags, [ "1", "2", "", "4", "", "5" ])
end
def test_with_multi_dimensional_empty_strings
- assert_cycle(:tags, [[['1', '2'], ['', '4'], ['', '5']]])
+ assert_cycle(:tags, [[["1", "2"], ["", "4"], ["", "5"]]])
end
def test_with_arbitrary_whitespace
- assert_cycle(:tags, [[['1', '2'], [' ', '4'], [' ', '5']]])
+ assert_cycle(:tags, [[["1", "2"], [" ", "4"], [" ", "5"]]])
end
def test_multi_dimensional_with_integers
@@ -163,34 +201,45 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
end
def test_strings_with_quotes
- assert_cycle(:tags, ['this has','some "s that need to be escaped"'])
+ assert_cycle(:tags, ["this has", 'some "s that need to be escaped"'])
end
def test_strings_with_commas
- assert_cycle(:tags, ['this,has','many,values'])
+ assert_cycle(:tags, ["this,has", "many,values"])
end
def test_strings_with_array_delimiters
- assert_cycle(:tags, ['{','}'])
+ assert_cycle(:tags, ["{", "}"])
end
def test_strings_with_null_strings
- assert_cycle(:tags, ['NULL','NULL'])
+ assert_cycle(:tags, ["NULL", "NULL"])
end
def test_contains_nils
- assert_cycle(:tags, ['1',nil,nil])
+ assert_cycle(:tags, ["1", nil, nil])
end
def test_insert_fixture
tag_values = ["val1", "val2", "val3_with_'_multiple_quote_'_chars"]
- @connection.insert_fixture({"tags" => tag_values}, "pg_arrays" )
+ @connection.insert_fixture({ "tags" => tag_values }, "pg_arrays")
+ assert_equal(PgArray.last.tags, tag_values)
+ end
+
+ def test_insert_fixtures
+ tag_values = ["val1", "val2", "val3_with_'_multiple_quote_'_chars"]
+ @connection.insert_fixtures([{ "tags" => tag_values }], "pg_arrays")
assert_equal(PgArray.last.tags, tag_values)
end
def test_attribute_for_inspect_for_array_field
+ record = PgArray.new { |a| a.ratings = (1..10).to_a }
+ assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", record.attribute_for_inspect(:ratings))
+ end
+
+ def test_attribute_for_inspect_for_array_field_for_large_array
record = PgArray.new { |a| a.ratings = (1..11).to_a }
- assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]", record.attribute_for_inspect(:ratings))
+ assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]", record.attribute_for_inspect(:ratings))
end
def test_escaping
@@ -206,17 +255,18 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
x = PgArray.create!(tags: tags)
x.reload
- assert_equal x.tags_before_type_cast, PgArray.type_for_attribute('tags').serialize(tags)
+ refute x.changed?
end
def test_quoting_non_standard_delimiters
strings = ["hello,", "world;"]
oid = ActiveRecord::ConnectionAdapters::PostgreSQL::OID
- comma_delim = oid::Array.new(ActiveRecord::Type::String.new, ',')
- semicolon_delim = oid::Array.new(ActiveRecord::Type::String.new, ';')
+ comma_delim = oid::Array.new(ActiveRecord::Type::String.new, ",")
+ semicolon_delim = oid::Array.new(ActiveRecord::Type::String.new, ";")
+ conn = PgArray.connection
- assert_equal %({"hello,",world;}), comma_delim.serialize(strings)
- assert_equal %({hello,;"world;"}), semicolon_delim.serialize(strings)
+ assert_equal %({"hello,",world;}), conn.type_cast(comma_delim.serialize(strings))
+ assert_equal %({hello,;"world;"}), conn.type_cast(semicolon_delim.serialize(strings))
end
def test_mutate_array
@@ -231,13 +281,13 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
end
def test_mutate_value_in_array
- x = PgArray.create!(hstores: [{ a: 'a' }, { b: 'b' }])
+ x = PgArray.create!(hstores: [{ a: "a" }, { b: "b" }])
- x.hstores.first['a'] = 'c'
+ x.hstores.first["a"] = "c"
x.save!
x.reload
- assert_equal [{ 'a' => 'c' }, { 'b' => 'b' }], x.hstores
+ assert_equal [{ "a" => "c" }, { "b" => "b" }], x.hstores
assert_not x.changed?
end
@@ -285,6 +335,12 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
assert_equal record.tags, record.reload.tags
end
+ def test_where_by_attribute_with_array
+ tags = ["black", "blue"]
+ record = PgArray.create!(tags: tags)
+ assert_equal record, PgArray.where(tags: tags).take
+ end
+
def test_uniqueness_validation
klass = Class.new(PgArray) do
validates_uniqueness_of :tags
@@ -300,18 +356,33 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
assert_equal ["has already been taken"], e2.errors[:tags], "Should have uniqueness message for tags"
end
- private
- def assert_cycle field, array
- # test creation
- x = PgArray.create!(field => array)
- x.reload
- assert_equal(array, x.public_send(field))
+ def test_encoding_arrays_of_utf8_strings
+ arrays_of_utf8_strings = %w(nový ファイル)
+ assert_equal arrays_of_utf8_strings, @type.deserialize(@type.serialize(arrays_of_utf8_strings))
+ assert_equal [arrays_of_utf8_strings], @type.deserialize(@type.serialize([arrays_of_utf8_strings]))
+ end
- # test updating
- x = PgArray.create!(field => [])
- x.public_send("#{field}=", array)
- x.save!
- x.reload
- assert_equal(array, x.public_send(field))
+ def test_precision_is_respected_on_timestamp_columns
+ time = Time.now.change(usec: 123)
+ record = PgArray.create!(timestamps: [time])
+
+ assert_equal 123, record.timestamps.first.usec
+ record.reload
+ assert_equal 123, record.timestamps.first.usec
end
+
+ private
+ def assert_cycle(field, array)
+ # test creation
+ x = PgArray.create!(field => array)
+ x.reload
+ assert_equal(array, x.public_send(field))
+
+ # test updating
+ x = PgArray.create!(field => [])
+ x.public_send("#{field}=", array)
+ x.save!
+ x.reload
+ assert_equal(array, x.public_send(field))
+ end
end
diff --git a/activerecord/test/cases/adapters/postgresql/bit_string_test.rb b/activerecord/test/cases/adapters/postgresql/bit_string_test.rb
index cec6081aec..df04299569 100644
--- a/activerecord/test/cases/adapters/postgresql/bit_string_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/bit_string_test.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/connection_helper'
-require 'support/schema_dumping_helper'
+require "support/connection_helper"
+require "support/schema_dumping_helper"
class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase
include ConnectionHelper
@@ -10,7 +12,7 @@ class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase
def setup
@connection = ActiveRecord::Base.connection
- @connection.create_table('postgresql_bit_strings', :force => true) do |t|
+ @connection.create_table("postgresql_bit_strings", force: true) do |t|
t.bit :a_bit, default: "00000011", limit: 8
t.bit_varying :a_bit_varying, default: "0011", limit: 4
t.bit :another_bit
@@ -20,7 +22,7 @@ class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase
def teardown
return unless @connection
- @connection.drop_table 'postgresql_bit_strings', if_exists: true
+ @connection.drop_table "postgresql_bit_strings", if_exists: true
end
def test_bit_string_column
@@ -44,10 +46,10 @@ class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase
end
def test_default
- assert_equal "00000011", PostgresqlBitString.column_defaults['a_bit']
+ assert_equal "00000011", PostgresqlBitString.column_defaults["a_bit"]
assert_equal "00000011", PostgresqlBitString.new.a_bit
- assert_equal "0011", PostgresqlBitString.column_defaults['a_bit_varying']
+ assert_equal "0011", PostgresqlBitString.column_defaults["a_bit_varying"]
assert_equal "0011", PostgresqlBitString.new.a_bit_varying
end
@@ -65,10 +67,11 @@ class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase
end
def test_roundtrip
- PostgresqlBitString.create! a_bit: "00001010", a_bit_varying: "0101"
- record = PostgresqlBitString.first
+ record = PostgresqlBitString.create!(a_bit: "00001010", a_bit_varying: "0101")
assert_equal "00001010", record.a_bit
assert_equal "0101", record.a_bit_varying
+ assert_nil record.another_bit
+ assert_nil record.another_bit_varying
record.a_bit = "11111111"
record.a_bit_varying = "0xF"
diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
index 7adc070430..a6bee113ff 100644
--- a/activerecord/test/cases/adapters/postgresql/bytea_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
@@ -1,29 +1,31 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
class ByteaDataType < ActiveRecord::Base
- self.table_name = 'bytea_data_type'
+ self.table_name = "bytea_data_type"
end
def setup
@connection = ActiveRecord::Base.connection
begin
@connection.transaction do
- @connection.create_table('bytea_data_type') do |t|
- t.binary 'payload'
- t.binary 'serialized'
+ @connection.create_table("bytea_data_type") do |t|
+ t.binary "payload"
+ t.binary "serialized"
end
end
end
- @column = ByteaDataType.columns_hash['payload']
+ @column = ByteaDataType.columns_hash["payload"]
@type = ByteaDataType.type_for_attribute("payload")
end
teardown do
- @connection.drop_table 'bytea_data_type', if_exists: true
+ @connection.drop_table "bytea_data_type", if_exists: true
end
def test_column
@@ -32,9 +34,9 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
end
def test_binary_columns_are_limitless_the_upper_limit_is_one_GB
- assert_equal 'bytea', @connection.type_to_sql(:binary, 100_000)
+ assert_equal "bytea", @connection.type_to_sql(:binary, limit: 100_000)
assert_raise ActiveRecord::ActiveRecordError do
- @connection.type_to_sql :binary, 4294967295
+ @connection.type_to_sql(:binary, limit: 4294967295)
end
end
@@ -42,17 +44,17 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
assert @column
data = "\u001F\x8B"
- assert_equal('UTF-8', data.encoding.name)
- assert_equal('ASCII-8BIT', @type.deserialize(data).encoding.name)
+ assert_equal("UTF-8", data.encoding.name)
+ assert_equal("ASCII-8BIT", @type.deserialize(data).encoding.name)
end
def test_type_cast_binary_value
- data = "\u001F\x8B".force_encoding("BINARY")
+ data = "\u001F\x8B".dup.force_encoding("BINARY")
assert_equal(data, @type.deserialize(data))
end
def test_type_case_nil
- assert_equal(nil, @type.deserialize(nil))
+ assert_nil(@type.deserialize(nil))
end
def test_read_value
@@ -66,7 +68,7 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
def test_read_nil_value
@connection.execute "insert into bytea_data_type (payload) VALUES (null)"
record = ByteaDataType.first
- assert_equal(nil, record.payload)
+ assert_nil(record.payload)
record.delete
end
@@ -88,14 +90,15 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
def test_via_to_sql_with_complicating_connection
Thread.new do
other_conn = ActiveRecord::Base.connection
- other_conn.execute('SET standard_conforming_strings = off')
+ other_conn.execute("SET standard_conforming_strings = off")
+ other_conn.execute("SET escape_string_warning = off")
end.join
test_via_to_sql
end
def test_write_binary
- data = File.read(File.join(File.dirname(__FILE__), '..', '..', '..', 'assets', 'example.log'))
+ data = File.read(File.join(__dir__, "..", "..", "..", "assets", "example.log"))
assert(data.size > 1)
record = ByteaDataType.create(payload: data)
assert_not record.new_record?
@@ -106,8 +109,8 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
def test_write_nil
record = ByteaDataType.create(payload: nil)
assert_not record.new_record?
- assert_equal(nil, record.payload)
- assert_equal(nil, ByteaDataType.where(id: record.id).first.payload)
+ assert_nil(record.payload)
+ assert_nil(ByteaDataType.where(id: record.id).first.payload)
end
class Serializer
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..305e033642
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+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/change_schema_test.rb b/activerecord/test/cases/adapters/postgresql/change_schema_test.rb
index bc12df668d..adf461a9cc 100644
--- a/activerecord/test/cases/adapters/postgresql/change_schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/change_schema_test.rb
@@ -1,4 +1,6 @@
-require 'cases/helper'
+# frozen_string_literal: true
+
+require "cases/helper"
module ActiveRecord
class Migration
@@ -19,17 +21,17 @@ module ActiveRecord
def test_change_string_to_date
connection.change_column :strings, :somedate, :timestamp, using: 'CAST("somedate" AS timestamp)'
- assert_equal :datetime, connection.columns(:strings).find { |c| c.name == 'somedate' }.type
+ assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type
end
def test_change_type_with_symbol
connection.change_column :strings, :somedate, :timestamp, cast_as: :timestamp
- assert_equal :datetime, connection.columns(:strings).find { |c| c.name == 'somedate' }.type
+ assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type
end
def test_change_type_with_array
connection.change_column :strings, :somedate, :timestamp, array: true, cast_as: :timestamp
- column = connection.columns(:strings).find { |c| c.name == 'somedate' }
+ column = connection.columns(:strings).find { |c| c.name == "somedate" }
assert_equal :datetime, column.type
assert column.array?
end
diff --git a/activerecord/test/cases/adapters/postgresql/cidr_test.rb b/activerecord/test/cases/adapters/postgresql/cidr_test.rb
index 52f2a0096c..f20958fbd2 100644
--- a/activerecord/test/cases/adapters/postgresql/cidr_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/cidr_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cases/helper"
require "ipaddr"
diff --git a/activerecord/test/cases/adapters/postgresql/citext_test.rb b/activerecord/test/cases/adapters/postgresql/citext_test.rb
index bd62041e79..a25f102bad 100644
--- a/activerecord/test/cases/adapters/postgresql/citext_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/citext_test.rb
@@ -1,78 +1,78 @@
-require 'cases/helper'
-require 'support/schema_dumping_helper'
-
-if ActiveRecord::Base.connection.supports_extensions?
- class PostgresqlCitextTest < ActiveRecord::PostgreSQLTestCase
- include SchemaDumpingHelper
- class Citext < ActiveRecord::Base
- self.table_name = 'citexts'
- end
+# frozen_string_literal: true
- def setup
- @connection = ActiveRecord::Base.connection
+require "cases/helper"
+require "support/schema_dumping_helper"
- enable_extension!('citext', @connection)
+class PostgresqlCitextTest < ActiveRecord::PostgreSQLTestCase
+ include SchemaDumpingHelper
+ class Citext < ActiveRecord::Base
+ self.table_name = "citexts"
+ end
- @connection.create_table('citexts') do |t|
- t.citext 'cival'
- end
- end
+ def setup
+ @connection = ActiveRecord::Base.connection
- teardown do
- @connection.drop_table 'citexts', if_exists: true
- disable_extension!('citext', @connection)
- end
+ enable_extension!("citext", @connection)
- def test_citext_enabled
- assert @connection.extension_enabled?('citext')
+ @connection.create_table("citexts") do |t|
+ t.citext "cival"
end
+ end
- def test_column
- column = Citext.columns_hash['cival']
- assert_equal :citext, column.type
- assert_equal 'citext', column.sql_type
- assert_not column.array?
+ teardown do
+ @connection.drop_table "citexts", if_exists: true
+ disable_extension!("citext", @connection)
+ end
- type = Citext.type_for_attribute('cival')
- assert_not type.binary?
- end
+ def test_citext_enabled
+ assert @connection.extension_enabled?("citext")
+ end
- def test_change_table_supports_json
- @connection.transaction do
- @connection.change_table('citexts') do |t|
- t.citext 'username'
- end
- Citext.reset_column_information
- column = Citext.columns_hash['username']
- assert_equal :citext, column.type
+ def test_column
+ column = Citext.columns_hash["cival"]
+ assert_equal :citext, column.type
+ assert_equal "citext", column.sql_type
+ assert_not column.array?
- raise ActiveRecord::Rollback # reset the schema change
+ type = Citext.type_for_attribute("cival")
+ assert_not type.binary?
+ end
+
+ def test_change_table_supports_json
+ @connection.transaction do
+ @connection.change_table("citexts") do |t|
+ t.citext "username"
end
- ensure
Citext.reset_column_information
+ column = Citext.columns_hash["username"]
+ assert_equal :citext, column.type
+
+ raise ActiveRecord::Rollback # reset the schema change
end
+ ensure
+ Citext.reset_column_information
+ end
- def test_write
- x = Citext.new(cival: 'Some CI Text')
- x.save!
- citext = Citext.first
- assert_equal "Some CI Text", citext.cival
+ def test_write
+ x = Citext.new(cival: "Some CI Text")
+ x.save!
+ citext = Citext.first
+ assert_equal "Some CI Text", citext.cival
- citext.cival = "Some NEW CI Text"
- citext.save!
+ citext.cival = "Some NEW CI Text"
+ citext.save!
- assert_equal "Some NEW CI Text", citext.reload.cival
- end
+ assert_equal "Some NEW CI Text", citext.reload.cival
+ end
- def test_select_case_insensitive
- @connection.execute "insert into citexts (cival) values('Cased Text')"
- x = Citext.where(cival: 'cased text').first
- assert_equal 'Cased Text', x.cival
- end
+ def test_select_case_insensitive
+ @connection.execute "insert into citexts (cival) values('Cased Text')"
+ x = Citext.where(cival: "cased text").first
+ assert_equal "Cased Text", x.cival
+ end
- def test_schema_dump_with_shorthand
- output = dump_table_schema("citexts")
- assert_match %r[t\.citext "cival"], output
- end
+ def test_schema_dump_with_shorthand
+ output = dump_table_schema("citexts")
+ assert_match %r[t\.citext "cival"], output
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/collation_test.rb b/activerecord/test/cases/adapters/postgresql/collation_test.rb
index 8470329c35..7468f4c4f8 100644
--- a/activerecord/test/cases/adapters/postgresql/collation_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/collation_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
class PostgresqlCollationTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
@@ -7,8 +9,8 @@ class PostgresqlCollationTest < ActiveRecord::PostgreSQLTestCase
def setup
@connection = ActiveRecord::Base.connection
@connection.create_table :postgresql_collations, force: true do |t|
- t.string :string_c, collation: 'C'
- t.text :text_posix, collation: 'POSIX'
+ t.string :string_c, collation: "C"
+ t.text :text_posix, collation: "POSIX"
end
end
@@ -17,37 +19,37 @@ class PostgresqlCollationTest < ActiveRecord::PostgreSQLTestCase
end
test "string column with collation" do
- column = @connection.columns(:postgresql_collations).find { |c| c.name == 'string_c' }
+ column = @connection.columns(:postgresql_collations).find { |c| c.name == "string_c" }
assert_equal :string, column.type
- assert_equal 'C', column.collation
+ assert_equal "C", column.collation
end
test "text column with collation" do
- column = @connection.columns(:postgresql_collations).find { |c| c.name == 'text_posix' }
+ column = @connection.columns(:postgresql_collations).find { |c| c.name == "text_posix" }
assert_equal :text, column.type
- assert_equal 'POSIX', column.collation
+ assert_equal "POSIX", column.collation
end
test "add column with collation" do
- @connection.add_column :postgresql_collations, :title, :string, collation: 'C'
+ @connection.add_column :postgresql_collations, :title, :string, collation: "C"
- column = @connection.columns(:postgresql_collations).find { |c| c.name == 'title' }
+ column = @connection.columns(:postgresql_collations).find { |c| c.name == "title" }
assert_equal :string, column.type
- assert_equal 'C', column.collation
+ assert_equal "C", column.collation
end
test "change column with collation" do
@connection.add_column :postgresql_collations, :description, :string
- @connection.change_column :postgresql_collations, :description, :text, collation: 'POSIX'
+ @connection.change_column :postgresql_collations, :description, :text, collation: "POSIX"
- column = @connection.columns(:postgresql_collations).find { |c| c.name == 'description' }
+ column = @connection.columns(:postgresql_collations).find { |c| c.name == "description" }
assert_equal :text, column.type
- assert_equal 'POSIX', column.collation
+ assert_equal "POSIX", column.collation
end
test "schema dump includes collation" do
output = dump_table_schema("postgresql_collations")
- assert_match %r{t.string\s+"string_c",\s+collation: "C"$}, output
- assert_match %r{t.text\s+"text_posix",\s+collation: "POSIX"$}, output
+ assert_match %r{t\.string\s+"string_c",\s+collation: "C"$}, output
+ assert_match %r{t\.text\s+"text_posix",\s+collation: "POSIX"$}, output
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/composite_test.rb b/activerecord/test/cases/adapters/postgresql/composite_test.rb
index 1de87e5f01..5da95f7e2c 100644
--- a/activerecord/test/cases/adapters/postgresql/composite_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/composite_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/connection_helper'
+require "support/connection_helper"
module PostgresqlCompositeBehavior
include ConnectionHelper
@@ -20,7 +22,7 @@ module PostgresqlCompositeBehavior
street VARCHAR(90)
);
SQL
- @connection.create_table('postgresql_composites') do |t|
+ @connection.create_table("postgresql_composites") do |t|
t.column :address, :full_address
end
end
@@ -29,8 +31,8 @@ module PostgresqlCompositeBehavior
def teardown
super
- @connection.drop_table 'postgresql_composites', if_exists: true
- @connection.execute 'DROP TYPE IF EXISTS full_address'
+ @connection.drop_table "postgresql_composites", if_exists: true
+ @connection.execute "DROP TYPE IF EXISTS full_address"
reset_connection
PostgresqlComposite.reset_column_information
end
@@ -69,12 +71,12 @@ class PostgresqlCompositeTest < ActiveRecord::PostgreSQLTestCase
end
private
- def ensure_warning_is_issued
- warning = capture(:stderr) do
- PostgresqlComposite.columns_hash
+ def ensure_warning_is_issued
+ warning = capture(:stderr) do
+ PostgresqlComposite.columns_hash
+ end
+ assert_match(/unknown OID \d+: failed to recognize type of 'address'\. It will be treated as String\./, warning)
end
- assert_match(/unknown OID \d+: failed to recognize type of 'address'\. It will be treated as String\./, warning)
- end
end
class PostgresqlCompositeWithCustomOIDTest < ActiveRecord::PostgreSQLTestCase
@@ -104,7 +106,7 @@ class PostgresqlCompositeWithCustomOIDTest < ActiveRecord::PostgreSQLTestCase
def setup
super
- @connection.type_map.register_type "full_address", FullAddressType.new
+ @connection.send(:type_map).register_type "full_address", FullAddressType.new
end
def test_column
@@ -126,7 +128,7 @@ class PostgresqlCompositeWithCustomOIDTest < ActiveRecord::PostgreSQLTestCase
composite.address = FullAddress.new("Paris", "Rue Basse")
composite.save!
- assert_equal 'Paris', composite.reload.address.city
- assert_equal 'Rue Basse', composite.reload.address.street
+ assert_equal "Paris", composite.reload.address.city
+ assert_equal "Rue Basse", composite.reload.address.street
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb
index f8403bfe1a..81358b8fc4 100644
--- a/activerecord/test/cases/adapters/postgresql/connection_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/connection_helper'
+require "support/connection_helper"
module ActiveRecord
class PostgresqlConnectionTest < ActiveRecord::PostgreSQLTestCase
@@ -13,7 +15,7 @@ module ActiveRecord
def setup
super
@subscriber = SQLSubscriber.new
- @subscription = ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber)
+ @subscription = ActiveSupport::Notifications.subscribe("sql.active_record", @subscriber)
@connection = ActiveRecord::Base.connection
end
@@ -23,23 +25,29 @@ module ActiveRecord
end
def test_truncate
- count = ActiveRecord::Base.connection.execute("select count(*) from comments").first['count'].to_i
+ count = ActiveRecord::Base.connection.execute("select count(*) from comments").first["count"].to_i
assert_operator count, :>, 0
ActiveRecord::Base.connection.truncate("comments")
- count = ActiveRecord::Base.connection.execute("select count(*) from comments").first['count'].to_i
+ count = ActiveRecord::Base.connection.execute("select count(*) from comments").first["count"].to_i
assert_equal 0, count
end
def test_encoding
- assert_not_nil @connection.encoding
+ assert_queries(1) do
+ assert_not_nil @connection.encoding
+ end
end
def test_collation
- assert_not_nil @connection.collation
+ assert_queries(1) do
+ assert_not_nil @connection.collation
+ end
end
def test_ctype
- assert_not_nil @connection.ctype
+ assert_queries(1) do
+ assert_not_nil @connection.ctype
+ end
end
def test_default_client_min_messages
@@ -54,85 +62,85 @@ module ActiveRecord
NonExistentTable.establish_connection(params)
# Verify the connection param has been applied.
- expect = NonExistentTable.connection.query('show geqo').first.first
- assert_equal 'off', expect
+ expect = NonExistentTable.connection.query("show geqo").first.first
+ assert_equal "off", expect
end
def test_reset
- @connection.query('ROLLBACK')
- @connection.query('SET geqo TO off')
+ @connection.query("ROLLBACK")
+ @connection.query("SET geqo TO off")
# Verify the setting has been applied.
- expect = @connection.query('show geqo').first.first
- assert_equal 'off', expect
+ expect = @connection.query("show geqo").first.first
+ assert_equal "off", expect
@connection.reset!
# Verify the setting has been cleared.
- expect = @connection.query('show geqo').first.first
- assert_equal 'on', expect
+ expect = @connection.query("show geqo").first.first
+ assert_equal "on", expect
end
def test_reset_with_transaction
- @connection.query('ROLLBACK')
- @connection.query('SET geqo TO off')
+ @connection.query("ROLLBACK")
+ @connection.query("SET geqo TO off")
# Verify the setting has been applied.
- expect = @connection.query('show geqo').first.first
- assert_equal 'off', expect
+ expect = @connection.query("show geqo").first.first
+ assert_equal "off", expect
- @connection.query('BEGIN')
+ @connection.query("BEGIN")
@connection.reset!
# Verify the setting has been cleared.
- expect = @connection.query('show geqo').first.first
- assert_equal 'on', expect
+ expect = @connection.query("show geqo").first.first
+ assert_equal "on", expect
end
def test_tables_logs_name
- ActiveSupport::Deprecation.silence { @connection.tables('hello') }
- assert_equal 'SCHEMA', @subscriber.logged[0][1]
+ @connection.tables
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_indexes_logs_name
- @connection.indexes('items', 'hello')
- assert_equal 'SCHEMA', @subscriber.logged[0][1]
+ @connection.indexes("items")
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_table_exists_logs_name
- ActiveSupport::Deprecation.silence { @connection.table_exists?('items') }
- assert_equal 'SCHEMA', @subscriber.logged[0][1]
+ @connection.table_exists?("items")
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_table_alias_length_logs_name
- @connection.instance_variable_set("@table_alias_length", nil)
+ @connection.instance_variable_set("@max_identifier_length", nil)
@connection.table_alias_length
- assert_equal 'SCHEMA', @subscriber.logged[0][1]
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_current_database_logs_name
@connection.current_database
- assert_equal 'SCHEMA', @subscriber.logged[0][1]
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_encoding_logs_name
@connection.encoding
- assert_equal 'SCHEMA', @subscriber.logged[0][1]
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_schema_names_logs_name
@connection.schema_names
- assert_equal 'SCHEMA', @subscriber.logged[0][1]
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
end
if ActiveRecord::Base.connection.prepared_statements
def test_statement_key_is_logged
bind = Relation::QueryAttribute.new(nil, 1, Type::Value.new)
- @connection.exec_query('SELECT $1::integer', 'SQL', [bind], prepare: true)
+ @connection.exec_query("SELECT $1::integer", "SQL", [bind], prepare: true)
name = @subscriber.payloads.last[:statement_name]
assert name
res = @connection.exec_query("EXPLAIN (FORMAT JSON) EXECUTE #{name}(1)")
- plan = res.column_types['QUERY PLAN'].deserialize res.rows.first.first
+ plan = res.column_types["QUERY PLAN"].deserialize res.rows.first.first
assert_operator plan.length, :>, 0
end
end
@@ -146,7 +154,7 @@ module ActiveRecord
# To restart PostgreSQL 9.1 on OS X, installed via MacPorts, ...
# sudo su postgres -c "pg_ctl restart -D /opt/local/var/db/postgresql91/defaultdb/ -m fast"
def test_reconnection_after_actual_disconnection_with_verify
- original_connection_pid = @connection.query('select pg_backend_pid()')
+ original_connection_pid = @connection.query("select pg_backend_pid()")
# Sanity check.
assert @connection.active?
@@ -155,8 +163,8 @@ module ActiveRecord
secondary_connection = ActiveRecord::Base.connection_pool.checkout
secondary_connection.query("select pg_terminate_backend(#{original_connection_pid.first.first})")
ActiveRecord::Base.connection_pool.checkin(secondary_connection)
- elsif ARTest.config['with_manual_interventions']
- puts 'Kill the connection now (e.g. by restarting the PostgreSQL ' +
+ elsif ARTest.config["with_manual_interventions"]
+ puts "Kill the connection now (e.g. by restarting the PostgreSQL " \
'server with the "-m fast" option) and then press enter.'
$stdin.gets
else
@@ -172,19 +180,19 @@ module ActiveRecord
# If we get no exception here, then either we re-connected successfully, or
# we never actually got disconnected.
- new_connection_pid = @connection.query('select pg_backend_pid()')
+ new_connection_pid = @connection.query("select pg_backend_pid()")
assert_not_equal original_connection_pid, new_connection_pid,
- "umm -- looks like you didn't break the connection, because we're still " +
+ "umm -- looks like you didn't break the connection, because we're still " \
"successfully querying with the same connection pid."
-
+ ensure
# Repair all fixture connections so other tests won't break.
@fixture_connections.each(&:verify!)
end
def test_set_session_variable_true
run_without_connection do |orig_connection|
- ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => true}}))
+ ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { debug_print_plan: true }))
set_true = ActiveRecord::Base.connection.exec_query "SHOW DEBUG_PRINT_PLAN"
assert_equal set_true.rows, [["on"]]
end
@@ -192,7 +200,7 @@ module ActiveRecord
def test_set_session_variable_false
run_without_connection do |orig_connection|
- ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => false}}))
+ ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { debug_print_plan: false }))
set_false = ActiveRecord::Base.connection.exec_query "SHOW DEBUG_PRINT_PLAN"
assert_equal set_false.rows, [["off"]]
end
@@ -201,14 +209,21 @@ module ActiveRecord
def test_set_session_variable_nil
run_without_connection do |orig_connection|
# This should be a no-op that does not raise an error
- ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => nil}}))
+ ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { debug_print_plan: nil }))
end
end
def test_set_session_variable_default
run_without_connection do |orig_connection|
# This should execute a query that does not raise an error
- ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => :default}}))
+ ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { debug_print_plan: :default }))
+ end
+ end
+
+ def test_set_session_timezone
+ run_without_connection do |orig_connection|
+ ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { timezone: "America/New_York" }))
+ assert_equal "America/New_York", ActiveRecord::Base.connection.query_value("SHOW TIME ZONE")
end
end
@@ -224,14 +239,14 @@ module ActiveRecord
got_lock = @connection.get_advisory_lock(lock_id)
assert got_lock, "get_advisory_lock should have returned true but it didn't"
- advisory_lock = @connection.query(list_advisory_locks).find {|l| l[1] == lock_id}
+ advisory_lock = @connection.query(list_advisory_locks).find { |l| l[1] == lock_id }
assert advisory_lock,
"expected to find an advisory lock with lock_id #{lock_id} but there wasn't one"
released_lock = @connection.release_advisory_lock(lock_id)
assert released_lock, "expected release_advisory_lock to return true but it didn't"
- advisory_locks = @connection.query(list_advisory_locks).select {|l| l[1] == lock_id}
+ advisory_locks = @connection.query(list_advisory_locks).select { |l| l[1] == lock_id }
assert_empty advisory_locks,
"expected to have released advisory lock with lock_id #{lock_id} but it was still held"
end
@@ -241,17 +256,17 @@ module ActiveRecord
with_warning_suppression do
released_non_existent_lock = @connection.release_advisory_lock(fake_lock_id)
assert_equal released_non_existent_lock, false,
- 'expected release_advisory_lock to return false when there was no lock to release'
+ "expected release_advisory_lock to return false when there was no lock to release"
end
end
- protected
+ private
- def with_warning_suppression
- log_level = @connection.client_min_messages
- @connection.client_min_messages = 'error'
- yield
- @connection.client_min_messages = log_level
- end
+ def with_warning_suppression
+ log_level = @connection.client_min_messages
+ @connection.client_min_messages = "error"
+ yield
+ @connection.client_min_messages = log_level
+ end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
index 232c25cb3b..b7535d5c9a 100644
--- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
@@ -1,6 +1,7 @@
-require "cases/helper"
-require 'support/ddl_helper'
+# frozen_string_literal: true
+require "cases/helper"
+require "support/ddl_helper"
class PostgresqlTime < ActiveRecord::Base
end
@@ -29,17 +30,17 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase
end
def test_data_type_of_time_types
- assert_equal :string, @first_time.column_for_attribute(:time_interval).type
- assert_equal :string, @first_time.column_for_attribute(:scaled_time_interval).type
+ assert_equal :interval, @first_time.column_for_attribute(:time_interval).type
+ assert_equal :interval, @first_time.column_for_attribute(:scaled_time_interval).type
end
def test_data_type_of_oid_types
- assert_equal :integer, @first_oid.column_for_attribute(:obj_id).type
+ assert_equal :oid, @first_oid.column_for_attribute(:obj_id).type
end
def test_time_values
- assert_equal '-1 years -2 days', @first_time.time_interval
- assert_equal '-21 days', @first_time.scaled_time_interval
+ assert_equal "-1 years -2 days", @first_time.time_interval
+ assert_equal "-21 days", @first_time.scaled_time_interval
end
def test_oid_values
@@ -47,10 +48,10 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase
end
def test_update_time
- @first_time.time_interval = '2 years 3 minutes'
+ @first_time.time_interval = "2 years 3 minutes"
assert @first_time.save
assert @first_time.reload
- assert_equal '2 years 00:03:00', @first_time.time_interval
+ assert_equal "2 years 00:03:00", @first_time.time_interval
end
def test_update_oid
@@ -62,9 +63,9 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase
end
def test_text_columns_are_limitless_the_upper_limit_is_one_GB
- assert_equal 'text', @connection.type_to_sql(:text, 100_000)
+ assert_equal "text", @connection.type_to_sql(:text, limit: 100_000)
assert_raise ActiveRecord::ActiveRecordError do
- @connection.type_to_sql :text, 4294967295
+ @connection.type_to_sql(:text, limit: 4294967295)
end
end
end
@@ -77,15 +78,15 @@ class PostgresqlInternalDataTypeTest < ActiveRecord::PostgreSQLTestCase
end
def test_name_column_type
- with_example_table @connection, 'ex', 'data name' do
- column = @connection.columns('ex').find { |col| col.name == 'data' }
+ with_example_table @connection, "ex", "data name" do
+ column = @connection.columns("ex").find { |col| col.name == "data" }
assert_equal :string, column.type
end
end
def test_char_column_type
- with_example_table @connection, 'ex', 'data "char"' do
- column = @connection.columns('ex').find { |col| col.name == 'data' }
+ with_example_table @connection, "ex", 'data "char"' do
+ column = @connection.columns("ex").find { |col| col.name == "data" }
assert_equal :string, column.type
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/domain_test.rb b/activerecord/test/cases/adapters/postgresql/domain_test.rb
index 6102ddacd1..dafbc0a3db 100644
--- a/activerecord/test/cases/adapters/postgresql/domain_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/domain_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/connection_helper'
+require "support/connection_helper"
class PostgresqlDomainTest < ActiveRecord::PostgreSQLTestCase
include ConnectionHelper
@@ -12,15 +14,15 @@ class PostgresqlDomainTest < ActiveRecord::PostgreSQLTestCase
@connection = ActiveRecord::Base.connection
@connection.transaction do
@connection.execute "CREATE DOMAIN custom_money as numeric(8,2)"
- @connection.create_table('postgresql_domains') do |t|
+ @connection.create_table("postgresql_domains") do |t|
t.column :price, :custom_money
end
end
end
teardown do
- @connection.drop_table 'postgresql_domains', if_exists: true
- @connection.execute 'DROP DOMAIN IF EXISTS custom_money'
+ @connection.drop_table "postgresql_domains", if_exists: true
+ @connection.execute "DROP DOMAIN IF EXISTS custom_money"
reset_connection
end
@@ -42,6 +44,6 @@ class PostgresqlDomainTest < ActiveRecord::PostgreSQLTestCase
record.price = "34.15"
record.save!
- assert_equal BigDecimal.new("34.15"), record.reload.price
+ assert_equal BigDecimal("34.15"), record.reload.price
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb
index 6816a6514b..3d3cbe11a3 100644
--- a/activerecord/test/cases/adapters/postgresql/enum_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/connection_helper'
+require "support/connection_helper"
class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase
include ConnectionHelper
@@ -14,15 +16,15 @@ class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase
@connection.execute <<-SQL
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
SQL
- @connection.create_table('postgresql_enums') do |t|
+ @connection.create_table("postgresql_enums") do |t|
t.column :current_mood, :mood
end
end
end
teardown do
- @connection.drop_table 'postgresql_enums', if_exists: true
- @connection.execute 'DROP TYPE IF EXISTS mood'
+ @connection.drop_table "postgresql_enums", if_exists: true
+ @connection.execute "DROP TYPE IF EXISTS mood"
reset_connection
end
@@ -37,10 +39,10 @@ class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase
end
def test_enum_defaults
- @connection.add_column 'postgresql_enums', 'good_mood', :mood, default: 'happy'
+ @connection.add_column "postgresql_enums", "good_mood", :mood, default: "happy"
PostgresqlEnum.reset_column_information
- assert_equal "happy", PostgresqlEnum.column_defaults['good_mood']
+ assert_equal "happy", PostgresqlEnum.column_defaults["good_mood"]
assert_equal "happy", PostgresqlEnum.new.good_mood
ensure
PostgresqlEnum.reset_column_information
diff --git a/activerecord/test/cases/adapters/postgresql/explain_test.rb b/activerecord/test/cases/adapters/postgresql/explain_test.rb
index 29bf2c15ea..be525383e9 100644
--- a/activerecord/test/cases/adapters/postgresql/explain_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/explain_test.rb
@@ -1,20 +1,22 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'models/developer'
-require 'models/computer'
+require "models/author"
+require "models/post"
class PostgreSQLExplainTest < ActiveRecord::PostgreSQLTestCase
- fixtures :developers
+ fixtures :authors
def test_explain_for_one_query
- explain = Developer.where(id: 1).explain
- assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = \$?1), explain
+ explain = Author.where(id: 1).explain
+ assert_match %r(EXPLAIN for: SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
assert_match %(QUERY PLAN), explain
end
def test_explain_with_eager_loading
- explain = Developer.where(id: 1).includes(:audit_logs).explain
+ explain = Author.where(id: 1).includes(:posts).explain
assert_match %(QUERY PLAN), explain
- assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = \$?1), explain
- assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" = 1), explain
+ assert_match %r(EXPLAIN for: SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
+ assert_match %r(EXPLAIN for: SELECT "posts"\.\* FROM "posts" WHERE "posts"\."author_id" = (?:\$1 \[\["author_id", 1\]\]|1)), explain
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb b/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
index b56c226763..df97ab11e7 100644
--- a/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cases/helper"
class PostgresqlExtensionMigrationTest < ActiveRecord::PostgreSQLTestCase
@@ -20,10 +22,6 @@ class PostgresqlExtensionMigrationTest < ActiveRecord::PostgreSQLTestCase
@connection = ActiveRecord::Base.connection
- unless @connection.supports_extensions?
- return skip("no extension support")
- end
-
@old_schema_migration_table_name = ActiveRecord::SchemaMigration.table_name
@old_table_name_prefix = ActiveRecord::Base.table_name_prefix
@old_table_name_suffix = ActiveRecord::Base.table_name_suffix
diff --git a/activerecord/test/cases/adapters/postgresql/full_text_test.rb b/activerecord/test/cases/adapters/postgresql/full_text_test.rb
index bde7513339..c6f1e1727f 100644
--- a/activerecord/test/cases/adapters/postgresql/full_text_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/full_text_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
class PostgresqlFullTextTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
@@ -7,13 +9,13 @@ class PostgresqlFullTextTest < ActiveRecord::PostgreSQLTestCase
setup do
@connection = ActiveRecord::Base.connection
- @connection.create_table('tsvectors') do |t|
- t.tsvector 'text_vector'
+ @connection.create_table("tsvectors") do |t|
+ t.tsvector "text_vector"
end
end
teardown do
- @connection.drop_table 'tsvectors', if_exists: true
+ @connection.drop_table "tsvectors", if_exists: true
end
def test_tsvector_column
diff --git a/activerecord/test/cases/adapters/postgresql/geometric_test.rb b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
index 9e250c2b7c..e1ba00e07b 100644
--- a/activerecord/test/cases/adapters/postgresql/geometric_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/connection_helper'
-require 'support/schema_dumping_helper'
+require "support/connection_helper"
+require "support/schema_dumping_helper"
class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
include ConnectionHelper
@@ -18,7 +20,7 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
def setup
@connection = ActiveRecord::Base.connection
- @connection.create_table('postgresql_points') do |t|
+ @connection.create_table("postgresql_points") do |t|
t.point :x
t.point :y, default: [12.2, 13.3]
t.point :z, default: "(14.4,15.5)"
@@ -27,22 +29,10 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
t.point :legacy_y, default: [12.2, 13.3]
t.point :legacy_z, default: "(14.4,15.5)"
end
- @connection.create_table('deprecated_points') do |t|
- t.point :x
- end
end
teardown do
- @connection.drop_table 'postgresql_points', if_exists: true
- @connection.drop_table 'deprecated_points', if_exists: true
- end
-
- class DeprecatedPoint < ActiveRecord::Base; end
-
- def test_deprecated_legacy_type
- assert_deprecated do
- DeprecatedPoint.new
- end
+ @connection.drop_table "postgresql_points", if_exists: true
end
def test_column
@@ -56,10 +46,10 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
end
def test_default
- assert_equal ActiveRecord::Point.new(12.2, 13.3), PostgresqlPoint.column_defaults['y']
+ assert_equal ActiveRecord::Point.new(12.2, 13.3), PostgresqlPoint.column_defaults["y"]
assert_equal ActiveRecord::Point.new(12.2, 13.3), PostgresqlPoint.new.y
- assert_equal ActiveRecord::Point.new(14.4, 15.5), PostgresqlPoint.column_defaults['z']
+ assert_equal ActiveRecord::Point.new(14.4, 15.5), PostgresqlPoint.column_defaults["z"]
assert_equal ActiveRecord::Point.new(14.4, 15.5), PostgresqlPoint.new.z
end
@@ -104,6 +94,11 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
assert_equal ActiveRecord::Point.new(1, 2), p.x
end
+ def test_empty_string_assignment
+ p = PostgresqlPoint.new(x: "")
+ assert_nil p.x
+ end
+
def test_array_of_points_round_trip
expected_value = [
ActiveRecord::Point.new(1, 2),
@@ -129,10 +124,10 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
end
def test_legacy_default
- assert_equal [12.2, 13.3], PostgresqlPoint.column_defaults['legacy_y']
+ assert_equal [12.2, 13.3], PostgresqlPoint.column_defaults["legacy_y"]
assert_equal [12.2, 13.3], PostgresqlPoint.new.legacy_y
- assert_equal [14.4, 15.5], PostgresqlPoint.column_defaults['legacy_z']
+ assert_equal [14.4, 15.5], PostgresqlPoint.column_defaults["legacy_z"]
assert_equal [14.4, 15.5], PostgresqlPoint.new.legacy_z
end
@@ -183,51 +178,51 @@ class PostgresqlGeometricTest < ActiveRecord::PostgreSQLTestCase
end
teardown do
- @connection.drop_table 'postgresql_geometrics', if_exists: true
+ @connection.drop_table "postgresql_geometrics", if_exists: true
end
def test_geometric_types
g = PostgresqlGeometric.new(
- :a_line_segment => '(2.0, 3), (5.5, 7.0)',
- :a_box => '2.0, 3, 5.5, 7.0',
- :a_path => '[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]',
- :a_polygon => '((2.0, 3), (5.5, 7.0), (8.5, 11.0))',
- :a_circle => '<(5.3, 10.4), 2>'
+ a_line_segment: "(2.0, 3), (5.5, 7.0)",
+ a_box: "2.0, 3, 5.5, 7.0",
+ a_path: "[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]",
+ a_polygon: "((2.0, 3), (5.5, 7.0), (8.5, 11.0))",
+ a_circle: "<(5.3, 10.4), 2>"
)
g.save!
h = PostgresqlGeometric.find(g.id)
- assert_equal '[(2,3),(5.5,7)]', h.a_line_segment
- assert_equal '(5.5,7),(2,3)', h.a_box # reordered to store upper right corner then bottom left corner
- assert_equal '[(2,3),(5.5,7),(8.5,11)]', h.a_path
- assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_polygon
- assert_equal '<(5.3,10.4),2>', h.a_circle
+ assert_equal "[(2,3),(5.5,7)]", h.a_line_segment
+ assert_equal "(5.5,7),(2,3)", h.a_box # reordered to store upper right corner then bottom left corner
+ assert_equal "[(2,3),(5.5,7),(8.5,11)]", h.a_path
+ assert_equal "((2,3),(5.5,7),(8.5,11))", h.a_polygon
+ assert_equal "<(5.3,10.4),2>", h.a_circle
end
def test_alternative_format
g = PostgresqlGeometric.new(
- :a_line_segment => '((2.0, 3), (5.5, 7.0))',
- :a_box => '(2.0, 3), (5.5, 7.0)',
- :a_path => '((2.0, 3), (5.5, 7.0), (8.5, 11.0))',
- :a_polygon => '2.0, 3, 5.5, 7.0, 8.5, 11.0',
- :a_circle => '((5.3, 10.4), 2)'
+ a_line_segment: "((2.0, 3), (5.5, 7.0))",
+ a_box: "(2.0, 3), (5.5, 7.0)",
+ a_path: "((2.0, 3), (5.5, 7.0), (8.5, 11.0))",
+ a_polygon: "2.0, 3, 5.5, 7.0, 8.5, 11.0",
+ a_circle: "((5.3, 10.4), 2)"
)
g.save!
h = PostgresqlGeometric.find(g.id)
- assert_equal '[(2,3),(5.5,7)]', h.a_line_segment
- assert_equal '(5.5,7),(2,3)', h.a_box # reordered to store upper right corner then bottom left corner
- assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_path
- assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_polygon
- assert_equal '<(5.3,10.4),2>', h.a_circle
+ assert_equal "[(2,3),(5.5,7)]", h.a_line_segment
+ assert_equal "(5.5,7),(2,3)", h.a_box # reordered to store upper right corner then bottom left corner
+ assert_equal "((2,3),(5.5,7),(8.5,11))", h.a_path
+ assert_equal "((2,3),(5.5,7),(8.5,11))", h.a_polygon
+ assert_equal "<(5.3,10.4),2>", h.a_circle
end
def test_geometric_function
- PostgresqlGeometric.create! a_path: '[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]' # [ ] is an open path
- PostgresqlGeometric.create! a_path: '((2.0, 3), (5.5, 7.0), (8.5, 11.0))' # ( ) is a closed path
+ PostgresqlGeometric.create! a_path: "[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]" # [ ] is an open path
+ PostgresqlGeometric.create! a_path: "((2.0, 3), (5.5, 7.0), (8.5, 11.0))" # ( ) is a closed path
objs = PostgresqlGeometric.find_by_sql "SELECT isopen(a_path) FROM postgresql_geometrics ORDER BY id ASC"
assert_equal [true, false], objs.map(&:isopen)
@@ -263,28 +258,28 @@ class PostgreSQLGeometricLineTest < ActiveRecord::PostgreSQLTestCase
teardown do
if defined?(@connection)
- @connection.drop_table 'postgresql_lines', if_exists: true
+ @connection.drop_table "postgresql_lines", if_exists: true
end
end
def test_geometric_line_type
g = PostgresqlLine.new(
- a_line: '{2.0, 3, 5.5}'
+ a_line: "{2.0, 3, 5.5}"
)
g.save!
h = PostgresqlLine.find(g.id)
- assert_equal '{2,3,5.5}', h.a_line
+ assert_equal "{2,3,5.5}", h.a_line
end
def test_alternative_format_line_type
g = PostgresqlLine.new(
- a_line: '(2.0, 3), (4.0, 6.0)'
+ a_line: "(2.0, 3), (4.0, 6.0)"
)
g.save!
h = PostgresqlLine.find(g.id)
- assert_equal '{1.5,-1,0}', h.a_line
+ assert_equal "{1.5,-1,0}", h.a_line
end
def test_schema_dumping_for_line_type
@@ -367,12 +362,12 @@ class PostgreSQLGeometricTypesTest < ActiveRecord::PostgreSQLTestCase
private
- def assert_column_exists(column_name)
- assert connection.column_exists?(table_name, column_name)
- end
+ def assert_column_exists(column_name)
+ assert connection.column_exists?(table_name, column_name)
+ end
- def assert_type_correct(column_name, type)
- column = connection.columns(table_name).find { |c| c.name == column_name.to_s }
- assert_equal type, column.type
- end
+ def assert_type_correct(column_name, type)
+ column = connection.columns(table_name).find { |c| c.name == column_name.to_s }
+ assert_equal type, column.type
+ end
end
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index 27cc65a643..f09e34b5f2 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -1,327 +1,353 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
-if ActiveRecord::Base.connection.supports_extensions?
- class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
- include SchemaDumpingHelper
- class Hstore < ActiveRecord::Base
- self.table_name = 'hstores'
+class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
+ include SchemaDumpingHelper
+ class Hstore < ActiveRecord::Base
+ self.table_name = "hstores"
- store_accessor :settings, :language, :timezone
- end
+ store_accessor :settings, :language, :timezone
+ end
- def setup
- @connection = ActiveRecord::Base.connection
+ class FakeParameters
+ def to_unsafe_h
+ { "hi" => "hi" }
+ end
+ end
- unless @connection.extension_enabled?('hstore')
- @connection.enable_extension 'hstore'
- @connection.commit_db_transaction
- end
+ def setup
+ @connection = ActiveRecord::Base.connection
- @connection.reconnect!
+ enable_extension!("hstore", @connection)
- @connection.transaction do
- @connection.create_table('hstores') do |t|
- t.hstore 'tags', :default => ''
- t.hstore 'payload', array: true
- t.hstore 'settings'
- end
+ @connection.transaction do
+ @connection.create_table("hstores") do |t|
+ t.hstore "tags", default: ""
+ t.hstore "payload", array: true
+ t.hstore "settings"
end
- Hstore.reset_column_information
- @column = Hstore.columns_hash['tags']
- @type = Hstore.type_for_attribute("tags")
- end
-
- teardown do
- @connection.drop_table 'hstores', if_exists: true
end
+ Hstore.reset_column_information
+ @column = Hstore.columns_hash["tags"]
+ @type = Hstore.type_for_attribute("tags")
+ end
- def test_hstore_included_in_extensions
- assert @connection.respond_to?(:extensions), "connection should have a list of extensions"
- assert @connection.extensions.include?('hstore'), "extension list should include hstore"
- end
+ teardown do
+ @connection.drop_table "hstores", if_exists: true
+ disable_extension!("hstore", @connection)
+ end
- def test_disable_enable_hstore
- assert @connection.extension_enabled?('hstore')
- @connection.disable_extension 'hstore'
- assert_not @connection.extension_enabled?('hstore')
- @connection.enable_extension 'hstore'
- assert @connection.extension_enabled?('hstore')
- ensure
- # Restore column(s) dropped by `drop extension hstore cascade;`
- load_schema
- end
+ def test_hstore_included_in_extensions
+ assert @connection.respond_to?(:extensions), "connection should have a list of extensions"
+ assert_includes @connection.extensions, "hstore", "extension list should include hstore"
+ end
- def test_column
- assert_equal :hstore, @column.type
- assert_equal "hstore", @column.sql_type
- assert_not @column.array?
+ def test_disable_enable_hstore
+ assert @connection.extension_enabled?("hstore")
+ @connection.disable_extension "hstore"
+ assert_not @connection.extension_enabled?("hstore")
+ @connection.enable_extension "hstore"
+ assert @connection.extension_enabled?("hstore")
+ ensure
+ # Restore column(s) dropped by `drop extension hstore cascade;`
+ load_schema
+ end
- assert_not @type.binary?
- end
+ def test_column
+ assert_equal :hstore, @column.type
+ assert_equal "hstore", @column.sql_type
+ assert_not @column.array?
- def test_default
- @connection.add_column 'hstores', 'permissions', :hstore, default: '"users"=>"read", "articles"=>"write"'
- Hstore.reset_column_information
+ assert_not @type.binary?
+ end
- assert_equal({"users"=>"read", "articles"=>"write"}, Hstore.column_defaults['permissions'])
- assert_equal({"users"=>"read", "articles"=>"write"}, Hstore.new.permissions)
- ensure
- Hstore.reset_column_information
- end
+ def test_default
+ @connection.add_column "hstores", "permissions", :hstore, default: '"users"=>"read", "articles"=>"write"'
+ Hstore.reset_column_information
- def test_change_table_supports_hstore
- @connection.transaction do
- @connection.change_table('hstores') do |t|
- t.hstore 'users', default: ''
- end
- Hstore.reset_column_information
- column = Hstore.columns_hash['users']
- assert_equal :hstore, column.type
+ assert_equal({ "users" => "read", "articles" => "write" }, Hstore.column_defaults["permissions"])
+ assert_equal({ "users" => "read", "articles" => "write" }, Hstore.new.permissions)
+ ensure
+ Hstore.reset_column_information
+ end
- raise ActiveRecord::Rollback # reset the schema change
+ def test_change_table_supports_hstore
+ @connection.transaction do
+ @connection.change_table("hstores") do |t|
+ t.hstore "users", default: ""
end
- ensure
Hstore.reset_column_information
+ column = Hstore.columns_hash["users"]
+ assert_equal :hstore, column.type
+
+ raise ActiveRecord::Rollback # reset the schema change
end
+ ensure
+ Hstore.reset_column_information
+ end
- def test_hstore_migration
- hstore_migration = Class.new(ActiveRecord::Migration::Current) do
- def change
- change_table("hstores") do |t|
- t.hstore :keys
- end
+ def test_hstore_migration
+ hstore_migration = Class.new(ActiveRecord::Migration::Current) do
+ def change
+ change_table("hstores") do |t|
+ t.hstore :keys
end
end
-
- hstore_migration.new.suppress_messages do
- hstore_migration.migrate(:up)
- assert_includes @connection.columns(:hstores).map(&:name), "keys"
- hstore_migration.migrate(:down)
- assert_not_includes @connection.columns(:hstores).map(&:name), "keys"
- end
end
- def test_cast_value_on_write
- x = Hstore.new tags: {"bool" => true, "number" => 5}
- assert_equal({"bool" => true, "number" => 5}, x.tags_before_type_cast)
- assert_equal({"bool" => "true", "number" => "5"}, x.tags)
- x.save
- assert_equal({"bool" => "true", "number" => "5"}, x.reload.tags)
+ hstore_migration.new.suppress_messages do
+ hstore_migration.migrate(:up)
+ assert_includes @connection.columns(:hstores).map(&:name), "keys"
+ hstore_migration.migrate(:down)
+ assert_not_includes @connection.columns(:hstores).map(&:name), "keys"
end
+ end
- def test_type_cast_hstore
- assert_equal({'1' => '2'}, @type.deserialize("\"1\"=>\"2\""))
- assert_equal({}, @type.deserialize(""))
- assert_equal({'key'=>nil}, @type.deserialize('key => NULL'))
- assert_equal({'c'=>'}','"a"'=>'b "a b'}, @type.deserialize(%q(c=>"}", "\"a\""=>"b \"a b")))
- end
+ def test_cast_value_on_write
+ x = Hstore.new tags: { "bool" => true, "number" => 5 }
+ assert_equal({ "bool" => true, "number" => 5 }, x.tags_before_type_cast)
+ assert_equal({ "bool" => "true", "number" => "5" }, x.tags)
+ x.save
+ assert_equal({ "bool" => "true", "number" => "5" }, x.reload.tags)
+ end
- def test_with_store_accessors
- x = Hstore.new(language: "fr", timezone: "GMT")
- assert_equal "fr", x.language
- assert_equal "GMT", x.timezone
+ def test_type_cast_hstore
+ assert_equal({ "1" => "2" }, @type.deserialize("\"1\"=>\"2\""))
+ assert_equal({}, @type.deserialize(""))
+ assert_equal({ "key" => nil }, @type.deserialize("key => NULL"))
+ assert_equal({ "c" => "}", '"a"' => 'b "a b' }, @type.deserialize(%q(c=>"}", "\"a\""=>"b \"a b")))
+ end
- x.save!
- x = Hstore.first
- assert_equal "fr", x.language
- assert_equal "GMT", x.timezone
+ def test_with_store_accessors
+ x = Hstore.new(language: "fr", timezone: "GMT")
+ assert_equal "fr", x.language
+ assert_equal "GMT", x.timezone
- x.language = "de"
- x.save!
+ x.save!
+ x = Hstore.first
+ assert_equal "fr", x.language
+ assert_equal "GMT", x.timezone
- x = Hstore.first
- assert_equal "de", x.language
- assert_equal "GMT", x.timezone
- end
+ x.language = "de"
+ x.save!
- def test_duplication_with_store_accessors
- x = Hstore.new(language: "fr", timezone: "GMT")
- assert_equal "fr", x.language
- assert_equal "GMT", x.timezone
+ x = Hstore.first
+ assert_equal "de", x.language
+ assert_equal "GMT", x.timezone
+ end
- y = x.dup
- assert_equal "fr", y.language
- assert_equal "GMT", y.timezone
- end
+ def test_duplication_with_store_accessors
+ x = Hstore.new(language: "fr", timezone: "GMT")
+ assert_equal "fr", x.language
+ assert_equal "GMT", x.timezone
- def test_yaml_round_trip_with_store_accessors
- x = Hstore.new(language: "fr", timezone: "GMT")
- assert_equal "fr", x.language
- assert_equal "GMT", x.timezone
+ y = x.dup
+ assert_equal "fr", y.language
+ assert_equal "GMT", y.timezone
+ end
- y = YAML.load(YAML.dump(x))
- assert_equal "fr", y.language
- assert_equal "GMT", y.timezone
- end
+ def test_yaml_round_trip_with_store_accessors
+ x = Hstore.new(language: "fr", timezone: "GMT")
+ assert_equal "fr", x.language
+ assert_equal "GMT", x.timezone
- def test_changes_in_place
- hstore = Hstore.create!(settings: { 'one' => 'two' })
- hstore.settings['three'] = 'four'
- hstore.save!
- hstore.reload
+ y = YAML.load(YAML.dump(x))
+ assert_equal "fr", y.language
+ assert_equal "GMT", y.timezone
+ end
- assert_equal 'four', hstore.settings['three']
- assert_not hstore.changed?
- end
+ def test_changes_in_place
+ hstore = Hstore.create!(settings: { "one" => "two" })
+ hstore.settings["three"] = "four"
+ hstore.save!
+ hstore.reload
- def test_gen1
- assert_equal(%q(" "=>""), @type.serialize({' '=>''}))
- end
+ assert_equal "four", hstore.settings["three"]
+ assert_not hstore.changed?
+ end
- def test_gen2
- assert_equal(%q(","=>""), @type.serialize({','=>''}))
- end
+ def test_dirty_from_user_equal
+ settings = { "alongkey" => "anything", "key" => "value" }
+ hstore = Hstore.create!(settings: settings)
- def test_gen3
- assert_equal(%q("="=>""), @type.serialize({'='=>''}))
- end
+ hstore.settings = { "key" => "value", "alongkey" => "anything" }
+ assert_equal settings, hstore.settings
+ refute hstore.changed?
+ end
- def test_gen4
- assert_equal(%q(">"=>""), @type.serialize({'>'=>''}))
- end
+ def test_hstore_dirty_from_database_equal
+ settings = { "alongkey" => "anything", "key" => "value" }
+ hstore = Hstore.create!(settings: settings)
+ hstore.reload
- def test_parse1
- assert_equal({'a'=>nil,'b'=>nil,'c'=>'NuLl','null'=>'c'}, @type.deserialize('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
- end
+ assert_equal settings, hstore.settings
+ hstore.settings = settings
+ refute hstore.changed?
+ end
- def test_parse2
- assert_equal({" " => " "}, @type.deserialize("\\ =>\\ "))
- end
+ def test_gen1
+ assert_equal('" "=>""', @type.serialize(" " => ""))
+ end
- def test_parse3
- assert_equal({"=" => ">"}, @type.deserialize("==>>"))
- end
+ def test_gen2
+ assert_equal('","=>""', @type.serialize("," => ""))
+ end
- def test_parse4
- assert_equal({"=a"=>"q=w"}, @type.deserialize('\=a=>q=w'))
- end
+ def test_gen3
+ assert_equal('"="=>""', @type.serialize("=" => ""))
+ end
- def test_parse5
- assert_equal({"=a"=>"q=w"}, @type.deserialize('"=a"=>q\=w'))
- end
+ def test_gen4
+ assert_equal('">"=>""', @type.serialize(">" => ""))
+ end
- def test_parse6
- assert_equal({"\"a"=>"q>w"}, @type.deserialize('"\"a"=>q>w'))
- end
+ def test_parse1
+ assert_equal({ "a" => nil, "b" => nil, "c" => "NuLl", "null" => "c" }, @type.deserialize('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
+ end
- def test_parse7
- assert_equal({"\"a"=>"q\"w"}, @type.deserialize('\"a=>q"w'))
- end
+ def test_parse2
+ assert_equal({ " " => " " }, @type.deserialize("\\ =>\\ "))
+ end
- def test_rewrite
- @connection.execute "insert into hstores (tags) VALUES ('1=>2')"
- x = Hstore.first
- x.tags = { '"a\'' => 'b' }
- assert x.save!
- end
+ def test_parse3
+ assert_equal({ "=" => ">" }, @type.deserialize("==>>"))
+ end
- def test_select
- @connection.execute "insert into hstores (tags) VALUES ('1=>2')"
- x = Hstore.first
- assert_equal({'1' => '2'}, x.tags)
- end
+ def test_parse4
+ assert_equal({ "=a" => "q=w" }, @type.deserialize('\=a=>q=w'))
+ end
- def test_array_cycle
- assert_array_cycle([{"AA" => "BB", "CC" => "DD"}, {"AA" => nil}])
- end
+ def test_parse5
+ assert_equal({ "=a" => "q=w" }, @type.deserialize('"=a"=>q\=w'))
+ end
- def test_array_strings_with_quotes
- assert_array_cycle([{'this has' => 'some "s that need to be escaped"'}])
- end
+ def test_parse6
+ assert_equal({ "\"a" => "q>w" }, @type.deserialize('"\"a"=>q>w'))
+ end
- def test_array_strings_with_commas
- assert_array_cycle([{'this,has' => 'many,values'}])
- end
+ def test_parse7
+ assert_equal({ "\"a" => "q\"w" }, @type.deserialize('\"a=>q"w'))
+ end
- def test_array_strings_with_array_delimiters
- assert_array_cycle(['{' => '}'])
- end
+ def test_rewrite
+ @connection.execute "insert into hstores (tags) VALUES ('1=>2')"
+ x = Hstore.first
+ x.tags = { '"a\'' => "b" }
+ assert x.save!
+ end
- def test_array_strings_with_null_strings
- assert_array_cycle([{'NULL' => 'NULL'}])
- end
+ def test_select
+ @connection.execute "insert into hstores (tags) VALUES ('1=>2')"
+ x = Hstore.first
+ assert_equal({ "1" => "2" }, x.tags)
+ end
- def test_contains_nils
- assert_array_cycle([{'NULL' => nil}])
- end
+ def test_array_cycle
+ assert_array_cycle([{ "AA" => "BB", "CC" => "DD" }, { "AA" => nil }])
+ end
- def test_select_multikey
- @connection.execute "insert into hstores (tags) VALUES ('1=>2,2=>3')"
- x = Hstore.first
- assert_equal({'1' => '2', '2' => '3'}, x.tags)
- end
+ def test_array_strings_with_quotes
+ assert_array_cycle([{ "this has" => 'some "s that need to be escaped"' }])
+ end
- def test_create
- assert_cycle('a' => 'b', '1' => '2')
- end
+ def test_array_strings_with_commas
+ assert_array_cycle([{ "this,has" => "many,values" }])
+ end
- def test_nil
- assert_cycle('a' => nil)
- end
+ def test_array_strings_with_array_delimiters
+ assert_array_cycle(["{" => "}"])
+ end
- def test_quotes
- assert_cycle('a' => 'b"ar', '1"foo' => '2')
- end
+ def test_array_strings_with_null_strings
+ assert_array_cycle([{ "NULL" => "NULL" }])
+ end
- def test_whitespace
- assert_cycle('a b' => 'b ar', '1"foo' => '2')
- end
+ def test_contains_nils
+ assert_array_cycle([{ "NULL" => nil }])
+ end
- def test_backslash
- assert_cycle('a\\b' => 'b\\ar', '1"foo' => '2')
- end
+ def test_select_multikey
+ @connection.execute "insert into hstores (tags) VALUES ('1=>2,2=>3')"
+ x = Hstore.first
+ assert_equal({ "1" => "2", "2" => "3" }, x.tags)
+ end
- def test_comma
- assert_cycle('a, b' => 'bar', '1"foo' => '2')
- end
+ def test_create
+ assert_cycle("a" => "b", "1" => "2")
+ end
- def test_arrow
- assert_cycle('a=>b' => 'bar', '1"foo' => '2')
- end
+ def test_nil
+ assert_cycle("a" => nil)
+ end
- def test_quoting_special_characters
- assert_cycle('ca' => 'cà', 'ac' => 'àc')
- end
+ def test_quotes
+ assert_cycle("a" => 'b"ar', '1"foo' => "2")
+ end
- def test_multiline
- assert_cycle("a\nb" => "c\nd")
- end
+ def test_whitespace
+ assert_cycle("a b" => "b ar", '1"foo' => "2")
+ end
- class TagCollection
- def initialize(hash); @hash = hash end
- def to_hash; @hash end
- def self.load(hash); new(hash) end
- def self.dump(object); object.to_hash end
- end
+ def test_backslash
+ assert_cycle('a\\b' => 'b\\ar', '1"foo' => "2")
+ end
- class HstoreWithSerialize < Hstore
- serialize :tags, TagCollection
- end
+ def test_comma
+ assert_cycle("a, b" => "bar", '1"foo' => "2")
+ end
- def test_hstore_with_serialized_attributes
- HstoreWithSerialize.create! tags: TagCollection.new({"one" => "two"})
- record = HstoreWithSerialize.first
- assert_instance_of TagCollection, record.tags
- assert_equal({"one" => "two"}, record.tags.to_hash)
- record.tags = TagCollection.new("three" => "four")
- record.save!
- assert_equal({"three" => "four"}, HstoreWithSerialize.first.tags.to_hash)
- end
+ def test_arrow
+ assert_cycle("a=>b" => "bar", '1"foo' => "2")
+ end
- def test_clone_hstore_with_serialized_attributes
- HstoreWithSerialize.create! tags: TagCollection.new({"one" => "two"})
- record = HstoreWithSerialize.first
- dupe = record.dup
- assert_equal({"one" => "two"}, dupe.tags.to_hash)
- end
+ def test_quoting_special_characters
+ assert_cycle("ca" => "cà", "ac" => "àc")
+ end
- def test_schema_dump_with_shorthand
- output = dump_table_schema("hstores")
- assert_match %r[t\.hstore "tags",\s+default: {}], output
- end
+ def test_multiline
+ assert_cycle("a\nb" => "c\nd")
+ end
+
+ class TagCollection
+ def initialize(hash); @hash = hash end
+ def to_hash; @hash end
+ def self.load(hash); new(hash) end
+ def self.dump(object); object.to_hash end
+ end
+
+ class HstoreWithSerialize < Hstore
+ serialize :tags, TagCollection
+ end
+
+ def test_hstore_with_serialized_attributes
+ HstoreWithSerialize.create! tags: TagCollection.new("one" => "two")
+ record = HstoreWithSerialize.first
+ assert_instance_of TagCollection, record.tags
+ assert_equal({ "one" => "two" }, record.tags.to_hash)
+ record.tags = TagCollection.new("three" => "four")
+ record.save!
+ assert_equal({ "three" => "four" }, HstoreWithSerialize.first.tags.to_hash)
+ end
- private
+ def test_clone_hstore_with_serialized_attributes
+ HstoreWithSerialize.create! tags: TagCollection.new("one" => "two")
+ record = HstoreWithSerialize.first
+ dupe = record.dup
+ assert_equal({ "one" => "two" }, dupe.tags.to_hash)
+ end
+
+ def test_schema_dump_with_shorthand
+ output = dump_table_schema("hstores")
+ assert_match %r[t\.hstore "tags",\s+default: {}], output
+ end
+
+ def test_supports_to_unsafe_h_values
+ assert_equal("\"hi\"=>\"hi\"", @type.serialize(FakeParameters.new))
+ end
+
+ private
def assert_array_cycle(array)
# test creation
x = Hstore.create!(payload: array)
@@ -338,16 +364,15 @@ if ActiveRecord::Base.connection.supports_extensions?
def assert_cycle(hash)
# test creation
- x = Hstore.create!(:tags => hash)
+ x = Hstore.create!(tags: hash)
x.reload
assert_equal(hash, x.tags)
# test updating
- x = Hstore.create!(:tags => {})
+ x = Hstore.create!(tags: {})
x.tags = hash
x.save!
x.reload
assert_equal(hash, x.tags)
end
- end
end
diff --git a/activerecord/test/cases/adapters/postgresql/infinity_test.rb b/activerecord/test/cases/adapters/postgresql/infinity_test.rb
index bfda933fa4..0b18c0c9d7 100644
--- a/activerecord/test/cases/adapters/postgresql/infinity_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/infinity_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cases/helper"
class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase
@@ -15,7 +17,7 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase
end
teardown do
- @connection.drop_table 'postgresql_infinities', if_exists: true
+ @connection.drop_table "postgresql_infinities", if_exists: true
end
test "type casting infinity on a float column" do
@@ -25,12 +27,12 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase
end
test "type casting string on a float column" do
- record = PostgresqlInfinity.new(float: 'Infinity')
+ record = PostgresqlInfinity.new(float: "Infinity")
assert_equal Float::INFINITY, record.float
- record = PostgresqlInfinity.new(float: '-Infinity')
+ record = PostgresqlInfinity.new(float: "-Infinity")
assert_equal(-Float::INFINITY, record.float)
- record = PostgresqlInfinity.new(float: 'NaN')
- assert_send [record.float, :nan?]
+ record = PostgresqlInfinity.new(float: "NaN")
+ assert record.float.nan?, "Expected #{record.float} to be NaN"
end
test "update_all with infinity on a float column" do
diff --git a/activerecord/test/cases/adapters/postgresql/integer_test.rb b/activerecord/test/cases/adapters/postgresql/integer_test.rb
index b4e55964b9..3e45b057ff 100644
--- a/activerecord/test/cases/adapters/postgresql/integer_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/integer_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cases/helper"
require "active_support/core_ext/numeric/bytes"
diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb
index 663de680b5..ee08841eb3 100644
--- a/activerecord/test/cases/adapters/postgresql/json_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/json_test.rb
@@ -1,196 +1,37 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "cases/json_shared_test_cases"
module PostgresqlJSONSharedTestCases
- include SchemaDumpingHelper
-
- class JsonDataType < ActiveRecord::Base
- self.table_name = 'json_data_type'
-
- store_accessor :settings, :resolution
- end
+ include JSONSharedTestCases
def setup
- @connection = ActiveRecord::Base.connection
- begin
- @connection.create_table('json_data_type') do |t|
- t.public_send column_type, 'payload', default: {} # t.json 'payload', default: {}
- t.public_send column_type, 'settings' # t.json 'settings'
- end
- rescue ActiveRecord::StatementInvalid
- skip "do not test on PostgreSQL without #{column_type} type."
+ super
+ @connection.create_table("json_data_type") do |t|
+ t.public_send column_type, "payload", default: {} # t.json 'payload', default: {}
+ t.public_send column_type, "settings" # t.json 'settings'
+ t.public_send column_type, "objects", array: true # t.json 'objects', array: true
end
- end
-
- def teardown
- @connection.drop_table :json_data_type, if_exists: true
- JsonDataType.reset_column_information
- end
-
- def test_column
- column = JsonDataType.columns_hash["payload"]
- assert_equal column_type, column.type
- assert_equal column_type.to_s, column.sql_type
- assert_not column.array?
-
- type = JsonDataType.type_for_attribute("payload")
- assert_not type.binary?
+ rescue ActiveRecord::StatementInvalid
+ skip "do not test on PostgreSQL without #{column_type} type."
end
def test_default
- @connection.add_column 'json_data_type', 'permissions', column_type, default: {"users": "read", "posts": ["read", "write"]}
- JsonDataType.reset_column_information
-
- assert_equal({"users"=>"read", "posts"=>["read", "write"]}, JsonDataType.column_defaults['permissions'])
- assert_equal({"users"=>"read", "posts"=>["read", "write"]}, JsonDataType.new.permissions)
- ensure
- JsonDataType.reset_column_information
- end
-
- def test_change_table_supports_json
- @connection.transaction do
- @connection.change_table('json_data_type') do |t|
- t.public_send column_type, 'users', default: '{}' # t.json 'users', default: '{}'
- end
- JsonDataType.reset_column_information
- column = JsonDataType.columns_hash['users']
- assert_equal column_type, column.type
-
- raise ActiveRecord::Rollback # reset the schema change
- end
- ensure
- JsonDataType.reset_column_information
- end
-
- def test_schema_dumping
- output = dump_table_schema("json_data_type")
- assert_match(/t\.#{column_type.to_s}\s+"payload",\s+default: {}/, output)
- end
-
- def test_cast_value_on_write
- x = JsonDataType.new payload: {"string" => "foo", :symbol => :bar}
- assert_equal({"string" => "foo", :symbol => :bar}, x.payload_before_type_cast)
- assert_equal({"string" => "foo", "symbol" => "bar"}, x.payload)
- x.save
- assert_equal({"string" => "foo", "symbol" => "bar"}, x.reload.payload)
- end
-
- def test_type_cast_json
- type = JsonDataType.type_for_attribute("payload")
-
- data = "{\"a_key\":\"a_value\"}"
- hash = type.deserialize(data)
- assert_equal({'a_key' => 'a_value'}, hash)
- assert_equal({'a_key' => 'a_value'}, type.deserialize(data))
-
- assert_equal({}, type.deserialize("{}"))
- assert_equal({'key'=>nil}, type.deserialize('{"key": null}'))
- assert_equal({'c'=>'}','"a"'=>'b "a b'}, type.deserialize(%q({"c":"}", "\"a\"":"b \"a b"})))
- end
-
- def test_rewrite
- @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')"
- x = JsonDataType.first
- x.payload = { '"a\'' => 'b' }
- assert x.save!
- end
-
- def test_select
- @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')"
- x = JsonDataType.first
- assert_equal({'k' => 'v'}, x.payload)
- end
-
- def test_select_multikey
- @connection.execute %q|insert into json_data_type (payload) VALUES ('{"k1":"v1", "k2":"v2", "k3":[1,2,3]}')|
- x = JsonDataType.first
- assert_equal({'k1' => 'v1', 'k2' => 'v2', 'k3' => [1,2,3]}, x.payload)
- end
-
- def test_null_json
- @connection.execute %q|insert into json_data_type (payload) VALUES(null)|
- x = JsonDataType.first
- assert_equal(nil, x.payload)
- end
+ @connection.add_column "json_data_type", "permissions", column_type, default: { "users": "read", "posts": ["read", "write"] }
+ klass.reset_column_information
- def test_select_array_json_value
- @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')|
- x = JsonDataType.first
- assert_equal(['v0', {'k1' => 'v1'}], x.payload)
+ assert_equal({ "users" => "read", "posts" => ["read", "write"] }, klass.column_defaults["permissions"])
+ assert_equal({ "users" => "read", "posts" => ["read", "write"] }, klass.new.permissions)
end
- def test_rewrite_array_json_value
- @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')|
- x = JsonDataType.first
- x.payload = ['v1', {'k2' => 'v2'}, 'v3']
- assert x.save!
- end
-
- def test_with_store_accessors
- x = JsonDataType.new(resolution: "320×480")
- assert_equal "320×480", x.resolution
-
- x.save!
- x = JsonDataType.first
- assert_equal "320×480", x.resolution
-
- x.resolution = "640×1136"
+ def test_deserialize_with_array
+ x = klass.new(objects: ["foo" => "bar"])
+ assert_equal ["foo" => "bar"], x.objects
x.save!
-
- x = JsonDataType.first
- assert_equal "640×1136", x.resolution
- end
-
- def test_duplication_with_store_accessors
- x = JsonDataType.new(resolution: "320×480")
- assert_equal "320×480", x.resolution
-
- y = x.dup
- assert_equal "320×480", y.resolution
- end
-
- def test_yaml_round_trip_with_store_accessors
- x = JsonDataType.new(resolution: "320×480")
- assert_equal "320×480", x.resolution
-
- y = YAML.load(YAML.dump(x))
- assert_equal "320×480", y.resolution
- end
-
- def test_changes_in_place
- json = JsonDataType.new
- assert_not json.changed?
-
- json.payload = { 'one' => 'two' }
- assert json.changed?
- assert json.payload_changed?
-
- json.save!
- assert_not json.changed?
-
- json.payload['three'] = 'four'
- assert json.payload_changed?
-
- json.save!
- json.reload
-
- assert_equal({ 'one' => 'two', 'three' => 'four' }, json.payload)
- assert_not json.changed?
- end
-
- def test_assigning_string_literal
- json = JsonDataType.create(payload: "foo")
- assert_equal "foo", json.payload
- end
-
- def test_assigning_number
- json = JsonDataType.create(payload: 1.234)
- assert_equal 1.234, json.payload
- end
-
- def test_assigning_boolean
- json = JsonDataType.create(payload: true)
- assert_equal true, json.payload
+ assert_equal ["foo" => "bar"], x.objects
+ x.reload
+ assert_equal ["foo" => "bar"], x.objects
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/ltree_test.rb b/activerecord/test/cases/adapters/postgresql/ltree_test.rb
index 56516c82b4..eca29f2892 100644
--- a/activerecord/test/cases/adapters/postgresql/ltree_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/ltree_test.rb
@@ -1,20 +1,22 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
class PostgresqlLtreeTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
class Ltree < ActiveRecord::Base
- self.table_name = 'ltrees'
+ self.table_name = "ltrees"
end
def setup
@connection = ActiveRecord::Base.connection
- enable_extension!('ltree', @connection)
+ enable_extension!("ltree", @connection)
@connection.transaction do
- @connection.create_table('ltrees') do |t|
- t.ltree 'path'
+ @connection.create_table("ltrees") do |t|
+ t.ltree "path"
end
end
rescue ActiveRecord::StatementInvalid
@@ -22,28 +24,28 @@ class PostgresqlLtreeTest < ActiveRecord::PostgreSQLTestCase
end
teardown do
- @connection.drop_table 'ltrees', if_exists: true
+ @connection.drop_table "ltrees", if_exists: true
end
def test_column
- column = Ltree.columns_hash['path']
+ column = Ltree.columns_hash["path"]
assert_equal :ltree, column.type
assert_equal "ltree", column.sql_type
assert_not column.array?
- type = Ltree.type_for_attribute('path')
+ type = Ltree.type_for_attribute("path")
assert_not type.binary?
end
def test_write
- ltree = Ltree.new(path: '1.2.3.4')
+ ltree = Ltree.new(path: "1.2.3.4")
assert ltree.save!
end
def test_select
@connection.execute "insert into ltrees (path) VALUES ('1.2.3')"
ltree = Ltree.first
- assert_equal '1.2.3', ltree.path
+ assert_equal "1.2.3", ltree.path
end
def test_schema_dump_with_shorthand
diff --git a/activerecord/test/cases/adapters/postgresql/money_test.rb b/activerecord/test/cases/adapters/postgresql/money_test.rb
index c031178479..cc10890fa8 100644
--- a/activerecord/test/cases/adapters/postgresql/money_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/money_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
@@ -9,14 +11,14 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase
setup do
@connection = ActiveRecord::Base.connection
@connection.execute("set lc_monetary = 'C'")
- @connection.create_table('postgresql_moneys', force: true) do |t|
+ @connection.create_table("postgresql_moneys", force: true) do |t|
t.money "wealth"
t.money "depth", default: "150.55"
end
end
teardown do
- @connection.drop_table 'postgresql_moneys', if_exists: true
+ @connection.drop_table "postgresql_moneys", if_exists: true
end
def test_column
@@ -31,8 +33,8 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase
end
def test_default
- assert_equal BigDecimal.new("150.55"), PostgresqlMoney.column_defaults['depth']
- assert_equal BigDecimal.new("150.55"), PostgresqlMoney.new.depth
+ assert_equal BigDecimal("150.55"), PostgresqlMoney.column_defaults["depth"]
+ assert_equal BigDecimal("150.55"), PostgresqlMoney.new.depth
end
def test_money_values
@@ -46,11 +48,11 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase
end
def test_money_type_cast
- type = PostgresqlMoney.type_for_attribute('wealth')
- assert_equal(12345678.12, type.cast("$12,345,678.12"))
- assert_equal(12345678.12, type.cast("$12.345.678,12"))
- assert_equal(-1.15, type.cast("-$1.15"))
- assert_equal(-2.25, type.cast("($2.25)"))
+ type = PostgresqlMoney.type_for_attribute("wealth")
+ assert_equal(12345678.12, type.cast("$12,345,678.12".dup))
+ assert_equal(12345678.12, type.cast("$12.345.678,12".dup))
+ assert_equal(-1.15, type.cast("-$1.15".dup))
+ assert_equal(-2.25, type.cast("($2.25)".dup))
end
def test_schema_dumping
@@ -60,10 +62,10 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase
end
def test_create_and_update_money
- money = PostgresqlMoney.create(wealth: "987.65")
+ money = PostgresqlMoney.create(wealth: "987.65".dup)
assert_equal 987.65, money.wealth
- new_value = BigDecimal.new('123.45')
+ new_value = BigDecimal("123.45")
money.wealth = new_value
money.save!
money.reload
@@ -80,7 +82,7 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase
def test_update_all_with_money_big_decimal
money = PostgresqlMoney.create!
- PostgresqlMoney.update_all(wealth: '123.45'.to_d)
+ PostgresqlMoney.update_all(wealth: "123.45".to_d)
money.reload
assert_equal 123.45, money.wealth
diff --git a/activerecord/test/cases/adapters/postgresql/network_test.rb b/activerecord/test/cases/adapters/postgresql/network_test.rb
index fe6ee4e2d9..f461544a85 100644
--- a/activerecord/test/cases/adapters/postgresql/network_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/network_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
class PostgresqlNetworkTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
@@ -7,15 +9,15 @@ class PostgresqlNetworkTest < ActiveRecord::PostgreSQLTestCase
setup do
@connection = ActiveRecord::Base.connection
- @connection.create_table('postgresql_network_addresses', force: true) do |t|
- t.inet 'inet_address', default: "192.168.1.1"
- t.cidr 'cidr_address', default: "192.168.1.0/24"
- t.macaddr 'mac_address', default: "ff:ff:ff:ff:ff:ff"
+ @connection.create_table("postgresql_network_addresses", force: true) do |t|
+ t.inet "inet_address", default: "192.168.1.1"
+ t.cidr "cidr_address", default: "192.168.1.0/24"
+ t.macaddr "mac_address", default: "ff:ff:ff:ff:ff:ff"
end
end
teardown do
- @connection.drop_table 'postgresql_network_addresses', if_exists: true
+ @connection.drop_table "postgresql_network_addresses", if_exists: true
end
def test_cidr_column
@@ -49,33 +51,33 @@ class PostgresqlNetworkTest < ActiveRecord::PostgreSQLTestCase
end
def test_network_types
- PostgresqlNetworkAddress.create(cidr_address: '192.168.0.0/24',
- inet_address: '172.16.1.254/32',
- mac_address: '01:23:45:67:89:0a')
+ PostgresqlNetworkAddress.create(cidr_address: "192.168.0.0/24",
+ inet_address: "172.16.1.254/32",
+ mac_address: "01:23:45:67:89:0a")
address = PostgresqlNetworkAddress.first
- assert_equal IPAddr.new('192.168.0.0/24'), address.cidr_address
- assert_equal IPAddr.new('172.16.1.254'), address.inet_address
- assert_equal '01:23:45:67:89:0a', address.mac_address
+ assert_equal IPAddr.new("192.168.0.0/24"), address.cidr_address
+ assert_equal IPAddr.new("172.16.1.254"), address.inet_address
+ assert_equal "01:23:45:67:89:0a", address.mac_address
- address.cidr_address = '10.1.2.3/32'
- address.inet_address = '10.0.0.0/8'
- address.mac_address = 'bc:de:f0:12:34:56'
+ address.cidr_address = "10.1.2.3/32"
+ address.inet_address = "10.0.0.0/8"
+ address.mac_address = "bc:de:f0:12:34:56"
address.save!
assert address.reload
- assert_equal IPAddr.new('10.1.2.3/32'), address.cidr_address
- assert_equal IPAddr.new('10.0.0.0/8'), address.inet_address
- assert_equal 'bc:de:f0:12:34:56', address.mac_address
+ assert_equal IPAddr.new("10.1.2.3/32"), address.cidr_address
+ assert_equal IPAddr.new("10.0.0.0/8"), address.inet_address
+ assert_equal "bc:de:f0:12:34:56", address.mac_address
end
def test_invalid_network_address
- invalid_address = PostgresqlNetworkAddress.new(cidr_address: 'invalid addr',
- inet_address: 'invalid addr')
+ invalid_address = PostgresqlNetworkAddress.new(cidr_address: "invalid addr",
+ inet_address: "invalid addr")
assert_nil invalid_address.cidr_address
assert_nil invalid_address.inet_address
- assert_equal 'invalid addr', invalid_address.cidr_address_before_type_cast
- assert_equal 'invalid addr', invalid_address.inet_address_before_type_cast
+ assert_equal "invalid addr", invalid_address.cidr_address_before_type_cast
+ assert_equal "invalid addr", invalid_address.inet_address_before_type_cast
assert invalid_address.save
invalid_address.reload
diff --git a/activerecord/test/cases/adapters/postgresql/numbers_test.rb b/activerecord/test/cases/adapters/postgresql/numbers_test.rb
index ba7e7dc9a3..b53a12254d 100644
--- a/activerecord/test/cases/adapters/postgresql/numbers_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/numbers_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cases/helper"
class PostgresqlNumberTest < ActiveRecord::PostgreSQLTestCase
@@ -5,14 +7,14 @@ class PostgresqlNumberTest < ActiveRecord::PostgreSQLTestCase
setup do
@connection = ActiveRecord::Base.connection
- @connection.create_table('postgresql_numbers', force: true) do |t|
- t.column 'single', 'REAL'
- t.column 'double', 'DOUBLE PRECISION'
+ @connection.create_table("postgresql_numbers", force: true) do |t|
+ t.column "single", "REAL"
+ t.column "double", "DOUBLE PRECISION"
end
end
teardown do
- @connection.drop_table 'postgresql_numbers', if_exists: true
+ @connection.drop_table "postgresql_numbers", if_exists: true
end
def test_data_type
@@ -31,7 +33,7 @@ class PostgresqlNumberTest < ActiveRecord::PostgreSQLTestCase
assert_equal 123456.789, first.double
assert_equal(-::Float::INFINITY, second.single)
assert_equal ::Float::INFINITY, second.double
- assert_send [third.double, :nan?]
+ assert third.double.nan?, "Expected #{third.double} to be NaN"
end
def test_update
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index 9832df7839..1951230c8a 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/ddl_helper'
-require 'support/connection_helper'
+require "support/ddl_helper"
+require "support/connection_helper"
module ActiveRecord
module ConnectionAdapters
@@ -15,163 +17,140 @@ module ActiveRecord
def test_bad_connection
assert_raise ActiveRecord::NoDatabaseError do
- configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'should_not_exist-cinco-dog-db')
+ configuration = ActiveRecord::Base.configurations["arunit"].merge(database: "should_not_exist-cinco-dog-db")
connection = ActiveRecord::Base.postgresql_connection(configuration)
- connection.exec_query('SELECT 1')
- end
- end
-
- def test_valid_column
- with_example_table do
- column = @connection.columns('ex').find { |col| col.name == 'id' }
- assert @connection.valid_type?(column.type)
+ connection.exec_query("SELECT 1")
end
end
- def test_invalid_column
- assert_not @connection.valid_type?(:foobar)
- end
-
def test_primary_key
with_example_table do
- assert_equal 'id', @connection.primary_key('ex')
+ assert_equal "id", @connection.primary_key("ex")
end
end
def test_primary_key_works_tables_containing_capital_letters
- assert_equal 'id', @connection.primary_key('CamelCase')
+ assert_equal "id", @connection.primary_key("CamelCase")
end
def test_non_standard_primary_key
- with_example_table 'data character varying(255) primary key' do
- assert_equal 'data', @connection.primary_key('ex')
+ with_example_table "data character varying(255) primary key" do
+ assert_equal "data", @connection.primary_key("ex")
end
end
def test_primary_key_returns_nil_for_no_pk
- with_example_table 'id integer' do
- assert_nil @connection.primary_key('ex')
- end
- end
-
- def test_primary_key_raises_error_if_table_not_found
- assert_raises(ActiveRecord::StatementInvalid) do
- @connection.primary_key('unobtainium')
+ with_example_table "id integer" do
+ assert_nil @connection.primary_key("ex")
end
end
def test_exec_insert_with_returning_disabled
connection = connection_without_insert_returning
- result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id', 'postgresql_partitioned_table_parent_id_seq')
- expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
+ result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], "id", "postgresql_partitioned_table_parent_id_seq")
+ expect = connection.query("select max(id) from postgresql_partitioned_table_parent").first.first
assert_equal expect.to_i, result.rows.first.first
end
def test_exec_insert_with_returning_disabled_and_no_sequence_name_given
connection = connection_without_insert_returning
- result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id')
- expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
+ result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], "id")
+ expect = connection.query("select max(id) from postgresql_partitioned_table_parent").first.first
assert_equal expect.to_i, result.rows.first.first
end
def test_exec_insert_default_values_with_returning_disabled_and_no_sequence_name_given
connection = connection_without_insert_returning
- result = connection.exec_insert("insert into postgresql_partitioned_table_parent DEFAULT VALUES", nil, [], 'id')
- expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
+ result = connection.exec_insert("insert into postgresql_partitioned_table_parent DEFAULT VALUES", nil, [], "id")
+ expect = connection.query("select max(id) from postgresql_partitioned_table_parent").first.first
assert_equal expect.to_i, result.rows.first.first
end
def test_exec_insert_default_values_quoted_schema_with_returning_disabled_and_no_sequence_name_given
connection = connection_without_insert_returning
- result = connection.exec_insert('insert into "public"."postgresql_partitioned_table_parent" DEFAULT VALUES', nil, [], 'id')
- expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
+ result = connection.exec_insert('insert into "public"."postgresql_partitioned_table_parent" DEFAULT VALUES', nil, [], "id")
+ expect = connection.query("select max(id) from postgresql_partitioned_table_parent").first.first
assert_equal expect.to_i, result.rows.first.first
end
- def test_sql_for_insert_with_returning_disabled
- connection = connection_without_insert_returning
- sql, binds = connection.sql_for_insert('sql', nil, nil, nil, 'binds')
- assert_equal ['sql', 'binds'], [sql, binds]
- end
-
def test_serial_sequence
- assert_equal 'public.accounts_id_seq',
- @connection.serial_sequence('accounts', 'id')
+ assert_equal "public.accounts_id_seq",
+ @connection.serial_sequence("accounts", "id")
assert_raises(ActiveRecord::StatementInvalid) do
- @connection.serial_sequence('zomg', 'id')
+ @connection.serial_sequence("zomg", "id")
end
end
def test_default_sequence_name
- assert_equal 'public.accounts_id_seq',
- @connection.default_sequence_name('accounts', 'id')
+ assert_equal "public.accounts_id_seq",
+ @connection.default_sequence_name("accounts", "id")
- assert_equal 'public.accounts_id_seq',
- @connection.default_sequence_name('accounts')
+ assert_equal "public.accounts_id_seq",
+ @connection.default_sequence_name("accounts")
end
def test_default_sequence_name_bad_table
- assert_equal 'zomg_id_seq',
- @connection.default_sequence_name('zomg', 'id')
+ assert_equal "zomg_id_seq",
+ @connection.default_sequence_name("zomg", "id")
- assert_equal 'zomg_id_seq',
- @connection.default_sequence_name('zomg')
+ assert_equal "zomg_id_seq",
+ @connection.default_sequence_name("zomg")
end
def test_pk_and_sequence_for
with_example_table do
- pk, seq = @connection.pk_and_sequence_for('ex')
- assert_equal 'id', pk
- assert_equal @connection.default_sequence_name('ex', 'id'), seq.to_s
+ pk, seq = @connection.pk_and_sequence_for("ex")
+ assert_equal "id", pk
+ assert_equal @connection.default_sequence_name("ex", "id"), seq.to_s
end
end
def test_pk_and_sequence_for_with_non_standard_primary_key
- with_example_table 'code serial primary key' do
- pk, seq = @connection.pk_and_sequence_for('ex')
- assert_equal 'code', pk
- assert_equal @connection.default_sequence_name('ex', 'code'), seq.to_s
+ with_example_table "code serial primary key" do
+ pk, seq = @connection.pk_and_sequence_for("ex")
+ assert_equal "code", pk
+ assert_equal @connection.default_sequence_name("ex", "code"), seq.to_s
end
end
def test_pk_and_sequence_for_returns_nil_if_no_seq
- with_example_table 'id integer primary key' do
- assert_nil @connection.pk_and_sequence_for('ex')
+ with_example_table "id integer primary key" do
+ assert_nil @connection.pk_and_sequence_for("ex")
end
end
def test_pk_and_sequence_for_returns_nil_if_no_pk
- with_example_table 'id integer' do
- assert_nil @connection.pk_and_sequence_for('ex')
+ with_example_table "id integer" do
+ assert_nil @connection.pk_and_sequence_for("ex")
end
end
def test_pk_and_sequence_for_returns_nil_if_table_not_found
- assert_nil @connection.pk_and_sequence_for('unobtainium')
+ assert_nil @connection.pk_and_sequence_for("unobtainium")
end
def test_pk_and_sequence_for_with_collision_pg_class_oid
- @connection.exec_query('create table ex(id serial primary key)')
- @connection.exec_query('create table ex2(id serial primary key)')
+ @connection.exec_query("create table ex(id serial primary key)")
+ @connection.exec_query("create table ex2(id serial primary key)")
correct_depend_record = [
"'pg_class'::regclass",
"'ex_id_seq'::regclass",
- '0',
+ "0",
"'pg_class'::regclass",
"'ex'::regclass",
- '1',
+ "1",
"'a'"
]
collision_depend_record = [
"'pg_attrdef'::regclass",
"'ex2_id_seq'::regclass",
- '0',
+ "0",
"'pg_class'::regclass",
"'ex'::regclass",
- '1',
+ "1",
"'a'"
]
@@ -185,15 +164,15 @@ module ActiveRecord
"INSERT INTO pg_depend VALUES(#{correct_depend_record.join(',')})"
)
- seq = @connection.pk_and_sequence_for('ex').last
+ seq = @connection.pk_and_sequence_for("ex").last
assert_equal PostgreSQL::Name.new("public", "ex_id_seq"), seq
@connection.exec_query(
"DELETE FROM pg_depend WHERE objid = 'ex2_id_seq'::regclass AND refobjid = 'ex'::regclass AND deptype = 'a'"
)
ensure
- @connection.drop_table 'ex', if_exists: true
- @connection.drop_table 'ex2', if_exists: true
+ @connection.drop_table "ex", if_exists: true
+ @connection.drop_table "ex2", if_exists: true
end
def test_table_alias_length
@@ -204,74 +183,77 @@ module ActiveRecord
def test_exec_no_binds
with_example_table do
- result = @connection.exec_query('SELECT id, data FROM ex')
+ result = @connection.exec_query("SELECT id, data FROM ex")
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
- string = @connection.quote('foo')
+ string = @connection.quote("foo")
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
- result = @connection.exec_query('SELECT id, data FROM ex')
+ result = @connection.exec_query("SELECT id, data FROM ex")
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
- assert_equal [[1, 'foo']], result.rows
+ assert_equal [[1, "foo"]], result.rows
end
end
if ActiveRecord::Base.connection.prepared_statements
def test_exec_with_binds
with_example_table do
- string = @connection.quote('foo')
+ string = @connection.quote("foo")
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
bind = Relation::QueryAttribute.new("id", 1, Type::Value.new)
- result = @connection.exec_query('SELECT id, data FROM ex WHERE id = $1', nil, [bind])
+ result = @connection.exec_query("SELECT id, data FROM ex WHERE id = $1", nil, [bind])
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
- assert_equal [[1, 'foo']], result.rows
+ assert_equal [[1, "foo"]], result.rows
end
end
def test_exec_typecasts_bind_vals
with_example_table do
- string = @connection.quote('foo')
+ string = @connection.quote("foo")
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
bind = Relation::QueryAttribute.new("id", "1-fuu", Type::Integer.new)
- result = @connection.exec_query('SELECT id, data FROM ex WHERE id = $1', nil, [bind])
+ result = @connection.exec_query("SELECT id, data FROM ex WHERE id = $1", nil, [bind])
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
- assert_equal [[1, 'foo']], result.rows
+ assert_equal [[1, "foo"]], result.rows
end
end
end
def test_partial_index
with_example_table do
- @connection.add_index 'ex', %w{ id number }, :name => 'partial', :where => "number > 100"
- index = @connection.indexes('ex').find { |idx| idx.name == 'partial' }
+ @connection.add_index "ex", %w{ id number }, name: "partial", where: "number > 100"
+ index = @connection.indexes("ex").find { |idx| idx.name == "partial" }
assert_equal "(number > 100)", index.where
end
end
def test_expression_index
with_example_table do
- @connection.add_index 'ex', 'mod(id, 10), abs(number)', name: 'expression'
- index = @connection.indexes('ex').find { |idx| idx.name == 'expression' }
- assert_equal 'mod(id, 10), abs(number)', index.columns
+ @connection.add_index "ex", "mod(id, 10), abs(number)", name: "expression"
+ index = @connection.indexes("ex").find { |idx| idx.name == "expression" }
+ assert_equal "mod(id, 10), abs(number)", index.columns
end
end
def test_index_with_opclass
with_example_table do
- @connection.add_index 'ex', 'data varchar_pattern_ops', name: 'with_opclass'
- index = @connection.indexes('ex').find { |idx| idx.name == 'with_opclass' }
- assert_equal 'data varchar_pattern_ops', index.columns
+ @connection.add_index "ex", "data", opclass: "varchar_pattern_ops"
+ index = @connection.indexes("ex").find { |idx| idx.name == "index_ex_on_data" }
+ assert_equal ["data"], index.columns
+
+ @connection.remove_index "ex", "data"
+ assert_not @connection.indexes("ex").find { |idx| idx.name == "index_ex_on_data" }
end
end
@@ -292,8 +274,8 @@ module ActiveRecord
def test_columns_for_distinct_with_case
assert_equal(
- 'posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0',
- @connection.columns_for_distinct('posts.id',
+ "posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0",
+ @connection.columns_for_distinct("posts.id",
["CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END"])
)
end
@@ -344,29 +326,35 @@ module ActiveRecord
reset_connection
end
- def test_only_reload_type_map_once_for_every_unknown_type
+ def test_only_reload_type_map_once_for_every_unrecognized_type
+ reset_connection
+ connection = ActiveRecord::Base.connection
+
silence_warnings do
assert_queries 2, ignore_none: true do
- @connection.select_all "SELECT NULL::anyelement"
+ connection.select_all "select 'pg_catalog.pg_class'::regclass"
end
assert_queries 1, ignore_none: true do
- @connection.select_all "SELECT NULL::anyelement"
+ connection.select_all "select 'pg_catalog.pg_class'::regclass"
end
assert_queries 2, ignore_none: true do
- @connection.select_all "SELECT NULL::anyarray"
+ connection.select_all "SELECT NULL::anyarray"
end
end
ensure
reset_connection
end
- def test_only_warn_on_first_encounter_of_unknown_oid
+ def test_only_warn_on_first_encounter_of_unrecognized_oid
+ reset_connection
+ connection = ActiveRecord::Base.connection
+
warning = capture(:stderr) {
- @connection.select_all "SELECT NULL::anyelement"
- @connection.select_all "SELECT NULL::anyelement"
- @connection.select_all "SELECT NULL::anyelement"
+ connection.select_all "select 'pg_catalog.pg_class'::regclass"
+ connection.select_all "select 'pg_catalog.pg_class'::regclass"
+ connection.select_all "select 'pg_catalog.pg_class'::regclass"
}
- assert_match(/\Aunknown OID \d+: failed to recognize type of 'anyelement'. It will be treated as String.\n\z/, warning)
+ assert_match(/\Aunknown OID \d+: failed to recognize type of 'regclass'\. It will be treated as String\.\n\z/, warning)
ensure
reset_connection
end
@@ -374,7 +362,7 @@ module ActiveRecord
def test_unparsed_defaults_are_at_least_set_when_saving
with_example_table "id SERIAL PRIMARY KEY, number INTEGER NOT NULL DEFAULT (4 + 4) * 2 / 4" do
number_klass = Class.new(ActiveRecord::Base) do
- self.table_name = 'ex'
+ self.table_name = "ex"
end
column = number_klass.columns_hash["number"]
assert_nil column.default
@@ -390,13 +378,13 @@ module ActiveRecord
private
- def with_example_table(definition = 'id serial primary key, number integer, data character varying(255)', &block)
- super(@connection, 'ex', definition, &block)
- end
+ def with_example_table(definition = "id serial primary key, number integer, data character varying(255)", &block)
+ super(@connection, "ex", definition, &block)
+ end
- def connection_without_insert_returning
- ActiveRecord::Base.postgresql_connection(ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false))
- end
+ def connection_without_insert_returning
+ ActiveRecord::Base.postgresql_connection(ActiveRecord::Base.configurations["arunit"].merge(insert_returning: false))
+ end
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb b/activerecord/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb
new file mode 100644
index 0000000000..f7478b50c3
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "models/computer"
+require "models/developer"
+
+class PreparedStatementsDisabledTest < ActiveRecord::PostgreSQLTestCase
+ fixtures :developers
+
+ def setup
+ @conn = ActiveRecord::Base.establish_connection :arunit_without_prepared_statements
+ end
+
+ def teardown
+ @conn.release_connection
+ ActiveRecord::Base.establish_connection :arunit
+ end
+
+ def test_select_query_works_even_when_prepared_statements_are_disabled
+ assert_not Developer.connection.prepared_statements
+
+ david = developers(:david)
+
+ assert_equal david, Developer.where(name: "David").last # With Binds
+ assert_operator Developer.count, :>, 0 # Without Binds
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb b/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb
deleted file mode 100644
index f1519db48b..0000000000
--- a/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require "cases/helper"
-require "models/developer"
-
-class PreparedStatementsTest < ActiveRecord::PostgreSQLTestCase
- fixtures :developers
-
- def setup
- @default_prepared_statements = Developer.connection_config[:prepared_statements]
- Developer.connection_config[:prepared_statements] = false
- end
-
- def teardown
- Developer.connection_config[:prepared_statements] = @default_prepared_statements
- end
-
- def nothing_raised_with_falsy_prepared_statements
- assert_nothing_raised do
- Developer.where(id: 1)
- end
- end
-
-end
diff --git a/activerecord/test/cases/adapters/postgresql/quoting_test.rb b/activerecord/test/cases/adapters/postgresql/quoting_test.rb
index 5e6f4dbbb8..d50dc49276 100644
--- a/activerecord/test/cases/adapters/postgresql/quoting_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/quoting_test.rb
@@ -1,5 +1,6 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'ipaddr'
module ActiveRecord
module ConnectionAdapters
@@ -10,20 +11,20 @@ module ActiveRecord
end
def test_type_cast_true
- assert_equal 't', @conn.type_cast(true)
+ assert_equal true, @conn.type_cast(true)
end
def test_type_cast_false
- assert_equal 'f', @conn.type_cast(false)
+ assert_equal false, @conn.type_cast(false)
end
def test_quote_float_nan
- nan = 0.0/0
+ nan = 0.0 / 0
assert_equal "'NaN'", @conn.quote(nan)
end
def test_quote_float_infinity
- infinity = 1.0/0
+ infinity = 1.0 / 0
assert_equal "'Infinity'", @conn.quote(infinity)
end
@@ -36,7 +37,7 @@ module ActiveRecord
def test_quote_bit_string
value = "'); SELECT * FROM users; /*\n01\n*/--"
type = OID::Bit.new
- assert_equal nil, @conn.quote(type.serialize(value))
+ assert_nil @conn.quote(type.serialize(value))
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/range_test.rb b/activerecord/test/cases/adapters/postgresql/range_test.rb
index 0edfa4ed9d..261c24634e 100644
--- a/activerecord/test/cases/adapters/postgresql/range_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/range_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/connection_helper'
+require "support/connection_helper"
if ActiveRecord::Base.connection.respond_to?(:supports_ranges?) && ActiveRecord::Base.connection.supports_ranges?
class PostgresqlRange < ActiveRecord::Base
@@ -23,7 +25,7 @@ if ActiveRecord::Base.connection.respond_to?(:supports_ranges?) && ActiveRecord:
);
_SQL
- @connection.create_table('postgresql_ranges') do |t|
+ @connection.create_table("postgresql_ranges") do |t|
t.daterange :date_range
t.numrange :num_range
t.tsrange :ts_range
@@ -32,7 +34,7 @@ _SQL
t.int8range :int8_range
end
- @connection.add_column 'postgresql_ranges', 'float_range', 'floatrange'
+ @connection.add_column "postgresql_ranges", "float_range", "floatrange"
end
PostgresqlRange.reset_column_information
rescue ActiveRecord::StatementInvalid
@@ -93,8 +95,8 @@ _SQL
end
teardown do
- @connection.drop_table 'postgresql_ranges', if_exists: true
- @connection.execute 'DROP TYPE IF EXISTS floatrange'
+ @connection.drop_table "postgresql_ranges", if_exists: true
+ @connection.execute "DROP TYPE IF EXISTS floatrange"
reset_connection
end
@@ -132,10 +134,10 @@ _SQL
end
def test_numrange_values
- assert_equal BigDecimal.new('0.1')..BigDecimal.new('0.2'), @first_range.num_range
- assert_equal BigDecimal.new('0.1')...BigDecimal.new('0.2'), @second_range.num_range
- assert_equal BigDecimal.new('0.1')...BigDecimal.new('Infinity'), @third_range.num_range
- assert_equal BigDecimal.new('-Infinity')...BigDecimal.new('Infinity'), @fourth_range.num_range
+ assert_equal BigDecimal("0.1")..BigDecimal("0.2"), @first_range.num_range
+ assert_equal BigDecimal("0.1")...BigDecimal("0.2"), @second_range.num_range
+ assert_equal BigDecimal("0.1")...BigDecimal("Infinity"), @third_range.num_range
+ assert_equal BigDecimal("-Infinity")...BigDecimal("Infinity"), @fourth_range.num_range
assert_nil @empty_range.num_range
end
@@ -148,8 +150,8 @@ _SQL
end
def test_tstzrange_values
- assert_equal Time.parse('2010-01-01 09:30:00 UTC')..Time.parse('2011-01-01 17:30:00 UTC'), @first_range.tstz_range
- assert_equal Time.parse('2010-01-01 09:30:00 UTC')...Time.parse('2011-01-01 17:30:00 UTC'), @second_range.tstz_range
+ assert_equal Time.parse("2010-01-01 09:30:00 UTC")..Time.parse("2011-01-01 17:30:00 UTC"), @first_range.tstz_range
+ assert_equal Time.parse("2010-01-01 09:30:00 UTC")...Time.parse("2011-01-01 17:30:00 UTC"), @second_range.tstz_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.tstz_range)
assert_nil @empty_range.tstz_range
end
@@ -183,17 +185,17 @@ _SQL
end
def test_create_tstzrange
- tstzrange = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2011-02-02 14:30:00 CDT')
+ tstzrange = Time.parse("2010-01-01 14:30:00 +0100")...Time.parse("2011-02-02 14:30:00 CDT")
round_trip(@new_range, :tstz_range, tstzrange)
assert_equal @new_range.tstz_range, tstzrange
- assert_equal @new_range.tstz_range, Time.parse('2010-01-01 13:30:00 UTC')...Time.parse('2011-02-02 19:30:00 UTC')
+ assert_equal @new_range.tstz_range, Time.parse("2010-01-01 13:30:00 UTC")...Time.parse("2011-02-02 19:30:00 UTC")
end
def test_update_tstzrange
assert_equal_round_trip(@first_range, :tstz_range,
- Time.parse('2010-01-01 14:30:00 CDT')...Time.parse('2011-02-02 14:30:00 CET'))
+ Time.parse("2010-01-01 14:30:00 CDT")...Time.parse("2011-02-02 14:30:00 CET"))
assert_nil_round_trip(@first_range, :tstz_range,
- Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2010-01-01 13:30:00 +0000'))
+ Time.parse("2010-01-01 14:30:00 +0100")...Time.parse("2010-01-01 13:30:00 +0000"))
end
def test_create_tsrange
@@ -230,16 +232,67 @@ _SQL
end
end
+ def test_create_tstzrange_preserve_usec
+ tstzrange = Time.parse("2010-01-01 14:30:00.670277 +0100")...Time.parse("2011-02-02 14:30:00.745125 CDT")
+ round_trip(@new_range, :tstz_range, tstzrange)
+ assert_equal @new_range.tstz_range, tstzrange
+ assert_equal @new_range.tstz_range, Time.parse("2010-01-01 13:30:00.670277 UTC")...Time.parse("2011-02-02 19:30:00.745125 UTC")
+ end
+
+ def test_update_tstzrange_preserve_usec
+ assert_equal_round_trip(@first_range, :tstz_range,
+ Time.parse("2010-01-01 14:30:00.245124 CDT")...Time.parse("2011-02-02 14:30:00.451274 CET"))
+ assert_nil_round_trip(@first_range, :tstz_range,
+ Time.parse("2010-01-01 14:30:00.245124 +0100")...Time.parse("2010-01-01 13:30:00.245124 +0000"))
+ end
+
+ def test_create_tsrange_preseve_usec
+ tz = ::ActiveRecord::Base.default_timezone
+ assert_equal_round_trip(@new_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0, 125435)...Time.send(tz, 2011, 2, 2, 14, 30, 0, 225435))
+ end
+
+ def test_update_tsrange_preserve_usec
+ tz = ::ActiveRecord::Base.default_timezone
+ assert_equal_round_trip(@first_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432)...Time.send(tz, 2011, 2, 2, 14, 30, 0, 224242))
+ assert_nil_round_trip(@first_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432)...Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432))
+ end
+
+ def test_timezone_awareness_tsrange_preserve_usec
+ tz = "Pacific Time (US & Canada)"
+
+ in_time_zone tz do
+ PostgresqlRange.reset_column_information
+ time_string = "2017-09-26 07:30:59.132451 -0700"
+ time = Time.zone.parse(time_string)
+ assert time.usec > 0
+
+ record = PostgresqlRange.new(ts_range: time_string..time_string)
+ assert_equal time..time, record.ts_range
+ assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
+ assert_equal time.usec, record.ts_range.begin.usec
+
+ record.save!
+ record.reload
+
+ assert_equal time..time, record.ts_range
+ assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
+ assert_equal time.usec, record.ts_range.begin.usec
+ end
+ end
+
def test_create_numrange
assert_equal_round_trip(@new_range, :num_range,
- BigDecimal.new('0.5')...BigDecimal.new('1'))
+ BigDecimal("0.5")...BigDecimal("1"))
end
def test_update_numrange
assert_equal_round_trip(@first_range, :num_range,
- BigDecimal.new('0.5')...BigDecimal.new('1'))
+ BigDecimal("0.5")...BigDecimal("1"))
assert_nil_round_trip(@first_range, :num_range,
- BigDecimal.new('0.5')...BigDecimal.new('0.5'))
+ BigDecimal("0.5")...BigDecimal("0.5"))
end
def test_create_daterange
@@ -282,6 +335,12 @@ _SQL
assert_raises(ArgumentError) { PostgresqlRange.create!(tstz_range: "(''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'']") }
end
+ def test_where_by_attribute_with_range
+ range = 1..100
+ record = PostgresqlRange.create!(int4_range: range)
+ assert_equal record, PostgresqlRange.where(int4_range: range).take
+ end
+
def test_update_all_with_ranges
PostgresqlRange.create!
@@ -299,6 +358,18 @@ _SQL
end
end
+ def test_infinity_values
+ PostgresqlRange.create!(int4_range: 1..Float::INFINITY,
+ int8_range: -Float::INFINITY..0,
+ float_range: -Float::INFINITY..Float::INFINITY)
+
+ record = PostgresqlRange.first
+
+ assert_equal(1...Float::INFINITY, record.int4_range)
+ assert_equal(-Float::INFINITY...1, record.int8_range)
+ assert_equal(-Float::INFINITY...Float::INFINITY, record.float_range)
+ end
+
private
def assert_equal_round_trip(range, attribute, value)
round_trip(range, attribute, value)
diff --git a/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb b/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb
index c895ab9db5..0bcc214c24 100644
--- a/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb
@@ -1,5 +1,7 @@
-require 'cases/helper'
-require 'support/connection_helper'
+# frozen_string_literal: true
+
+require "cases/helper"
+require "support/connection_helper"
class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase
self.use_transactional_tests = false
@@ -14,7 +16,7 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase
def execute(sql)
if IS_REFERENTIAL_INTEGRITY_SQL.call(sql)
super "BROKEN;" rescue nil # put transaction in broken state
- raise ActiveRecord::StatementInvalid, 'PG::InsufficientPrivilege'
+ raise ActiveRecord::StatementInvalid, "PG::InsufficientPrivilege"
else
super
end
@@ -24,7 +26,7 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase
module ProgrammerMistake
def execute(sql)
if IS_REFERENTIAL_INTEGRITY_SQL.call(sql)
- raise ArgumentError, 'something is not right.'
+ raise ArgumentError, "something is not right."
else
super
end
@@ -48,10 +50,10 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase
warning = capture(:stderr) do
e = assert_raises(ActiveRecord::InvalidForeignKey) do
@connection.disable_referential_integrity do
- raise ActiveRecord::InvalidForeignKey, 'Should be re-raised'
+ raise ActiveRecord::InvalidForeignKey, "Should be re-raised"
end
end
- assert_equal 'Should be re-raised', e.message
+ assert_equal "Should be re-raised", e.message
end
assert_match (/WARNING: Rails was not able to disable referential integrity/), warning
assert_match (/cause: PG::InsufficientPrivilege/), warning
@@ -63,10 +65,10 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase
warning = capture(:stderr) do
e = assert_raises(ActiveRecord::StatementInvalid) do
@connection.disable_referential_integrity do
- raise ActiveRecord::StatementInvalid, 'Should be re-raised'
+ raise ActiveRecord::StatementInvalid, "Should be re-raised"
end
end
- assert_equal 'Should be re-raised', e.message
+ assert_equal "Should be re-raised", e.message
end
assert warning.blank?, "expected no warnings but got:\n#{warning}"
end
@@ -105,7 +107,7 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase
private
- def assert_transaction_is_not_broken
- assert_equal 1, @connection.select_value("SELECT 1")
- end
+ def assert_transaction_is_not_broken
+ assert_equal 1, @connection.select_value("SELECT 1")
+ end
end
diff --git a/activerecord/test/cases/adapters/postgresql/rename_table_test.rb b/activerecord/test/cases/adapters/postgresql/rename_table_test.rb
index bd64bae308..100d247113 100644
--- a/activerecord/test/cases/adapters/postgresql/rename_table_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/rename_table_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cases/helper"
class PostgresqlRenameTableTest < ActiveRecord::PostgreSQLTestCase
@@ -24,11 +26,11 @@ class PostgresqlRenameTableTest < ActiveRecord::PostgreSQLTestCase
private
- def num_indices_named(name)
- @connection.execute(<<-SQL).values.length
- SELECT 1 FROM "pg_index"
- JOIN "pg_class" ON "pg_index"."indexrelid" = "pg_class"."oid"
- WHERE "pg_class"."relname" = '#{name}'
- SQL
- end
+ def num_indices_named(name)
+ @connection.execute(<<-SQL).values.length
+ SELECT 1 FROM "pg_index"
+ JOIN "pg_class" ON "pg_index"."indexrelid" = "pg_class"."oid"
+ WHERE "pg_class"."relname" = '#{name}'
+ SQL
+ end
end
diff --git a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
index 285a92f60e..fcb0aec81b 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cases/helper"
class SchemaThing < ActiveRecord::Base
@@ -6,12 +8,12 @@ end
class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase
self.use_transactional_tests = false
- TABLE_NAME = 'schema_things'
+ TABLE_NAME = "schema_things"
COLUMNS = [
- 'id serial primary key',
- 'name character varying(50)'
+ "id serial primary key",
+ "name character varying(50)"
]
- USERS = ['rails_pg_schema_user1', 'rails_pg_schema_user2']
+ USERS = ["rails_pg_schema_user1", "rails_pg_schema_user2"]
def setup
@connection = ActiveRecord::Base.connection
@@ -45,7 +47,7 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase
def test_session_auth=
assert_raise(ActiveRecord::StatementInvalid) do
- @connection.session_auth = 'DEFAULT'
+ @connection.session_auth = "DEFAULT"
@connection.execute "SELECT * FROM #{TABLE_NAME}"
end
end
@@ -68,31 +70,20 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase
USERS.each do |u|
@connection.clear_cache!
set_session_auth u
- assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [bind_param(1)])
+ assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = $1", "SQL", [bind_param(1)])
set_session_auth
end
end
end
end
- def test_schema_uniqueness
- assert_nothing_raised do
- set_session_auth
- USERS.each do |u|
- set_session_auth u
- assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = 1")
- set_session_auth
- end
- end
- end
-
def test_sequence_schema_caching
assert_nothing_raised do
USERS.each do |u|
set_session_auth u
- st = SchemaThing.new :name => 'TEST1'
+ st = SchemaThing.new name: "TEST1"
st.save!
- st = SchemaThing.new :id => 5, :name => 'TEST2'
+ st = SchemaThing.new id: 5, name: "TEST2"
st.save!
set_session_auth
end
@@ -100,17 +91,17 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase
end
def test_tables_in_current_schemas
- assert !@connection.tables.include?(TABLE_NAME)
+ assert_not_includes @connection.tables, TABLE_NAME
USERS.each do |u|
set_session_auth u
- assert @connection.tables.include?(TABLE_NAME)
+ assert_includes @connection.tables, TABLE_NAME
set_session_auth
end
end
private
- def set_session_auth auth = nil
- @connection.session_auth = auth || 'default'
+ def set_session_auth(auth = nil)
+ @connection.session_auth = auth || "default"
end
def bind_param(value)
diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb
index 52ef07f654..2c99fa78bd 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb
@@ -1,6 +1,8 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'models/default'
-require 'support/schema_dumping_helper'
+require "models/default"
+require "support/schema_dumping_helper"
module PGSchemaHelper
def with_schema_search_path(schema_search_path)
@@ -17,32 +19,32 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
include PGSchemaHelper
self.use_transactional_tests = false
- SCHEMA_NAME = 'test_schema'
- SCHEMA2_NAME = 'test_schema2'
- TABLE_NAME = 'things'
- CAPITALIZED_TABLE_NAME = 'Things'
- INDEX_A_NAME = 'a_index_things_on_name'
- INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema'
- INDEX_C_NAME = 'c_index_full_text_search'
- INDEX_D_NAME = 'd_index_things_on_description_desc'
- INDEX_E_NAME = 'e_index_things_on_name_vector'
- INDEX_A_COLUMN = 'name'
- INDEX_B_COLUMN_S1 = 'email'
- INDEX_B_COLUMN_S2 = 'moment'
- INDEX_C_COLUMN = %q{(to_tsvector('english', coalesce(things.name, '')))}
- INDEX_D_COLUMN = 'description'
- INDEX_E_COLUMN = 'name_vector'
+ SCHEMA_NAME = "test_schema"
+ SCHEMA2_NAME = "test_schema2"
+ TABLE_NAME = "things"
+ CAPITALIZED_TABLE_NAME = "Things"
+ INDEX_A_NAME = "a_index_things_on_name"
+ INDEX_B_NAME = "b_index_things_on_different_columns_in_each_schema"
+ INDEX_C_NAME = "c_index_full_text_search"
+ INDEX_D_NAME = "d_index_things_on_description_desc"
+ INDEX_E_NAME = "e_index_things_on_name_vector"
+ INDEX_A_COLUMN = "name"
+ INDEX_B_COLUMN_S1 = "email"
+ INDEX_B_COLUMN_S2 = "moment"
+ INDEX_C_COLUMN = "(to_tsvector('english', coalesce(things.name, '')))"
+ INDEX_D_COLUMN = "description"
+ INDEX_E_COLUMN = "name_vector"
COLUMNS = [
- 'id integer',
- 'name character varying(50)',
- 'email character varying(50)',
- 'description character varying(100)',
- 'name_vector tsvector',
- 'moment timestamp without time zone default now()'
+ "id integer",
+ "name character varying(50)",
+ "email character varying(50)",
+ "description character varying(100)",
+ "name_vector tsvector",
+ "moment timestamp without time zone default now()"
]
- PK_TABLE_NAME = 'table_with_pk'
- UNMATCHED_SEQUENCE_NAME = 'unmatched_primary_key_default_value_seq'
- UNMATCHED_PK_TABLE_NAME = 'table_with_unmatched_sequence_for_pk'
+ PK_TABLE_NAME = "table_with_pk"
+ UNMATCHED_SEQUENCE_NAME = "unmatched_primary_key_default_value_seq"
+ UNMATCHED_PK_TABLE_NAME = "table_with_unmatched_sequence_for_pk"
class Thing1 < ActiveRecord::Base
self.table_name = "test_schema.things"
@@ -61,7 +63,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
end
class Thing5 < ActiveRecord::Base
- self.table_name = 'things'
+ self.table_name = "things"
end
class Song < ActiveRecord::Base
@@ -91,6 +93,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
@connection.execute "CREATE INDEX #{INDEX_E_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING gin (#{INDEX_E_COLUMN});"
@connection.execute "CREATE INDEX #{INDEX_E_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING gin (#{INDEX_E_COLUMN});"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{PK_TABLE_NAME} (id serial primary key)"
+ @connection.execute "CREATE TABLE #{SCHEMA2_NAME}.#{PK_TABLE_NAME} (id serial primary key)"
@connection.execute "CREATE SEQUENCE #{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME} (id integer NOT NULL DEFAULT nextval('#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}'::regclass), CONSTRAINT unmatched_pkey PRIMARY KEY (id))"
end
@@ -130,7 +133,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
ensure
@connection.drop_schema "test_schema3"
end
- assert !@connection.schema_names.include?("test_schema3")
+ assert_not_includes @connection.schema_names, "test_schema3"
end
def test_drop_schema_if_exists
@@ -168,21 +171,21 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
def test_raise_wrapped_exception_on_bad_prepare
assert_raises(ActiveRecord::StatementInvalid) do
- @connection.exec_query "select * from developers where id = ?", 'sql', [bind_param(1)]
+ @connection.exec_query "select * from developers where id = ?", "sql", [bind_param(1)]
end
end
if ActiveRecord::Base.connection.prepared_statements
def test_schema_change_with_prepared_stmt
altered = false
- @connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)]
- @connection.exec_query "alter table developers add column zomg int", 'sql', []
+ @connection.exec_query "select * from developers where id = $1", "sql", [bind_param(1)]
+ @connection.exec_query "alter table developers add column zomg int", "sql", []
altered = true
- @connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)]
+ @connection.exec_query "select * from developers where id = $1", "sql", [bind_param(1)]
ensure
# We are not using DROP COLUMN IF EXISTS because that syntax is only
# supported by pg 9.X
- @connection.exec_query("alter table developers drop column zomg", 'sql', []) if altered
+ @connection.exec_query("alter table developers drop column zomg", "sql", []) if altered
end
end
@@ -200,7 +203,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
end
def test_data_source_exists_when_not_on_schema_search_path
- with_schema_search_path('PUBLIC') do
+ with_schema_search_path("PUBLIC") do
assert(!@connection.data_source_exists?(TABLE_NAME), "data_source exists but should not be found")
end
end
@@ -246,9 +249,9 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
end
def test_proper_encoding_of_table_name
- assert_equal '"table_name"', @connection.quote_table_name('table_name')
+ assert_equal '"table_name"', @connection.quote_table_name("table_name")
assert_equal '"table.name"', @connection.quote_table_name('"table.name"')
- assert_equal '"schema_name"."table_name"', @connection.quote_table_name('schema_name.table_name')
+ assert_equal '"schema_name"."table_name"', @connection.quote_table_name("schema_name.table_name")
assert_equal '"schema_name"."table.name"', @connection.quote_table_name('schema_name."table.name"')
assert_equal '"schema.name"."table_name"', @connection.quote_table_name('"schema.name".table_name')
assert_equal '"schema.name"."table.name"', @connection.quote_table_name('"schema.name"."table.name"')
@@ -260,25 +263,25 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
assert_equal 0, Thing3.count
assert_equal 0, Thing4.count
- Thing1.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ Thing1.create(id: 1, name: "thing1", email: "thing1@localhost", moment: Time.now)
assert_equal 1, Thing1.count
assert_equal 0, Thing2.count
assert_equal 0, Thing3.count
assert_equal 0, Thing4.count
- Thing2.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ Thing2.create(id: 1, name: "thing1", email: "thing1@localhost", moment: Time.now)
assert_equal 1, Thing1.count
assert_equal 1, Thing2.count
assert_equal 0, Thing3.count
assert_equal 0, Thing4.count
- Thing3.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ Thing3.create(id: 1, name: "thing1", email: "thing1@localhost", moment: Time.now)
assert_equal 1, Thing1.count
assert_equal 1, Thing2.count
assert_equal 1, Thing3.count
assert_equal 0, Thing4.count
- Thing4.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now)
+ Thing4.create(id: 1, name: "thing1", email: "thing1@localhost", moment: Time.now)
assert_equal 1, Thing1.count
assert_equal 1, Thing2.count
assert_equal 1, Thing3.count
@@ -287,7 +290,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
def test_raise_on_unquoted_schema_name
assert_raises(ActiveRecord::StatementInvalid) do
- with_schema_search_path '$user,public'
+ with_schema_search_path "$user,public"
end
end
@@ -301,13 +304,13 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
def test_index_name_exists
with_schema_search_path(SCHEMA_NAME) do
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_A_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_B_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_C_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_D_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME, true)
- assert_not @connection.index_name_exists?(TABLE_NAME, 'missing_index', true)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_A_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_B_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_C_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_D_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME)
+ assert_not @connection.index_name_exists?(TABLE_NAME, "missing_index")
end
end
@@ -332,7 +335,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
@connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
with_schema_search_path SCHEMA_NAME do
- assert_nothing_raised { @connection.remove_index "things", name: "things_Index"}
+ assert_nothing_raised { @connection.remove_index "things", name: "things_Index" }
end
end
@@ -356,21 +359,13 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
%(#{SCHEMA_NAME}."#{PK_TABLE_NAME}"),
%(#{SCHEMA_NAME}.#{PK_TABLE_NAME})
].each do |given|
- assert_equal 'id', @connection.primary_key(given), "primary key should be found when table referenced as #{given}"
+ assert_equal "id", @connection.primary_key(given), "primary key should be found when table referenced as #{given}"
end
end
def test_primary_key_assuming_schema_search_path
- with_schema_search_path(SCHEMA_NAME) do
- assert_equal 'id', @connection.primary_key(PK_TABLE_NAME), "primary key should be found"
- end
- end
-
- def test_primary_key_raises_error_if_table_not_found_on_schema_search_path
- with_schema_search_path(SCHEMA2_NAME) do
- assert_raises(ActiveRecord::StatementInvalid) do
- @connection.primary_key(PK_TABLE_NAME)
- end
+ with_schema_search_path("#{SCHEMA_NAME}, #{SCHEMA2_NAME}") do
+ assert_equal "id", @connection.primary_key(PK_TABLE_NAME), "primary key should be found"
end
end
@@ -381,19 +376,19 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
%("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
].each do |given|
pk, seq = @connection.pk_and_sequence_for(given)
- assert_equal 'id', pk, "primary key should be found when table referenced as #{given}"
+ assert_equal "id", pk, "primary key should be found when table referenced as #{given}"
assert_equal pg_name.new(SCHEMA_NAME, "#{PK_TABLE_NAME}_id_seq"), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}")
- assert_equal pg_name.new(SCHEMA_NAME, UNMATCHED_SEQUENCE_NAME), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
+ assert_equal pg_name.new(SCHEMA_NAME, UNMATCHED_SEQUENCE_NAME), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
end
end
def test_current_schema
{
- %('$user',public) => 'public',
+ %('$user',public) => "public",
SCHEMA_NAME => SCHEMA_NAME,
%(#{SCHEMA2_NAME},#{SCHEMA_NAME},public) => SCHEMA2_NAME,
- %(public,#{SCHEMA2_NAME},#{SCHEMA_NAME}) => 'public'
- }.each do |given,expect|
+ %(public,#{SCHEMA2_NAME},#{SCHEMA_NAME}) => "public"
+ }.each do |given, expect|
with_schema_search_path(given) { assert_equal expect, @connection.current_schema }
end
end
@@ -401,7 +396,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
def test_prepared_statements_with_multiple_schemas
[SCHEMA_NAME, SCHEMA2_NAME].each do |schema_name|
with_schema_search_path schema_name do
- Thing5.create(:id => 1, :name => "thing inside #{SCHEMA_NAME}", :email => "thing1@localhost", :moment => Time.now)
+ Thing5.create(id: 1, name: "thing inside #{SCHEMA_NAME}", email: "thing1@localhost", moment: Time.now)
end
end
@@ -414,11 +409,11 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
def test_schema_exists?
{
- 'public' => true,
+ "public" => true,
SCHEMA_NAME => true,
SCHEMA2_NAME => true,
- 'darkside' => false
- }.each do |given,expect|
+ "darkside" => false
+ }.each do |given, expect|
assert_equal expect, @connection.schema_exists?(given)
end
end
@@ -442,7 +437,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
private
def columns(table_name)
@connection.send(:column_definitions, table_name).map do |name, type, default|
- "#{name} #{type}" + (default ? " default #{default}" : '')
+ "#{name} #{type}" + (default ? " default #{default}" : "")
end
end
@@ -464,7 +459,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
assert_equal :btree, index_d.using
assert_equal :gin, index_e.using
- assert_equal :desc, index_d.orders[INDEX_D_COLUMN]
+ assert_equal :desc, index_d.orders
end
end
@@ -505,6 +500,38 @@ class SchemaForeignKeyTest < ActiveRecord::PostgreSQLTestCase
end
end
+class SchemaIndexOpclassTest < ActiveRecord::PostgreSQLTestCase
+ include SchemaDumpingHelper
+
+ setup do
+ @connection = ActiveRecord::Base.connection
+ @connection.create_table "trains" do |t|
+ t.string :name
+ t.text :description
+ end
+ end
+
+ teardown do
+ @connection.drop_table "trains", if_exists: true
+ end
+
+ def test_string_opclass_is_dumped
+ @connection.execute "CREATE INDEX trains_name_and_description ON trains USING btree(name text_pattern_ops, description text_pattern_ops)"
+
+ output = dump_table_schema "trains"
+
+ assert_match(/opclass: :text_pattern_ops/, output)
+ end
+
+ def test_non_default_opclass_is_dumped
+ @connection.execute "CREATE INDEX trains_name_and_description ON trains USING btree(name, description text_pattern_ops)"
+
+ output = dump_table_schema "trains"
+
+ assert_match(/opclass: \{ description: :text_pattern_ops \}/, output)
+ end
+end
+
class DefaultsUsingMultipleSchemasAndDomainTest < ActiveRecord::PostgreSQLTestCase
setup do
@connection = ActiveRecord::Base.connection
@@ -539,7 +566,7 @@ class DefaultsUsingMultipleSchemasAndDomainTest < ActiveRecord::PostgreSQLTestCa
end
def test_decimal_defaults_in_new_schema_when_overriding_domain
- assert_equal BigDecimal.new("3.14159265358979323846"), Default.new.decimal_col, "Default of decimal column was not correctly parsed"
+ assert_equal BigDecimal("3.14159265358979323846"), Default.new.decimal_col, "Default of decimal column was not correctly parsed"
end
def test_bpchar_defaults_in_new_schema_when_overriding_domain
diff --git a/activerecord/test/cases/adapters/postgresql/serial_test.rb b/activerecord/test/cases/adapters/postgresql/serial_test.rb
index 8abe064bf1..6a99323be5 100644
--- a/activerecord/test/cases/adapters/postgresql/serial_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/serial_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
class PostgresqlSerialTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
@@ -84,3 +86,71 @@ class PostgresqlBigSerialTest < ActiveRecord::PostgreSQLTestCase
assert_match %r{t\.bigint\s+"serials_id",\s+default: -> \{ "nextval\('postgresql_big_serials_id_seq'::regclass\)" \}$}, output
end
end
+
+module SequenceNameDetectionTestCases
+ class CollidedSequenceNameTest < ActiveRecord::PostgreSQLTestCase
+ include SchemaDumpingHelper
+
+ def setup
+ @connection = ActiveRecord::Base.connection
+ @connection.create_table :foo_bar, force: true do |t|
+ t.serial :baz_id
+ end
+ @connection.create_table :foo, force: true do |t|
+ t.serial :bar_id
+ t.bigserial :bar_baz_id
+ end
+ end
+
+ def teardown
+ @connection.drop_table :foo_bar, if_exists: true
+ @connection.drop_table :foo, if_exists: true
+ end
+
+ def test_serial_columns
+ columns = @connection.columns(:foo)
+ columns.each do |column|
+ assert_equal :integer, column.type
+ assert column.serial?
+ end
+ end
+
+ def test_schema_dump_with_collided_sequence_name
+ output = dump_table_schema "foo"
+ assert_match %r{t\.serial\s+"bar_id",\s+null: false$}, output
+ assert_match %r{t\.bigserial\s+"bar_baz_id",\s+null: false$}, output
+ end
+ end
+
+ class LongerSequenceNameDetectionTest < ActiveRecord::PostgreSQLTestCase
+ include SchemaDumpingHelper
+
+ def setup
+ @table_name = "long_table_name_to_test_sequence_name_detection_for_serial_cols"
+ @connection = ActiveRecord::Base.connection
+ @connection.create_table @table_name, force: true do |t|
+ t.serial :seq
+ t.bigserial :bigseq
+ end
+ end
+
+ def teardown
+ @connection.drop_table @table_name, if_exists: true
+ end
+
+ def test_serial_columns
+ columns = @connection.columns(@table_name)
+ columns.each do |column|
+ assert_equal :integer, column.type
+ assert column.serial?
+ end
+ end
+
+ def test_schema_dump_with_long_table_name
+ output = dump_table_schema @table_name
+ assert_match %r{create_table "#{@table_name}", force: :cascade}, output
+ assert_match %r{t\.serial\s+"seq",\s+null: false$}, output
+ assert_match %r{t\.bigserial\s+"bigseq",\s+null: false$}, output
+ end
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb b/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb
index 5aab246c99..fef4b02b04 100644
--- a/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb
@@ -1,15 +1,17 @@
-require 'cases/helper'
+# frozen_string_literal: true
+
+require "cases/helper"
module ActiveRecord
module ConnectionAdapters
class PostgreSQLAdapter < AbstractAdapter
- class InactivePGconn
+ class InactivePgConnection
def query(*args)
- raise PGError
+ raise PG::Error
end
def status
- PGconn::CONNECTION_BAD
+ PG::CONNECTION_BAD
end
end
@@ -17,22 +19,22 @@ module ActiveRecord
if Process.respond_to?(:fork)
def test_cache_is_per_pid
cache = StatementPool.new nil, 10
- cache['foo'] = 'bar'
- assert_equal 'bar', cache['foo']
+ cache["foo"] = "bar"
+ assert_equal "bar", cache["foo"]
pid = fork {
- lookup = cache['foo'];
+ lookup = cache["foo"]
exit!(!lookup)
}
Process.waitpid pid
- assert $?.success?, 'process should exit successfully'
+ assert $?.success?, "process should exit successfully"
end
end
def test_dealloc_does_not_raise_on_inactive_connection
- cache = StatementPool.new InactivePGconn.new, 10
- cache['foo'] = 'bar'
+ cache = StatementPool.new InactivePgConnection.new, 10
+ cache["foo"] = "bar"
assert_nothing_raised { cache.clear }
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
index 4c4866b46b..b7f213efc8 100644
--- a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
@@ -1,6 +1,8 @@
-require 'cases/helper'
-require 'models/developer'
-require 'models/topic'
+# frozen_string_literal: true
+
+require "cases/helper"
+require "models/developer"
+require "models/topic"
class PostgresqlTimestampTest < ActiveRecord::PostgreSQLTestCase
class PostgresqlTimestampWithZone < ActiveRecord::Base; end
@@ -21,7 +23,7 @@ class PostgresqlTimestampTest < ActiveRecord::PostgreSQLTestCase
@connection.reconnect!
timestamp = PostgresqlTimestampWithZone.find(1)
- assert_equal Time.utc(2010,1,1, 11,0,0), timestamp.time
+ assert_equal Time.utc(2010, 1, 1, 11, 0, 0), timestamp.time
assert_instance_of Time, timestamp.time
end
ensure
@@ -32,10 +34,10 @@ class PostgresqlTimestampTest < ActiveRecord::PostgreSQLTestCase
with_timezone_config default: :local, aware_attributes: false do
@connection.reconnect!
# make sure to use a non-UTC time zone
- @connection.execute("SET time zone 'America/Jamaica'", 'SCHEMA')
+ @connection.execute("SET time zone 'America/Jamaica'", "SCHEMA")
timestamp = PostgresqlTimestampWithZone.find(1)
- assert_equal Time.utc(2010,1,1, 11,0,0), timestamp.time
+ assert_equal Time.utc(2010, 1, 1, 11, 0, 0), timestamp.time
assert_instance_of Time, timestamp.time
end
ensure
@@ -54,37 +56,37 @@ class PostgresqlTimestampFixtureTest < ActiveRecord::PostgreSQLTestCase
def test_load_infinity_and_beyond
d = Developer.find_by_sql("select 'infinity'::timestamp as updated_at")
- assert d.first.updated_at.infinite?, 'timestamp should be infinite'
+ assert d.first.updated_at.infinite?, "timestamp should be infinite"
d = Developer.find_by_sql("select '-infinity'::timestamp as updated_at")
time = d.first.updated_at
- assert time.infinite?, 'timestamp should be infinite'
+ assert time.infinite?, "timestamp should be infinite"
assert_operator time, :<, 0
end
def test_save_infinity_and_beyond
- d = Developer.create!(:name => 'aaron', :updated_at => 1.0 / 0.0)
+ d = Developer.create!(name: "aaron", updated_at: 1.0 / 0.0)
assert_equal(1.0 / 0.0, d.updated_at)
- d = Developer.create!(:name => 'aaron', :updated_at => -1.0 / 0.0)
+ d = Developer.create!(name: "aaron", updated_at: -1.0 / 0.0)
assert_equal(-1.0 / 0.0, d.updated_at)
end
def test_bc_timestamp
date = Date.new(0) - 1.week
- Developer.create!(:name => "aaron", :updated_at => date)
+ Developer.create!(name: "aaron", updated_at: date)
assert_equal date, Developer.find_by_name("aaron").updated_at
end
def test_bc_timestamp_leap_year
date = Time.utc(-4, 2, 29)
- Developer.create!(:name => "taihou", :updated_at => date)
+ Developer.create!(name: "taihou", updated_at: date)
assert_equal date, Developer.find_by_name("taihou").updated_at
end
def test_bc_timestamp_year_zero
date = Time.utc(0, 4, 7)
- Developer.create!(:name => "yahagi", :updated_at => date)
+ Developer.create!(name: "yahagi", updated_at: date)
assert_equal date, Developer.find_by_name("yahagi").updated_at
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/transaction_test.rb b/activerecord/test/cases/adapters/postgresql/transaction_test.rb
new file mode 100644
index 0000000000..9821b103df
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/transaction_test.rb
@@ -0,0 +1,190 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "support/connection_helper"
+require "concurrent/atomic/cyclic_barrier"
+
+module ActiveRecord
+ class PostgresqlTransactionTest < ActiveRecord::PostgreSQLTestCase
+ self.use_transactional_tests = false
+
+ class Sample < ActiveRecord::Base
+ self.table_name = "samples"
+ end
+
+ setup do
+ @abort, Thread.abort_on_exception = Thread.abort_on_exception, false
+ Thread.report_on_exception, @original_report_on_exception = false, Thread.report_on_exception if Thread.respond_to?(:report_on_exception)
+
+ @connection = ActiveRecord::Base.connection
+
+ @connection.transaction do
+ @connection.drop_table "samples", if_exists: true
+ @connection.create_table("samples") do |t|
+ t.integer "value"
+ end
+ end
+
+ Sample.reset_column_information
+ end
+
+ teardown do
+ @connection.drop_table "samples", if_exists: true
+
+ Thread.abort_on_exception = @abort
+ Thread.report_on_exception = @original_report_on_exception if Thread.respond_to?(:report_on_exception)
+ end
+
+ test "raises SerializationFailure when a serialization failure occurs" do
+ assert_raises(ActiveRecord::SerializationFailure) do
+ before = Concurrent::CyclicBarrier.new(2)
+ after = Concurrent::CyclicBarrier.new(2)
+
+ 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
+
+ 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
+ end
+
+ 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!
+ barrier.wait
+ s2.update_attributes value: 1
+ end
+ end
+
+ begin
+ Sample.transaction do
+ s2.lock!
+ barrier.wait
+ s1.update_attributes value: 2
+ end
+ ensure
+ thread.join
+ end
+ end
+ end
+ end
+
+ test "raises LockWaitTimeout when lock wait timeout exceeded" do
+ skip unless ActiveRecord::Base.connection.postgresql_version >= 90300
+ assert_raises(ActiveRecord::LockWaitTimeout) do
+ s = Sample.create!(value: 1)
+ latch1 = Concurrent::CountDownLatch.new
+ latch2 = Concurrent::CountDownLatch.new
+
+ thread = Thread.new do
+ Sample.transaction do
+ Sample.lock.find(s.id)
+ latch1.count_down
+ latch2.wait
+ end
+ end
+
+ begin
+ Sample.transaction do
+ latch1.wait
+ Sample.connection.execute("SET lock_timeout = 1")
+ Sample.lock.find(s.id)
+ end
+ ensure
+ Sample.connection.execute("SET lock_timeout = DEFAULT")
+ latch2.count_down
+ thread.join
+ end
+ end
+ end
+
+ test "raises QueryCanceled when statement timeout exceeded" do
+ assert_raises(ActiveRecord::QueryCanceled) do
+ s = Sample.create!(value: 1)
+ latch1 = Concurrent::CountDownLatch.new
+ latch2 = Concurrent::CountDownLatch.new
+
+ thread = Thread.new do
+ Sample.transaction do
+ Sample.lock.find(s.id)
+ latch1.count_down
+ latch2.wait
+ end
+ end
+
+ begin
+ Sample.transaction do
+ latch1.wait
+ Sample.connection.execute("SET statement_timeout = 1")
+ Sample.lock.find(s.id)
+ end
+ ensure
+ Sample.connection.execute("SET statement_timeout = DEFAULT")
+ latch2.count_down
+ thread.join
+ end
+ end
+ end
+
+ test "raises QueryCanceled when canceling statement due to user request" do
+ assert_raises(ActiveRecord::QueryCanceled) do
+ s = Sample.create!(value: 1)
+ latch = Concurrent::CountDownLatch.new
+
+ thread = Thread.new do
+ Sample.transaction do
+ Sample.lock.find(s.id)
+ latch.count_down
+ sleep(0.5)
+ conn = Sample.connection
+ pid = conn.query_value("SELECT pid FROM pg_stat_activity WHERE query LIKE '% FOR UPDATE'")
+ conn.execute("SELECT pg_cancel_backend(#{pid})")
+ end
+ end
+
+ begin
+ Sample.transaction do
+ latch.wait
+ Sample.lock.find(s.id)
+ end
+ ensure
+ thread.join
+ end
+ end
+ end
+
+ private
+
+ def with_warning_suppression
+ log_level = ActiveRecord::Base.connection.client_min_messages
+ ActiveRecord::Base.connection.client_min_messages = "error"
+ yield
+ ensure
+ ActiveRecord::Base.connection.client_min_messages = log_level
+ end
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
index ea0f0b8fa5..8212ed4263 100644
--- a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
@@ -1,4 +1,6 @@
-require 'cases/helper'
+# frozen_string_literal: true
+
+require "cases/helper"
class PostgresqlTypeLookupTest < ActiveRecord::PostgreSQLTestCase
setup do
@@ -6,28 +8,28 @@ class PostgresqlTypeLookupTest < ActiveRecord::PostgreSQLTestCase
end
test "array delimiters are looked up correctly" do
- box_array = @connection.type_map.lookup(1020)
- int_array = @connection.type_map.lookup(1007)
+ box_array = @connection.send(:type_map).lookup(1020)
+ int_array = @connection.send(:type_map).lookup(1007)
- assert_equal ';', box_array.delimiter
- assert_equal ',', int_array.delimiter
+ assert_equal ";", box_array.delimiter
+ assert_equal ",", int_array.delimiter
end
test "array types correctly respect registration of subtypes" do
- int_array = @connection.type_map.lookup(1007, -1, "integer[]")
- bigint_array = @connection.type_map.lookup(1016, -1, "bigint[]")
+ int_array = @connection.send(:type_map).lookup(1007, -1, "integer[]")
+ bigint_array = @connection.send(:type_map).lookup(1016, -1, "bigint[]")
big_array = [123456789123456789]
assert_raises(ActiveModel::RangeError) { int_array.serialize(big_array) }
- assert_equal "{123456789123456789}", bigint_array.serialize(big_array)
+ assert_equal "{123456789123456789}", @connection.type_cast(bigint_array.serialize(big_array))
end
test "range types correctly respect registration of subtypes" do
- int_range = @connection.type_map.lookup(3904, -1, "int4range")
- bigint_range = @connection.type_map.lookup(3926, -1, "int8range")
+ int_range = @connection.send(:type_map).lookup(3904, -1, "int4range")
+ bigint_range = @connection.send(:type_map).lookup(3926, -1, "int8range")
big_range = 0..123456789123456789
assert_raises(ActiveModel::RangeError) { int_range.serialize(big_range) }
- assert_equal "[0,123456789123456789]", bigint_range.serialize(big_range)
+ assert_equal "[0,123456789123456789]", @connection.type_cast(bigint_range.serialize(big_range))
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/utils_test.rb b/activerecord/test/cases/adapters/postgresql/utils_test.rb
index 095c1826e5..c91884f384 100644
--- a/activerecord/test/cases/adapters/postgresql/utils_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/utils_test.rb
@@ -1,5 +1,7 @@
-require 'cases/helper'
-require 'active_record/connection_adapters/postgresql/utils'
+# frozen_string_literal: true
+
+require "cases/helper"
+require "active_record/connection_adapters/postgresql/utils"
class PostgreSQLUtilsTest < ActiveRecord::PostgreSQLTestCase
Name = ActiveRecord::ConnectionAdapters::PostgreSQL::Name
@@ -7,14 +9,14 @@ class PostgreSQLUtilsTest < ActiveRecord::PostgreSQLTestCase
def test_extract_schema_qualified_name
{
- %(table_name) => [nil,'table_name'],
- %("table.name") => [nil,'table.name'],
+ %(table_name) => [nil, "table_name"],
+ %("table.name") => [nil, "table.name"],
%(schema.table_name) => %w{schema table_name},
%("schema".table_name) => %w{schema table_name},
%(schema."table_name") => %w{schema table_name},
%("schema"."table_name") => %w{schema table_name},
- %("even spaces".table) => ['even spaces','table'],
- %(schema."table.name") => ['schema', 'table.name']
+ %("even spaces".table) => ["even spaces", "table"],
+ %(schema."table.name") => ["schema", "table.name"]
}.each do |given, expect|
assert_equal Name.new(*expect), extract_schema_qualified_name(given)
end
@@ -54,9 +56,9 @@ class PostgreSQLNameTest < ActiveRecord::PostgreSQLTestCase
end
test "can be used as hash key" do
- hash = {Name.new("schema", "article_seq") => "success"}
+ hash = { Name.new("schema", "article_seq") => "success" }
assert_equal "success", hash[Name.new("schema", "article_seq")]
- assert_equal nil, hash[Name.new("schema", "articles")]
- assert_equal nil, hash[Name.new("public", "article_seq")]
+ assert_nil hash[Name.new("schema", "articles")]
+ assert_nil hash[Name.new("public", "article_seq")]
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
index 7628075ad2..c24e0cb330 100644
--- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require "cases/helper"
-require 'support/schema_dumping_helper'
+require "support/schema_dumping_helper"
module PostgresqlUUIDHelper
def connection
@@ -9,6 +11,14 @@ module PostgresqlUUIDHelper
def drop_table(name)
connection.drop_table name, if_exists: true
end
+
+ def uuid_function
+ connection.supports_pgcrypto_uuid? ? "gen_random_uuid()" : "uuid_generate_v4()"
+ end
+
+ def uuid_default
+ connection.supports_pgcrypto_uuid? ? {} : { default: uuid_function }
+ end
end
class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
@@ -20,10 +30,11 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
end
setup do
- enable_extension!('uuid-ossp', connection)
+ enable_extension!("uuid-ossp", connection)
+ enable_extension!("pgcrypto", connection) if connection.supports_pgcrypto_uuid?
connection.create_table "uuid_data_type" do |t|
- t.uuid 'guid'
+ t.uuid "guid"
end
end
@@ -31,21 +42,53 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
drop_table "uuid_data_type"
end
+ if ActiveRecord::Base.connection.respond_to?(:supports_pgcrypto_uuid?) &&
+ ActiveRecord::Base.connection.supports_pgcrypto_uuid?
+ def test_uuid_column_default
+ connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "gen_random_uuid()"
+ UUIDType.reset_column_information
+ column = UUIDType.columns_hash["thingy"]
+ assert_equal "gen_random_uuid()", column.default_function
+ end
+ end
+
def test_change_column_default
- @connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v1()"
+ connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v1()"
UUIDType.reset_column_information
- column = UUIDType.columns_hash['thingy']
+ column = UUIDType.columns_hash["thingy"]
assert_equal "uuid_generate_v1()", column.default_function
- @connection.change_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v4()"
-
+ connection.change_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v4()"
UUIDType.reset_column_information
- column = UUIDType.columns_hash['thingy']
+ column = UUIDType.columns_hash["thingy"]
assert_equal "uuid_generate_v4()", column.default_function
ensure
UUIDType.reset_column_information
end
+ def test_add_column_with_null_true_and_default_nil
+ connection.add_column :uuid_data_type, :thingy, :uuid, null: true, default: nil
+
+ UUIDType.reset_column_information
+ column = UUIDType.columns_hash["thingy"]
+
+ assert column.null
+ assert_nil column.default
+ end
+
+ def test_add_column_with_default_array
+ connection.add_column :uuid_data_type, :thingy, :uuid, array: true, default: []
+
+ UUIDType.reset_column_information
+ column = UUIDType.columns_hash["thingy"]
+
+ assert column.array?
+ assert_equal "{}", column.default
+
+ schema = dump_table_schema "uuid_data_type"
+ assert_match %r{t\.uuid "thingy", default: \[\], array: true$}, schema
+ end
+
def test_data_type_of_uuid_types
column = UUIDType.columns_hash["guid"]
assert_equal :uuid, column.type
@@ -57,46 +100,48 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
end
def test_treat_blank_uuid_as_nil
- UUIDType.create! guid: ''
- assert_equal(nil, UUIDType.last.guid)
+ UUIDType.create! guid: ""
+ assert_nil(UUIDType.last.guid)
end
def test_treat_invalid_uuid_as_nil
- uuid = UUIDType.create! guid: 'foobar'
- assert_equal(nil, uuid.guid)
+ uuid = UUIDType.create! guid: "foobar"
+ assert_nil(uuid.guid)
end
def test_invalid_uuid_dont_modify_before_type_cast
- uuid = UUIDType.new guid: 'foobar'
- assert_equal 'foobar', uuid.guid_before_type_cast
+ uuid = UUIDType.new guid: "foobar"
+ assert_equal "foobar", uuid.guid_before_type_cast
end
def test_acceptable_uuid_regex
# Valid uuids
- ['A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11',
- '{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}',
- 'a0eebc999c0b4ef8bb6d6bb9bd380a11',
- 'a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11',
- '{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}',
+ ["A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11",
+ "{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}",
+ "a0eebc999c0b4ef8bb6d6bb9bd380a11",
+ "a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11",
+ "{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}",
# The following is not a valid RFC 4122 UUID, but PG doesn't seem to care,
# so we shouldn't block it either. (Pay attention to "fb6d" – the "f" here
# is invalid – it must be one of 8, 9, A, B, a, b according to the spec.)
- '{a0eebc99-9c0b-4ef8-fb6d-6bb9bd380a11}',
+ "{a0eebc99-9c0b-4ef8-fb6d-6bb9bd380a11}",
].each do |valid_uuid|
uuid = UUIDType.new guid: valid_uuid
assert_not_nil uuid.guid
end
# Invalid uuids
- [['A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11'],
+ [["A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11"],
Hash.new,
0,
0.0,
true,
- 'Z0000C99-9C0B-4EF8-BB6D-6BB9BD380A11',
- 'a0eebc999r0b4ef8ab6d6bb9bd380a11',
- 'a0ee-bc99------4ef8-bb6d-6bb9-bd38-0a11',
- '{a0eebc99-bb6d6bb9-bd380a11}'].each do |invalid_uuid|
+ "Z0000C99-9C0B-4EF8-BB6D-6BB9BD380A11",
+ "a0eebc999r0b4ef8ab6d6bb9bd380a11",
+ "a0ee-bc99------4ef8-bb6d-6bb9-bd38-0a11",
+ "{a0eebc99-bb6d6bb9-bd380a11}",
+ "{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11",
+ "a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}"].each do |invalid_uuid|
uuid = UUIDType.new guid: invalid_uuid
assert_nil uuid.guid
end
@@ -142,71 +187,102 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
class UUID < ActiveRecord::Base
- self.table_name = 'pg_uuids'
+ self.table_name = "pg_uuids"
end
setup do
- connection.create_table('pg_uuids', id: :uuid, default: 'uuid_generate_v1()') do |t|
- t.string 'name'
- t.uuid 'other_uuid', default: 'uuid_generate_v4()'
+ connection.create_table("pg_uuids", id: :uuid, default: "uuid_generate_v1()") do |t|
+ t.string "name"
+ t.uuid "other_uuid", default: "uuid_generate_v4()"
end
# Create custom PostgreSQL function to generate UUIDs
# to test dumping tables which columns have defaults with custom functions
connection.execute <<-SQL
CREATE OR REPLACE FUNCTION my_uuid_generator() RETURNS uuid
- AS $$ SELECT * FROM uuid_generate_v4() $$
+ AS $$ SELECT * FROM #{uuid_function} $$
LANGUAGE SQL VOLATILE;
SQL
# Create such a table with custom function as default value generator
- connection.create_table('pg_uuids_2', id: :uuid, default: 'my_uuid_generator()') do |t|
- t.string 'name'
- t.uuid 'other_uuid_2', default: 'my_uuid_generator()'
+ connection.create_table("pg_uuids_2", id: :uuid, default: "my_uuid_generator()") do |t|
+ t.string "name"
+ t.uuid "other_uuid_2", default: "my_uuid_generator()"
+ end
+
+ connection.create_table("pg_uuids_3", id: :uuid, **uuid_default) do |t|
+ t.string "name"
end
end
teardown do
drop_table "pg_uuids"
- drop_table 'pg_uuids_2'
- connection.execute 'DROP FUNCTION IF EXISTS my_uuid_generator();'
+ drop_table "pg_uuids_2"
+ drop_table "pg_uuids_3"
+ connection.execute "DROP FUNCTION IF EXISTS my_uuid_generator();"
end
- if ActiveRecord::Base.connection.supports_extensions?
- def test_id_is_uuid
- assert_equal :uuid, UUID.columns_hash['id'].type
- assert UUID.primary_key
- end
+ def test_id_is_uuid
+ assert_equal :uuid, UUID.columns_hash["id"].type
+ assert UUID.primary_key
+ end
- def test_id_has_a_default
- u = UUID.create
- assert_not_nil u.id
- end
+ def test_id_has_a_default
+ u = UUID.create
+ assert_not_nil u.id
+ end
- def test_auto_create_uuid
- u = UUID.create
- u.reload
- assert_not_nil u.other_uuid
- end
+ def test_auto_create_uuid
+ u = UUID.create
+ u.reload
+ assert_not_nil u.other_uuid
+ end
- def test_pk_and_sequence_for_uuid_primary_key
- pk, seq = connection.pk_and_sequence_for('pg_uuids')
- assert_equal 'id', pk
- assert_equal nil, seq
- end
+ def test_pk_and_sequence_for_uuid_primary_key
+ pk, seq = connection.pk_and_sequence_for("pg_uuids")
+ assert_equal "id", pk
+ assert_nil seq
+ end
- def test_schema_dumper_for_uuid_primary_key
- schema = dump_table_schema "pg_uuids"
- assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: -> { "uuid_generate_v1\(\)" }/, schema)
- assert_match(/t\.uuid "other_uuid", default: -> { "uuid_generate_v4\(\)" }/, schema)
- end
+ def test_schema_dumper_for_uuid_primary_key
+ schema = dump_table_schema "pg_uuids"
+ assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: -> { "uuid_generate_v1\(\)" }/, schema)
+ assert_match(/t\.uuid "other_uuid", default: -> { "uuid_generate_v4\(\)" }/, schema)
+ end
+
+ def test_schema_dumper_for_uuid_primary_key_with_custom_default
+ schema = dump_table_schema "pg_uuids_2"
+ assert_match(/\bcreate_table "pg_uuids_2", id: :uuid, default: -> { "my_uuid_generator\(\)" }/, schema)
+ assert_match(/t\.uuid "other_uuid_2", default: -> { "my_uuid_generator\(\)" }/, schema)
+ end
- def test_schema_dumper_for_uuid_primary_key_with_custom_default
- schema = dump_table_schema "pg_uuids_2"
- assert_match(/\bcreate_table "pg_uuids_2", id: :uuid, default: -> { "my_uuid_generator\(\)" }/, schema)
- assert_match(/t\.uuid "other_uuid_2", default: -> { "my_uuid_generator\(\)" }/, schema)
+ def test_schema_dumper_for_uuid_primary_key_default
+ schema = dump_table_schema "pg_uuids_3"
+ if connection.supports_pgcrypto_uuid?
+ assert_match(/\bcreate_table "pg_uuids_3", id: :uuid, default: -> { "gen_random_uuid\(\)" }/, schema)
+ else
+ assert_match(/\bcreate_table "pg_uuids_3", id: :uuid, default: -> { "uuid_generate_v4\(\)" }/, schema)
end
end
+
+ def test_schema_dumper_for_uuid_primary_key_default_in_legacy_migration
+ @verbose_was = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.verbose = false
+
+ migration = Class.new(ActiveRecord::Migration[5.0]) do
+ def version; 101 end
+ def migrate(x)
+ create_table("pg_uuids_4", id: :uuid)
+ end
+ end.new
+ ActiveRecord::Migrator.new(:up, [migration]).migrate
+
+ schema = dump_table_schema "pg_uuids_4"
+ assert_match(/\bcreate_table "pg_uuids_4", id: :uuid, default: -> { "uuid_generate_v4\(\)" }/, schema)
+ ensure
+ drop_table "pg_uuids_4"
+ ActiveRecord::Migration.verbose = @verbose_was
+ end
end
class PostgresqlUUIDTestNilDefault < ActiveRecord::PostgreSQLTestCase
@@ -214,9 +290,9 @@ class PostgresqlUUIDTestNilDefault < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
setup do
- connection.create_table('pg_uuids', id: false) do |t|
+ connection.create_table("pg_uuids", id: false) do |t|
t.primary_key :id, :uuid, default: nil
- t.string 'name'
+ t.string "name"
end
end
@@ -224,19 +300,36 @@ class PostgresqlUUIDTestNilDefault < ActiveRecord::PostgreSQLTestCase
drop_table "pg_uuids"
end
- if ActiveRecord::Base.connection.supports_extensions?
- def test_id_allows_default_override_via_nil
- col_desc = connection.execute("SELECT pg_get_expr(d.adbin, d.adrelid) as default
- FROM pg_attribute a
- LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
- WHERE a.attname='id' AND a.attrelid = 'pg_uuids'::regclass").first
- assert_nil col_desc["default"]
- end
+ def test_id_allows_default_override_via_nil
+ col_desc = connection.execute("SELECT pg_get_expr(d.adbin, d.adrelid) as default
+ FROM pg_attribute a
+ LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
+ WHERE a.attname='id' AND a.attrelid = 'pg_uuids'::regclass").first
+ assert_nil col_desc["default"]
+ end
- def test_schema_dumper_for_uuid_primary_key_with_default_override_via_nil
- schema = dump_table_schema "pg_uuids"
- assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: nil/, schema)
- end
+ def test_schema_dumper_for_uuid_primary_key_with_default_override_via_nil
+ schema = dump_table_schema "pg_uuids"
+ assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: nil/, schema)
+ end
+
+ def test_schema_dumper_for_uuid_primary_key_with_default_nil_in_legacy_migration
+ @verbose_was = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.verbose = false
+
+ migration = Class.new(ActiveRecord::Migration[5.0]) do
+ def version; 101 end
+ def migrate(x)
+ create_table("pg_uuids_4", id: :uuid, default: nil)
+ end
+ end.new
+ ActiveRecord::Migrator.new(:up, [migration]).migrate
+
+ schema = dump_table_schema "pg_uuids_4"
+ assert_match(/\bcreate_table "pg_uuids_4", id: :uuid, default: nil/, schema)
+ ensure
+ drop_table "pg_uuids_4"
+ ActiveRecord::Migration.verbose = @verbose_was
end
end
@@ -244,51 +337,47 @@ class PostgresqlUUIDTestInverseOf < ActiveRecord::PostgreSQLTestCase
include PostgresqlUUIDHelper
class UuidPost < ActiveRecord::Base
- self.table_name = 'pg_uuid_posts'
+ self.table_name = "pg_uuid_posts"
has_many :uuid_comments, inverse_of: :uuid_post
end
class UuidComment < ActiveRecord::Base
- self.table_name = 'pg_uuid_comments'
+ self.table_name = "pg_uuid_comments"
belongs_to :uuid_post
end
setup do
connection.transaction do
- connection.create_table('pg_uuid_posts', id: :uuid) do |t|
- t.string 'title'
+ connection.create_table("pg_uuid_posts", id: :uuid, **uuid_default) do |t|
+ t.string "title"
end
- connection.create_table('pg_uuid_comments', id: :uuid) do |t|
+ connection.create_table("pg_uuid_comments", id: :uuid, **uuid_default) do |t|
t.references :uuid_post, type: :uuid
- t.string 'content'
+ t.string "content"
end
end
end
teardown do
- drop_table "pg_uuid_comments"
- drop_table "pg_uuid_posts"
+ drop_table "pg_uuid_comments"
+ drop_table "pg_uuid_posts"
end
- if ActiveRecord::Base.connection.supports_extensions?
- def test_collection_association_with_uuid
- post = UuidPost.create!
- comment = post.uuid_comments.create!
- assert post.uuid_comments.find(comment.id)
- end
-
- def test_find_with_uuid
- UuidPost.create!
- assert_raise ActiveRecord::RecordNotFound do
- UuidPost.find(123456)
- end
-
- end
+ def test_collection_association_with_uuid
+ post = UuidPost.create!
+ comment = post.uuid_comments.create!
+ assert post.uuid_comments.find(comment.id)
+ end
- def test_find_by_with_uuid
- UuidPost.create!
- assert_nil UuidPost.find_by(id: 789)
+ def test_find_with_uuid
+ UuidPost.create!
+ assert_raise ActiveRecord::RecordNotFound do
+ UuidPost.find(123456)
end
end
+ def test_find_by_with_uuid
+ UuidPost.create!
+ assert_nil UuidPost.find_by(id: 789)
+ end
end
diff --git a/activerecord/test/cases/adapters/postgresql/xml_test.rb b/activerecord/test/cases/adapters/postgresql/xml_test.rb
index add32699fa..71ead6f7f3 100644
--- a/activerecord/test/cases/adapters/postgresql/xml_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/xml_test.rb
@@ -1,28 +1,30 @@
-require 'cases/helper'
-require 'support/schema_dumping_helper'
+# frozen_string_literal: true
+
+require "cases/helper"
+require "support/schema_dumping_helper"
class PostgresqlXMLTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
class XmlDataType < ActiveRecord::Base
- self.table_name = 'xml_data_type'
+ self.table_name = "xml_data_type"
end
def setup
@connection = ActiveRecord::Base.connection
begin
@connection.transaction do
- @connection.create_table('xml_data_type') do |t|
- t.xml 'payload'
+ @connection.create_table("xml_data_type") do |t|
+ t.xml "payload"
end
end
rescue ActiveRecord::StatementInvalid
skip "do not test on PG without xml"
end
- @column = XmlDataType.columns_hash['payload']
+ @column = XmlDataType.columns_hash["payload"]
end
teardown do
- @connection.drop_table 'xml_data_type', if_exists: true
+ @connection.drop_table "xml_data_type", if_exists: true
end
def test_column
@@ -30,7 +32,7 @@ class PostgresqlXMLTest < ActiveRecord::PostgreSQLTestCase
end
def test_null_xml
- @connection.execute %q|insert into xml_data_type (payload) VALUES(null)|
+ @connection.execute "insert into xml_data_type (payload) VALUES(null)"
assert_nil XmlDataType.first.payload
end