Files
prism/test/test_cli_db.rb
T

175 lines
5.4 KiB
Ruby

require 'minitest/autorun'
require 'prism'
require 'stringio'
require 'tmpdir'
require 'fileutils'
class CliDbTest < Minitest::Test
def setup
@workdir = Dir.mktmpdir('prism-cli-db')
@cli = Prism::Cli.new(@workdir)
@database = 'db/test.pstore'
FileUtils.mkdir_p(File.join(@workdir, 'db', 'migrate'))
end
def teardown
FileUtils.remove_entry(@workdir)
end
def write_migration(version, class_name, body)
path = File.join(@workdir, 'db', 'migrate', "#{version}_#{Prism::Inflector.underscore(class_name)}.rb")
File.write(path, <<~RUBY)
class #{class_name} < Prism::Orm::Migration
#{body}
end
RUBY
path
end
def widgets_migration(version = '20260101000001')
write_migration(version, 'CreateWidgetsForCliDbTest', <<~RUBY)
def up
create_table :widgets_for_cli_db_test do |t|
t.string :name
end
end
def down
drop_table :widgets_for_cli_db_test
end
RUBY
end
def gadgets_migration(version = '20260101000002')
write_migration(version, 'CreateGadgetsForCliDbTest', <<~RUBY)
def up
create_table :gadgets_for_cli_db_test do |t|
t.string :label
end
end
def down
drop_table :gadgets_for_cli_db_test
end
RUBY
end
def store
Prism::Orm::Store.new(File.join(@workdir, @database))
end
def test_db_migrate_applies_pending_migrations_and_reports_them
widgets_migration
out = StringIO.new
applied = @cli.db_migrate(["--database=#{@database}"], out: out)
assert_equal ['20260101000001'], applied
assert_includes out.string, 'migrated 20260101000001'
assert store.table_exists?(:widgets_for_cli_db_test)
end
def test_db_migrate_with_nothing_pending_reports_that_instead_of_erroring
widgets_migration
@cli.db_migrate(["--database=#{@database}"], out: StringIO.new)
out = StringIO.new
applied = @cli.db_migrate(["--database=#{@database}"], out: out)
assert_empty applied
assert_includes out.string, 'no pending migrations'
end
def test_db_migrate_dispatches_through_run
widgets_migration
capture_io { @cli.run(['db:migrate', "--database=#{@database}"]) }
assert store.table_exists?(:widgets_for_cli_db_test)
end
def test_db_rollback_defaults_to_one_step
widgets_migration
gadgets_migration
@cli.db_migrate(["--database=#{@database}"], out: StringIO.new)
assert store.table_exists?(:gadgets_for_cli_db_test)
out = StringIO.new
reverted = @cli.db_rollback(["--database=#{@database}"], out: out)
assert_equal ['20260101000002'], reverted
assert_includes out.string, 'rolled back 20260101000002'
refute store.table_exists?(:gadgets_for_cli_db_test)
assert store.table_exists?(:widgets_for_cli_db_test), 'earlier migration must survive a single-step rollback'
end
def test_db_rollback_honors_explicit_step_count
widgets_migration
gadgets_migration
@cli.db_migrate(["--database=#{@database}"], out: StringIO.new)
reverted = @cli.db_rollback(["--database=#{@database}", '--step=2'], out: StringIO.new)
assert_equal ['20260101000002', '20260101000001'], reverted
refute store.table_exists?(:gadgets_for_cli_db_test)
refute store.table_exists?(:widgets_for_cli_db_test)
end
def test_db_rollback_with_nothing_applied_reports_that_instead_of_erroring
widgets_migration
out = StringIO.new
reverted = @cli.db_rollback(["--database=#{@database}"], out: out)
assert_empty reverted
assert_includes out.string, 'nothing to roll back'
end
def test_db_status_marks_applied_migrations_up_and_the_rest_down
widgets_migration
gadgets_migration
@cli.db_migrate(["--database=#{@database}"], out: StringIO.new)
@cli.db_rollback(["--database=#{@database}"], out: StringIO.new)
out = StringIO.new
status = @cli.db_status(["--database=#{@database}"], out: out)
assert_equal [['20260101000001', true], ['20260101000002', false]],
status.map { |entry, applied| [entry.version, applied] }
assert_match(/up\s+20260101000001\s+create_widgets_for_cli_db_test/, out.string)
assert_match(/down\s+20260101000002\s+create_gadgets_for_cli_db_test/, out.string)
end
def test_db_status_with_no_migration_files_prints_only_the_header
out = StringIO.new
status = @cli.db_status(["--database=#{@database}"], out: out)
assert_empty status
assert_equal "STATUS VERSION NAME\n", out.string
end
def test_db_commands_use_the_migrations_flag_to_find_a_custom_directory
FileUtils.mkdir_p(File.join(@workdir, 'other_migrations'))
File.write(File.join(@workdir, 'other_migrations', '20260101000003_create_thingies_for_cli_db_test.rb'), <<~RUBY)
class CreateThingiesForCliDbTest < Prism::Orm::Migration
def up
create_table :thingies_for_cli_db_test do |t|
t.string :name
end
end
def down
drop_table :thingies_for_cli_db_test
end
end
RUBY
applied = @cli.db_migrate(["--database=#{@database}", '--migrations=other_migrations'], out: StringIO.new)
assert_equal ['20260101000003'], applied
assert store.table_exists?(:thingies_for_cli_db_test)
end
def test_db_options_reject_unknown_flags
assert_raises(Prism::Cli::UsageError) { @cli.db_migrate(['--bogus=1']) }
assert_raises(Prism::Cli::UsageError) { @cli.db_rollback(['--bogus=1']) }
assert_raises(Prism::Cli::UsageError) { @cli.db_status(['--bogus=1']) }
end
end