mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
3f4964299a
We've replaced most querues using DROP TABLE in our tests already. This patch replaces the last couple calls.
388 lines
11 KiB
Ruby
388 lines
11 KiB
Ruby
require "cases/helper"
|
|
require "cases/migration/helper"
|
|
|
|
class MigratorTest < ActiveRecord::TestCase
|
|
self.use_transactional_fixtures = false
|
|
|
|
# Use this class to sense if migrations have gone
|
|
# up or down.
|
|
class Sensor < ActiveRecord::Migration
|
|
attr_reader :went_up, :went_down
|
|
|
|
def initialize name = self.class.name, version = nil
|
|
super
|
|
@went_up = false
|
|
@went_down = false
|
|
end
|
|
|
|
def up; @went_up = true; end
|
|
def down; @went_down = true; end
|
|
end
|
|
|
|
def setup
|
|
super
|
|
ActiveRecord::SchemaMigration.create_table
|
|
ActiveRecord::SchemaMigration.delete_all rescue nil
|
|
@verbose_was = ActiveRecord::Migration.verbose
|
|
ActiveRecord::Migration.message_count = 0
|
|
ActiveRecord::Migration.class_eval do
|
|
undef :puts
|
|
def puts(*)
|
|
ActiveRecord::Migration.message_count += 1
|
|
end
|
|
end
|
|
end
|
|
|
|
teardown do
|
|
ActiveRecord::SchemaMigration.delete_all rescue nil
|
|
ActiveRecord::Migration.verbose = @verbose_was
|
|
ActiveRecord::Migration.class_eval do
|
|
undef :puts
|
|
def puts(*)
|
|
super
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_migrator_with_duplicate_names
|
|
assert_raises(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do
|
|
list = [ActiveRecord::Migration.new('Chunky'), ActiveRecord::Migration.new('Chunky')]
|
|
ActiveRecord::Migrator.new(:up, list)
|
|
end
|
|
end
|
|
|
|
def test_migrator_with_duplicate_versions
|
|
assert_raises(ActiveRecord::DuplicateMigrationVersionError) do
|
|
list = [ActiveRecord::Migration.new('Foo', 1), ActiveRecord::Migration.new('Bar', 1)]
|
|
ActiveRecord::Migrator.new(:up, list)
|
|
end
|
|
end
|
|
|
|
def test_migrator_with_missing_version_numbers
|
|
assert_raises(ActiveRecord::UnknownMigrationVersionError) do
|
|
list = [ActiveRecord::Migration.new('Foo', 1), ActiveRecord::Migration.new('Bar', 2)]
|
|
ActiveRecord::Migrator.new(:up, list, 3).run
|
|
end
|
|
end
|
|
|
|
def test_finds_migrations
|
|
migrations = ActiveRecord::Migrator.migrations(MIGRATIONS_ROOT + "/valid")
|
|
|
|
[[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
|
|
assert_equal migrations[i].version, pair.first
|
|
assert_equal migrations[i].name, pair.last
|
|
end
|
|
end
|
|
|
|
def test_finds_migrations_in_subdirectories
|
|
migrations = ActiveRecord::Migrator.migrations(MIGRATIONS_ROOT + "/valid_with_subdirectories")
|
|
|
|
[[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i|
|
|
assert_equal migrations[i].version, pair.first
|
|
assert_equal migrations[i].name, pair.last
|
|
end
|
|
end
|
|
|
|
def test_finds_migrations_from_two_directories
|
|
directories = [MIGRATIONS_ROOT + '/valid_with_timestamps', MIGRATIONS_ROOT + '/to_copy_with_timestamps']
|
|
migrations = ActiveRecord::Migrator.migrations directories
|
|
|
|
[[20090101010101, "PeopleHaveHobbies"],
|
|
[20090101010202, "PeopleHaveDescriptions"],
|
|
[20100101010101, "ValidWithTimestampsPeopleHaveLastNames"],
|
|
[20100201010101, "ValidWithTimestampsWeNeedReminders"],
|
|
[20100301010101, "ValidWithTimestampsInnocentJointable"]].each_with_index do |pair, i|
|
|
assert_equal pair.first, migrations[i].version
|
|
assert_equal pair.last, migrations[i].name
|
|
end
|
|
end
|
|
|
|
def test_finds_migrations_in_numbered_directory
|
|
migrations = ActiveRecord::Migrator.migrations [MIGRATIONS_ROOT + '/10_urban']
|
|
assert_equal 9, migrations[0].version
|
|
assert_equal 'AddExpressions', migrations[0].name
|
|
end
|
|
|
|
def test_relative_migrations
|
|
list = Dir.chdir(MIGRATIONS_ROOT) do
|
|
ActiveRecord::Migrator.migrations("valid")
|
|
end
|
|
|
|
migration_proxy = list.find { |item|
|
|
item.name == 'ValidPeopleHaveLastNames'
|
|
}
|
|
assert migration_proxy, 'should find pending migration'
|
|
end
|
|
|
|
def test_finds_pending_migrations
|
|
ActiveRecord::SchemaMigration.create!(:version => '1')
|
|
migration_list = [ActiveRecord::Migration.new('foo', 1), ActiveRecord::Migration.new('bar', 3)]
|
|
migrations = ActiveRecord::Migrator.new(:up, migration_list).pending_migrations
|
|
|
|
assert_equal 1, migrations.size
|
|
assert_equal migration_list.last, migrations.first
|
|
end
|
|
|
|
def test_migrator_interleaved_migrations
|
|
pass_one = [Sensor.new('One', 1)]
|
|
|
|
ActiveRecord::Migrator.new(:up, pass_one).migrate
|
|
assert pass_one.first.went_up
|
|
assert_not pass_one.first.went_down
|
|
|
|
pass_two = [Sensor.new('One', 1), Sensor.new('Three', 3)]
|
|
ActiveRecord::Migrator.new(:up, pass_two).migrate
|
|
assert_not pass_two[0].went_up
|
|
assert pass_two[1].went_up
|
|
assert pass_two.all? { |x| !x.went_down }
|
|
|
|
pass_three = [Sensor.new('One', 1),
|
|
Sensor.new('Two', 2),
|
|
Sensor.new('Three', 3)]
|
|
|
|
ActiveRecord::Migrator.new(:down, pass_three).migrate
|
|
assert pass_three[0].went_down
|
|
assert_not pass_three[1].went_down
|
|
assert pass_three[2].went_down
|
|
end
|
|
|
|
def test_up_calls_up
|
|
migrations = [Sensor.new(nil, 0), Sensor.new(nil, 1), Sensor.new(nil, 2)]
|
|
ActiveRecord::Migrator.new(:up, migrations).migrate
|
|
assert migrations.all?(&:went_up)
|
|
assert migrations.all? { |m| !m.went_down }
|
|
assert_equal 2, ActiveRecord::Migrator.current_version
|
|
end
|
|
|
|
def test_down_calls_down
|
|
test_up_calls_up
|
|
|
|
migrations = [Sensor.new(nil, 0), Sensor.new(nil, 1), Sensor.new(nil, 2)]
|
|
ActiveRecord::Migrator.new(:down, migrations).migrate
|
|
assert migrations.all? { |m| !m.went_up }
|
|
assert migrations.all?(&:went_down)
|
|
assert_equal 0, ActiveRecord::Migrator.current_version
|
|
end
|
|
|
|
def test_current_version
|
|
ActiveRecord::SchemaMigration.create!(:version => '1000')
|
|
assert_equal 1000, ActiveRecord::Migrator.current_version
|
|
end
|
|
|
|
def test_migrator_one_up
|
|
calls, migrations = sensors(3)
|
|
|
|
ActiveRecord::Migrator.new(:up, migrations, 1).migrate
|
|
assert_equal [[:up, 1]], calls
|
|
calls.clear
|
|
|
|
ActiveRecord::Migrator.new(:up, migrations, 2).migrate
|
|
assert_equal [[:up, 2]], calls
|
|
end
|
|
|
|
def test_migrator_one_down
|
|
calls, migrations = sensors(3)
|
|
|
|
ActiveRecord::Migrator.new(:up, migrations).migrate
|
|
assert_equal [[:up, 1], [:up, 2], [:up, 3]], calls
|
|
calls.clear
|
|
|
|
ActiveRecord::Migrator.new(:down, migrations, 1).migrate
|
|
|
|
assert_equal [[:down, 3], [:down, 2]], calls
|
|
end
|
|
|
|
def test_migrator_one_up_one_down
|
|
calls, migrations = sensors(3)
|
|
|
|
ActiveRecord::Migrator.new(:up, migrations, 1).migrate
|
|
assert_equal [[:up, 1]], calls
|
|
calls.clear
|
|
|
|
ActiveRecord::Migrator.new(:down, migrations, 0).migrate
|
|
assert_equal [[:down, 1]], calls
|
|
end
|
|
|
|
def test_migrator_double_up
|
|
calls, migrations = sensors(3)
|
|
assert_equal(0, ActiveRecord::Migrator.current_version)
|
|
|
|
ActiveRecord::Migrator.new(:up, migrations, 1).migrate
|
|
assert_equal [[:up, 1]], calls
|
|
calls.clear
|
|
|
|
ActiveRecord::Migrator.new(:up, migrations, 1).migrate
|
|
assert_equal [], calls
|
|
end
|
|
|
|
def test_migrator_double_down
|
|
calls, migrations = sensors(3)
|
|
|
|
assert_equal(0, ActiveRecord::Migrator.current_version)
|
|
|
|
ActiveRecord::Migrator.new(:up, migrations, 1).run
|
|
assert_equal [[:up, 1]], calls
|
|
calls.clear
|
|
|
|
ActiveRecord::Migrator.new(:down, migrations, 1).run
|
|
assert_equal [[:down, 1]], calls
|
|
calls.clear
|
|
|
|
ActiveRecord::Migrator.new(:down, migrations, 1).run
|
|
assert_equal [], calls
|
|
|
|
assert_equal(0, ActiveRecord::Migrator.current_version)
|
|
end
|
|
|
|
def test_migrator_verbosity
|
|
_, migrations = sensors(3)
|
|
|
|
ActiveRecord::Migrator.new(:up, migrations, 1).migrate
|
|
assert_not_equal 0, ActiveRecord::Migration.message_count
|
|
|
|
ActiveRecord::Migration.message_count = 0
|
|
|
|
ActiveRecord::Migrator.new(:down, migrations, 0).migrate
|
|
assert_not_equal 0, ActiveRecord::Migration.message_count
|
|
end
|
|
|
|
def test_migrator_verbosity_off
|
|
_, migrations = sensors(3)
|
|
|
|
ActiveRecord::Migration.message_count = 0
|
|
ActiveRecord::Migration.verbose = false
|
|
ActiveRecord::Migrator.new(:up, migrations, 1).migrate
|
|
assert_equal 0, ActiveRecord::Migration.message_count
|
|
ActiveRecord::Migrator.new(:down, migrations, 0).migrate
|
|
assert_equal 0, ActiveRecord::Migration.message_count
|
|
end
|
|
|
|
def test_target_version_zero_should_run_only_once
|
|
calls, migrations = sensors(3)
|
|
|
|
# migrate up to 1
|
|
ActiveRecord::Migrator.new(:up, migrations, 1).migrate
|
|
assert_equal [[:up, 1]], calls
|
|
calls.clear
|
|
|
|
# migrate down to 0
|
|
ActiveRecord::Migrator.new(:down, migrations, 0).migrate
|
|
assert_equal [[:down, 1]], calls
|
|
calls.clear
|
|
|
|
# migrate down to 0 again
|
|
ActiveRecord::Migrator.new(:down, migrations, 0).migrate
|
|
assert_equal [], calls
|
|
end
|
|
|
|
def test_migrator_going_down_due_to_version_target
|
|
calls, migrator = migrator_class(3)
|
|
|
|
migrator.up("valid", 1)
|
|
assert_equal [[:up, 1]], calls
|
|
calls.clear
|
|
|
|
migrator.migrate("valid", 0)
|
|
assert_equal [[:down, 1]], calls
|
|
calls.clear
|
|
|
|
migrator.migrate("valid")
|
|
assert_equal [[:up, 1], [:up, 2], [:up, 3]], calls
|
|
end
|
|
|
|
def test_migrator_rollback
|
|
_, migrator = migrator_class(3)
|
|
|
|
migrator.migrate("valid")
|
|
assert_equal(3, ActiveRecord::Migrator.current_version)
|
|
|
|
migrator.rollback("valid")
|
|
assert_equal(2, ActiveRecord::Migrator.current_version)
|
|
|
|
migrator.rollback("valid")
|
|
assert_equal(1, ActiveRecord::Migrator.current_version)
|
|
|
|
migrator.rollback("valid")
|
|
assert_equal(0, ActiveRecord::Migrator.current_version)
|
|
|
|
migrator.rollback("valid")
|
|
assert_equal(0, ActiveRecord::Migrator.current_version)
|
|
end
|
|
|
|
def test_migrator_db_has_no_schema_migrations_table
|
|
_, migrator = migrator_class(3)
|
|
|
|
ActiveRecord::Base.connection.drop_table "schema_migrations", if_exists: true
|
|
assert_not ActiveRecord::Base.connection.table_exists?('schema_migrations')
|
|
migrator.migrate("valid", 1)
|
|
assert ActiveRecord::Base.connection.table_exists?('schema_migrations')
|
|
end
|
|
|
|
def test_migrator_forward
|
|
_, migrator = migrator_class(3)
|
|
migrator.migrate("/valid", 1)
|
|
assert_equal(1, ActiveRecord::Migrator.current_version)
|
|
|
|
migrator.forward("/valid", 2)
|
|
assert_equal(3, ActiveRecord::Migrator.current_version)
|
|
|
|
migrator.forward("/valid")
|
|
assert_equal(3, ActiveRecord::Migrator.current_version)
|
|
end
|
|
|
|
def test_only_loads_pending_migrations
|
|
# migrate up to 1
|
|
ActiveRecord::SchemaMigration.create!(:version => '1')
|
|
|
|
calls, migrator = migrator_class(3)
|
|
migrator.migrate("valid", nil)
|
|
|
|
assert_equal [[:up, 2], [:up, 3]], calls
|
|
end
|
|
|
|
def test_get_all_versions
|
|
_, migrator = migrator_class(3)
|
|
|
|
migrator.migrate("valid")
|
|
assert_equal([1,2,3], ActiveRecord::Migrator.get_all_versions)
|
|
|
|
migrator.rollback("valid")
|
|
assert_equal([1,2], ActiveRecord::Migrator.get_all_versions)
|
|
|
|
migrator.rollback("valid")
|
|
assert_equal([1], ActiveRecord::Migrator.get_all_versions)
|
|
|
|
migrator.rollback("valid")
|
|
assert_equal([], ActiveRecord::Migrator.get_all_versions)
|
|
end
|
|
|
|
private
|
|
def m(name, version)
|
|
x = Sensor.new name, version
|
|
x.extend(Module.new {
|
|
define_method(:up) { yield(:up, x); super() }
|
|
define_method(:down) { yield(:down, x); super() }
|
|
}) if block_given?
|
|
end
|
|
|
|
def sensors(count)
|
|
calls = []
|
|
migrations = count.times.map { |i|
|
|
m(nil, i + 1) { |c,migration|
|
|
calls << [c, migration.version]
|
|
}
|
|
}
|
|
[calls, migrations]
|
|
end
|
|
|
|
def migrator_class(count)
|
|
calls, migrations = sensors(count)
|
|
|
|
migrator = Class.new(ActiveRecord::Migrator).extend(Module.new {
|
|
define_method(:migrations) { |paths|
|
|
migrations
|
|
}
|
|
})
|
|
[calls, migrator]
|
|
end
|
|
end
|