# frozen_string_literal: true
require "cases/helper"
require "active_record/tasks/database_tasks"
if current_adapter?(:PostgreSQLAdapter)
module ActiveRecord
class PostgreSQLDBCreateTest < ActiveRecord::TestCase
def setup
@connection = Class.new { def create_database(*); end }.new
@configuration = {
"adapter" => "postgresql",
"database" => "my-app-db"
}
$stdout, @original_stdout = StringIO.new, $stdout
$stderr, @original_stderr = StringIO.new, $stderr
end
def teardown
$stdout, $stderr = @original_stdout, @original_stderr
end
def test_establishes_connection_to_postgresql_database
ActiveRecord::Base.stub(:connection, @connection) do
assert_called_with(
ActiveRecord::Base,
:establish_connection,
[
[
"adapter" => "postgresql",
"database" => "postgres",
"schema_search_path" => "public"
],
[
"adapter" => "postgresql",
"database" => "my-app-db"
]
]
) do
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
end
end
def test_creates_database_with_default_encoding
with_stubbed_connection_establish_connection do
assert_called_with(
@connection,
:create_database,
["my-app-db", @configuration.merge("encoding" => "utf8")]
) do
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
end
end
def test_creates_database_with_given_encoding
with_stubbed_connection_establish_connection do
assert_called_with(
@connection,
:create_database,
["my-app-db", @configuration.merge("encoding" => "latin")]
) do
ActiveRecord::Tasks::DatabaseTasks.create @configuration.
merge("encoding" => "latin")
end
end
end
def test_creates_database_with_given_collation_and_ctype
with_stubbed_connection_establish_connection do
assert_called_with(
@connection,
:create_database,
[
"my-app-db",
@configuration.merge(
"encoding" => "utf8",
"collation" => "ja_JP.UTF8",
"ctype" => "ja_JP.UTF8"
)
]
) do
ActiveRecord::Tasks::DatabaseTasks.create @configuration.
merge("collation" => "ja_JP.UTF8", "ctype" => "ja_JP.UTF8")
end
end
end
def test_establishes_connection_to_new_database
ActiveRecord::Base.stub(:connection, @connection) do
assert_called_with(
ActiveRecord::Base,
:establish_connection,
[
[
"adapter" => "postgresql",
"database" => "postgres",
"schema_search_path" => "public"
],
[
@configuration
]
]
) do
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
end
end
def test_db_create_with_error_prints_message
ActiveRecord::Base.stub(:connection, @connection) do
ActiveRecord::Base.stub(:establish_connection, -> * { raise Exception }) do
assert_raises(Exception) { ActiveRecord::Tasks::DatabaseTasks.create @configuration }
assert_match "Couldn't create '#{@configuration['database']}' database. Please check your configuration.", $stderr.string
end
end
end
def test_when_database_created_successfully_outputs_info_to_stdout
with_stubbed_connection_establish_connection do
ActiveRecord::Tasks::DatabaseTasks.create @configuration
assert_equal "Created database 'my-app-db'\n", $stdout.string
end
end
def test_create_when_database_exists_outputs_info_to_stderr
with_stubbed_connection_establish_connection do
ActiveRecord::Base.connection.stub(
:create_database,
proc { raise ActiveRecord::DatabaseAlreadyExists }
) do
ActiveRecord::Tasks::DatabaseTasks.create @configuration
assert_equal "Database 'my-app-db' already exists\n", $stderr.string
end
end
end
private
def with_stubbed_connection_establish_connection
ActiveRecord::Base.stub(:connection, @connection) do
ActiveRecord::Base.stub(:establish_connection, nil) do
yield
end
end
end
end
class PostgreSQLDBDropTest < ActiveRecord::TestCase
def setup
@connection = Class.new { def drop_database(*); end }.new
@configuration = {
"adapter" => "postgresql",
"database" => "my-app-db"
}
$stdout, @original_stdout = StringIO.new, $stdout
$stderr, @original_stderr = StringIO.new, $stderr
end
def teardown
$stdout, $stderr = @original_stdout, @original_stderr
end
def test_establishes_connection_to_postgresql_database
ActiveRecord::Base.stub(:connection, @connection) do
assert_called_with(
ActiveRecord::Base,
:establish_connection,
[
"adapter" => "postgresql",
"database" => "postgres",
"schema_search_path" => "public"
]
) do
ActiveRecord::Tasks::DatabaseTasks.drop @configuration
end
end
end
def test_drops_database
with_stubbed_connection_establish_connection do
assert_called_with(
@connection,
:drop_database,
["my-app-db"]
) do
ActiveRecord::Tasks::DatabaseTasks.drop @configuration
end
end
end
def test_when_database_dropped_successfully_outputs_info_to_stdout
with_stubbed_connection_establish_connection do
ActiveRecord::Tasks::DatabaseTasks.drop @configuration
assert_equal "Dropped database 'my-app-db'\n", $stdout.string
end
end
private
def with_stubbed_connection_establish_connection
ActiveRecord::Base.stub(:connection, @connection) do
ActiveRecord::Base.stub(:establish_connection, nil) do
yield
end
end
end
end
class PostgreSQLPurgeTest < ActiveRecord::TestCase
def setup
@connection = Class.new do
def create_database(*); end
def drop_database(*); end
end.new
@configuration = {
"adapter" => "postgresql",
"database" => "my-app-db"
}
end
def test_clears_active_connections
with_stubbed_connection do
ActiveRecord::Base.stub(:establish_connection, nil) do
assert_called(ActiveRecord::Base, :clear_active_connections!) do
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
end
end
end
def test_establishes_connection_to_postgresql_database
with_stubbed_connection do
assert_called_with(
ActiveRecord::Base,
:establish_connection,
[
[
"adapter" => "postgresql",
"database" => "postgres",
"schema_search_path" => "public"
],
[
"adapter" => "postgresql",
"database" => "my-app-db"
]
]
) do
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
end
end
def test_drops_database
with_stubbed_connection do
ActiveRecord::Base.stub(:establish_connection, nil) do
assert_called_with(@connection, :drop_database, ["my-app-db"]) do
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
end
end
end
def test_creates_database
with_stubbed_connection do
ActiveRecord::Base.stub(:establish_connection, nil) do
assert_called_with(
@connection,
:create_database,
["my-app-db", @configuration.merge("encoding" => "utf8")]
) do
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
end
end
end
def test_establishes_connection
with_stubbed_connection do
assert_called_with(
ActiveRecord::Base,
:establish_connection,
[
[
"adapter" => "postgresql",
"database" => "postgres",
"schema_search_path" => "public"
],
[
@configuration
]
]
) do
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
end
end
private
def with_stubbed_connection
ActiveRecord::Base.stub(:connection, @connection) do
yield
end
end
end
class PostgreSQLDBCharsetTest < ActiveRecord::TestCase
def setup
@connection = Class.new do
def create_database(*); end
def encoding; end
end.new
@configuration = {
"adapter" => "postgresql",
"database" => "my-app-db"
}
end
def test_db_retrieves_charset
ActiveRecord::Base.stub(:connection, @connection) do
assert_called(@connection, :encoding) do
ActiveRecord::Tasks::DatabaseTasks.charset @configuration
end
end
end
end
class PostgreSQLDBCollationTest < ActiveRecord::TestCase
def setup
@connection = Class.new { def collation; end }.new
@configuration = {
"adapter" => "postgresql",
"database" => "my-app-db"
}
end
def test_db_retrieves_collation
ActiveRecord::Base.stub(:connection, @connection) do
assert_called(@connection, :collation) do
ActiveRecord::Tasks::DatabaseTasks.collation @configuration
end
end
end
end
class PostgreSQLStructureDumpTest < ActiveRecord::TestCase
def setup
@configuration = {
"adapter" => "postgresql",
"database" => "my-app-db"
}
@filename = "/tmp/awesome-file.sql"
FileUtils.touch(@filename)
end
def teardown
FileUtils.rm_f(@filename)
end
def test_structure_dump
assert_called_with(
Kernel,
:system,
["pg_dump", "-s", "-x", "-O", "-f", @filename, "my-app-db"],
returns: true
) do
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
end
end
def test_structure_dump_header_comments_removed
Kernel.stub(:system, true) do
File.write(@filename, "-- header comment\n\n-- more header comment\n statement \n-- lower comment\n")
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
assert_equal [" statement \n", "-- lower comment\n"], File.readlines(@filename).first(2)
end
end
def test_structure_dump_with_extra_flags
expected_command = ["pg_dump", "-s", "-x", "-O", "-f", @filename, "--noop", "my-app-db"]
assert_called_with(Kernel, :system, expected_command, returns: true) do
with_structure_dump_flags(["--noop"]) do
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
end
end
end
def test_structure_dump_with_ignore_tables
assert_called(
ActiveRecord::SchemaDumper,
:ignore_tables,
returns: ["foo", "bar"]
) do
assert_called_with(
Kernel,
:system,
["pg_dump", "-s", "-x", "-O", "-f", @filename, "-T", "foo", "-T", "bar", "my-app-db"],
returns: true
) do
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
end
end
end
def test_structure_dump_with_schema_search_path
@configuration["schema_search_path"] = "foo,bar"
assert_called_with(
Kernel,
:system,
["pg_dump", "-s", "-x", "-O", "-f", @filename, "--schema=foo", "--schema=bar", "my-app-db"],
returns: true
) do
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
end
end
def test_structure_dump_with_schema_search_path_and_dump_schemas_all
@configuration["schema_search_path"] = "foo,bar"
assert_called_with(
Kernel,
:system,
["pg_dump", "-s", "-x", "-O", "-f", @filename, "my-app-db"],
returns: true
) do
with_dump_schemas(:all) do
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
end
end
end
def test_structure_dump_with_dump_schemas_string
assert_called_with(
Kernel,
:system,
["pg_dump", "-s", "-x", "-O", "-f", @filename, "--schema=foo", "--schema=bar", "my-app-db"],
returns: true
) do
with_dump_schemas("foo,bar") do
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
end
end
end
def test_structure_dump_execution_fails
filename = "awesome-file.sql"
assert_called_with(
Kernel,
:system,
["pg_dump", "-s", "-x", "-O", "-f", filename, "my-app-db"],
returns: nil
) do
e = assert_raise(RuntimeError) do
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename)
end
assert_match("failed to execute:", e.message)
end
end
private
def with_dump_schemas(value, &block)
old_dump_schemas = ActiveRecord::Base.dump_schemas
ActiveRecord::Base.dump_schemas = value
yield
ensure
ActiveRecord::Base.dump_schemas = old_dump_schemas
end
def with_structure_dump_flags(flags)
old = ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = flags
yield
ensure
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = old
end
end
class PostgreSQLStructureLoadTest < ActiveRecord::TestCase
def setup
@configuration = {
"adapter" => "postgresql",
"database" => "my-app-db"
}
end
def test_structure_load
filename = "awesome-file.sql"
assert_called_with(
Kernel,
:system,
["psql", "-v", "ON_ERROR_STOP=1", "-q", "-X", "-f", filename, @configuration["database"]],
returns: true
) do
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
end
end
def test_structure_load_with_extra_flags
filename = "awesome-file.sql"
expected_command = ["psql", "-v", "ON_ERROR_STOP=1", "-q", "-X", "-f", filename, "--noop", @configuration["database"]]
assert_called_with(Kernel, :system, expected_command, returns: true) do
with_structure_load_flags(["--noop"]) do
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
end
end
end
def test_structure_load_accepts_path_with_spaces
filename = "awesome file.sql"
assert_called_with(
Kernel,
:system,
["psql", "-v", "ON_ERROR_STOP=1", "-q", "-X", "-f", filename, @configuration["database"]],
returns: true
) do
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
end
end
private
def with_structure_load_flags(flags)
old = ActiveRecord::Tasks::DatabaseTasks.structure_load_flags
ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = flags
yield
ensure
ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = old
end
end
end
end