class MigrationTest

Private Class Methods

base_class() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 689
def self.base_class; self; end
name() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 688
def self.name; "Reminder"; end

Public Instance Methods

connection() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 147
def connection
  Class.new {
    def create_table; "hi mom!"; end
  }.new
end
create_table() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 149
def create_table; "hi mom!"; end
migrate(x) click to toggle source
# File activerecord/test/cases/migration_test.rb, line 277
def migrate(x)
  add_column "people", "last_name", :string
  raise "Something broke"
end
setup() click to toggle source
Calls superclass method
# File activerecord/test/cases/migration_test.rb, line 34
def setup
  super
  %w(reminders people_reminders prefix_reminders_suffix p_things_s).each do |table|
    Reminder.connection.drop_table(table) rescue nil
  end
  Reminder.reset_column_information
  @verbose_was, ActiveRecord::Migration.verbose = ActiveRecord::Migration.verbose, false
  ActiveRecord::Base.connection.schema_cache.clear!
end
test_add_drop_table_with_prefix_and_suffix() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 473
def test_add_drop_table_with_prefix_and_suffix
  assert !Reminder.table_exists?
  ActiveRecord::Base.table_name_prefix = "prefix_"
  ActiveRecord::Base.table_name_suffix = "_suffix"
  Reminder.reset_table_name
  Reminder.reset_sequence_name
  Reminder.reset_column_information
  WeNeedReminders.up
  assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
  assert_equal "hello world", Reminder.first.content

  WeNeedReminders.down
  assert_raise(ActiveRecord::StatementInvalid) { Reminder.first }
ensure
  Reminder.reset_sequence_name
end
test_add_table_with_decimals() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 157
def test_add_table_with_decimals
  Person.connection.drop_table :big_numbers rescue nil

  assert !BigNumber.table_exists?
  GiveMeBigNumbers.up
  BigNumber.reset_column_information

  assert BigNumber.create(
    bank_balance: 1586.43,
    big_bank_balance: BigDecimal("1000234000567.95"),
    world_population: 6000000000,
    my_house_population: 3,
    value_of_e: BigDecimal("2.7182818284590452353602875")
  )

  b = BigNumber.first
  assert_not_nil b

  assert_not_nil b.bank_balance
  assert_not_nil b.big_bank_balance
  assert_not_nil b.world_population
  assert_not_nil b.my_house_population
  assert_not_nil b.value_of_e

  # TODO: set world_population >= 2**62 to cover 64-bit platforms and test
  # is_a?(Bignum)
  assert_kind_of Integer, b.world_population
  assert_equal 6000000000, b.world_population
  assert_kind_of Integer, b.my_house_population
  assert_equal 3, b.my_house_population
  assert_kind_of BigDecimal, b.bank_balance
  assert_equal BigDecimal("1586.43"), b.bank_balance
  assert_kind_of BigDecimal, b.big_bank_balance
  assert_equal BigDecimal("1000234000567.95"), b.big_bank_balance

  # This one is fun. The 'value_of_e' field is defined as 'DECIMAL' with
  # precision/scale explicitly left out.  By the SQL standard, numbers
  # assigned to this field should be truncated but that's seldom respected.
  if current_adapter?(:PostgreSQLAdapter)
    # - PostgreSQL changes the SQL spec on columns declared simply as
    # "decimal" to something more useful: instead of being given a scale
    # of 0, they take on the compile-time limit for precision and scale,
    # so the following should succeed unless you have used really wacky
    # compilation options
    assert_kind_of BigDecimal, b.value_of_e
    assert_equal BigDecimal("2.7182818284590452353602875"), b.value_of_e
  elsif current_adapter?(:SQLite3Adapter)
    # - SQLite3 stores a float, in violation of SQL
    assert_kind_of BigDecimal, b.value_of_e
    assert_in_delta BigDecimal("2.71828182845905"), b.value_of_e, 0.00000000000001
  else
    # - SQL standard is an integer
    assert_kind_of Integer, b.value_of_e
    assert_equal 2, b.value_of_e
  end

  GiveMeBigNumbers.down
  assert_raise(ActiveRecord::StatementInvalid) { BigNumber.first }
end
test_allows_sqlite3_rollback_on_invalid_column_type() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 530
def test_allows_sqlite3_rollback_on_invalid_column_type
  Person.connection.create_table :something, force: true do |t|
    t.column :number, :integer
    t.column :name, :string
    t.column :foo, :bar
  end
  assert Person.connection.column_exists?(:something, :foo)
  assert_nothing_raised { Person.connection.remove_column :something, :foo, :bar }
  assert !Person.connection.column_exists?(:something, :foo)
  assert Person.connection.column_exists?(:something, :name)
  assert Person.connection.column_exists?(:something, :number)
ensure
  Person.connection.drop_table :something, if_exists: true
end
test_any_migrations() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 109
def test_any_migrations
  old_path = ActiveRecord::Migrator.migrations_paths
  ActiveRecord::Migrator.migrations_paths = MIGRATIONS_ROOT + "/valid"

  assert ActiveRecord::Migrator.any_migrations?

  ActiveRecord::Migrator.migrations_paths = MIGRATIONS_ROOT + "/empty"

  assert_not ActiveRecord::Migrator.any_migrations?
ensure
  ActiveRecord::Migrator.migrations_paths = old_path
end
test_create_table_with_binary_column() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 490
def test_create_table_with_binary_column
  assert_nothing_raised {
    Person.connection.create_table :binary_testings do |t|
      t.column "data", :binary, null: false
    end
  }

  columns = Person.connection.columns(:binary_testings)
  data_column = columns.detect { |c| c.name == "data" }

  assert_nil data_column.default
ensure
  Person.connection.drop_table :binary_testings, if_exists: true
end
test_create_table_with_custom_sequence_name() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 547
def test_create_table_with_custom_sequence_name
  # table name is 29 chars, the standard sequence name will
  # be 33 chars and should be shortened
  assert_nothing_raised do
    begin
      Person.connection.create_table :table_with_name_thats_just_ok do |t|
        t.column :foo, :string, null: false
      end
    ensure
      Person.connection.drop_table :table_with_name_thats_just_ok rescue nil
    end
  end

  # should be all good w/ a custom sequence name
  assert_nothing_raised do
    begin
      Person.connection.create_table :table_with_name_thats_just_ok,
        sequence_name: "suitably_short_seq" do |t|
        t.column :foo, :string, null: false
      end

      Person.connection.execute("select suitably_short_seq.nextval from dual")

    ensure
      Person.connection.drop_table :table_with_name_thats_just_ok,
        sequence_name: "suitably_short_seq" rescue nil
    end
  end

  # confirm the custom sequence got dropped
  assert_raise(ActiveRecord::StatementInvalid) do
    Person.connection.execute("select suitably_short_seq.nextval from dual")
  end
end
test_create_table_with_force_true_does_not_drop_nonexisting_table() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 126
def test_create_table_with_force_true_does_not_drop_nonexisting_table
  # using a copy as we need the drop_table method to
  # continue to work for the ensure block of the test
  temp_conn = Person.connection.dup

  assert_not_equal temp_conn, Person.connection

  temp_conn.create_table :testings2, force: true do |t|
    t.column :foo, :string
  end
ensure
  Person.connection.drop_table :testings2, if_exists: true
end
test_create_table_with_query() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 506
def test_create_table_with_query
  Person.connection.create_table :table_from_query_testings, as: "SELECT id FROM people WHERE id = 1"

  columns = Person.connection.columns(:table_from_query_testings)
  assert_equal [1], Person.connection.select_values("SELECT * FROM table_from_query_testings")
  assert_equal 1, columns.length
  assert_equal "id", columns.first.name
ensure
  Person.connection.drop_table :table_from_query_testings rescue nil
end
test_create_table_with_query_from_relation() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 517
def test_create_table_with_query_from_relation
  Person.connection.create_table :table_from_query_testings, as: Person.select(:id).where(id: 1)

  columns = Person.connection.columns(:table_from_query_testings)
  assert_equal [1], Person.connection.select_values("SELECT * FROM table_from_query_testings")
  assert_equal 1, columns.length
  assert_equal "id", columns.first.name
ensure
  Person.connection.drop_table :table_from_query_testings rescue nil
end
test_filtering_migrations() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 217
def test_filtering_migrations
  assert_no_column Person, :last_name
  assert !Reminder.table_exists?

  name_filter = lambda { |migration| migration.name == "ValidPeopleHaveLastNames" }
  ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", &name_filter)

  assert_column Person, :last_name
  assert_raise(ActiveRecord::StatementInvalid) { Reminder.first }

  ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", &name_filter)

  assert_no_column Person, :last_name
  assert_raise(ActiveRecord::StatementInvalid) { Reminder.first }
end
test_generate_migrator_advisory_lock_id() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 624
def test_generate_migrator_advisory_lock_id
  # It is important we are consistent with how we generate this so that
  # exclusive locking works across migrator versions
  migration = Class.new(ActiveRecord::Migration::Current).new
  migrator = ActiveRecord::Migrator.new(:up, [migration], 100)

  lock_id = migrator.send(:generate_migrator_advisory_lock_id)

  current_database = ActiveRecord::Base.connection.current_database
  salt = ActiveRecord::Migrator::MIGRATOR_SALT
  expected_id = Zlib.crc32(current_database) * salt

  assert lock_id == expected_id, "expected lock id generated by the migrator to be #{expected_id}, but it was #{lock_id} instead"
  assert lock_id.bit_length <= 63, "lock id must be a signed integer of max 63 bits magnitude"
end
test_instance_based_migration_down() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 261
def test_instance_based_migration_down
  migration = MockMigration.new
  assert !migration.went_up, "have not gone up"
  assert !migration.went_down, "have not gone down"

  migration.migrate :down
  assert !migration.went_up, "have gone up"
  assert migration.went_down, "have not gone down"
end
test_instance_based_migration_up() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 251
def test_instance_based_migration_up
  migration = MockMigration.new
  assert !migration.went_up, "have not gone up"
  assert !migration.went_down, "have not gone down"

  migration.migrate :up
  assert migration.went_up, "have gone up"
  assert !migration.went_down, "have not gone down"
end
test_internal_metadata_stores_environment() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 381
def test_internal_metadata_stores_environment
  current_env     = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
  migrations_path = MIGRATIONS_ROOT + "/valid"
  old_path        = ActiveRecord::Migrator.migrations_paths
  ActiveRecord::Migrator.migrations_paths = migrations_path

  ActiveRecord::Migrator.up(migrations_path)
  assert_equal current_env, ActiveRecord::InternalMetadata[:environment]

  original_quails_env  = ENV["RAILS_ENV"]
  original_rack_env   = ENV["RACK_ENV"]
  ENV["RAILS_ENV"]    = ENV["RACK_ENV"] = "foofoo"
  new_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call

  refute_equal current_env, new_env

  sleep 1 # mysql by default does not store fractional seconds in the database
  ActiveRecord::Migrator.up(migrations_path)
  assert_equal new_env, ActiveRecord::InternalMetadata[:environment]
ensure
  ActiveRecord::Migrator.migrations_paths = old_path
  ENV["RAILS_ENV"] = original_quails_env
  ENV["RACK_ENV"]  = original_rack_env
  ActiveRecord::Migrator.up(migrations_path)
end
test_internal_metadata_stores_environment_when_other_data_exists() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 407
def test_internal_metadata_stores_environment_when_other_data_exists
  ActiveRecord::InternalMetadata.delete_all
  ActiveRecord::InternalMetadata[:foo] = "bar"

  current_env     = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
  migrations_path = MIGRATIONS_ROOT + "/valid"
  old_path        = ActiveRecord::Migrator.migrations_paths
  ActiveRecord::Migrator.migrations_paths = migrations_path

  current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
  ActiveRecord::Migrator.up(migrations_path)
  assert_equal current_env, ActiveRecord::InternalMetadata[:environment]
  assert_equal "bar", ActiveRecord::InternalMetadata[:foo]
ensure
  ActiveRecord::Migrator.migrations_paths = old_path
end
test_internal_metadata_table_name() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 361
def test_internal_metadata_table_name
  original_internal_metadata_table_name = ActiveRecord::Base.internal_metadata_table_name

  assert_equal "ar_internal_metadata", ActiveRecord::InternalMetadata.table_name
  ActiveRecord::Base.table_name_prefix = "p_"
  ActiveRecord::Base.table_name_suffix = "_s"
  Reminder.reset_table_name
  assert_equal "p_ar_internal_metadata_s", ActiveRecord::InternalMetadata.table_name
  ActiveRecord::Base.internal_metadata_table_name = "changed"
  Reminder.reset_table_name
  assert_equal "p_changed_s", ActiveRecord::InternalMetadata.table_name
  ActiveRecord::Base.table_name_prefix = ""
  ActiveRecord::Base.table_name_suffix = ""
  Reminder.reset_table_name
  assert_equal "changed", ActiveRecord::InternalMetadata.table_name
ensure
  ActiveRecord::Base.internal_metadata_table_name = original_internal_metadata_table_name
  Reminder.reset_table_name
end
test_method_missing_delegates_to_connection() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 145
def test_method_missing_delegates_to_connection
  migration = Class.new(ActiveRecord::Migration::Current) {
    def connection
      Class.new {
        def create_table; "hi mom!"; end
      }.new
    end
  }.new

  assert_equal "hi mom!", migration.method_missing(:create_table)
end
test_migration_detection_without_schema_migration_table() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 97
def test_migration_detection_without_schema_migration_table
  ActiveRecord::Base.connection.drop_table "schema_migrations", if_exists: true

  migrations_path = MIGRATIONS_ROOT + "/valid"
  old_path = ActiveRecord::Migrator.migrations_paths
  ActiveRecord::Migrator.migrations_paths = migrations_path

  assert_equal true, ActiveRecord::Migrator.needs_migration?
ensure
  ActiveRecord::Migrator.migrations_paths = old_path
end
test_migration_instance_has_connection() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 140
def test_migration_instance_has_connection
  migration = Class.new(ActiveRecord::Migration::Current).new
  assert_equal ActiveRecord::Base.connection, migration.connection
end
test_migration_version() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 122
def test_migration_version
  assert_nothing_raised { ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/version_check", 20131219224947) }
end
test_migration_version_matches_component_version() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 74
def test_migration_version_matches_component_version
  assert_equal ActiveRecord::VERSION::STRING.to_f, ActiveRecord::Migration.current_version
end
test_migration_without_transaction() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 314
def test_migration_without_transaction
  assert_no_column Person, :last_name

  migration = Class.new(ActiveRecord::Migration::Current) {
    disable_ddl_transaction!

    def version; 101 end
    def migrate(x)
      add_column "people", "last_name", :string
      raise "Something broke"
    end
  }.new

  migrator = ActiveRecord::Migrator.new(:up, [migration], 101)
  e = assert_raise(StandardError) { migrator.migrate }
  assert_equal "An error has occurred, all later migrations canceled:\n\nSomething broke", e.message

  assert_column Person, :last_name,
    "without ddl transactions, the Migrator should not rollback on error but it did."
ensure
  Person.reset_column_information
  if Person.column_names.include?("last_name")
    Person.connection.remove_column("people", "last_name")
  end
end
test_migrator_generates_valid_lock_id() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 612
def test_migrator_generates_valid_lock_id
  migration = Class.new(ActiveRecord::Migration::Current).new
  migrator = ActiveRecord::Migrator.new(:up, [migration], 100)

  lock_id = migrator.send(:generate_migrator_advisory_lock_id)

  assert ActiveRecord::Base.connection.get_advisory_lock(lock_id),
    "the Migrator should have generated a valid lock id, but it didn't"
  assert ActiveRecord::Base.connection.release_advisory_lock(lock_id),
    "the Migrator should have generated a valid lock id, but it didn't"
end
test_migrator_one_up_with_exception_and_rollback() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 272
def test_migrator_one_up_with_exception_and_rollback
  assert_no_column Person, :last_name

  migration = Class.new(ActiveRecord::Migration::Current) {
    def version; 100 end
    def migrate(x)
      add_column "people", "last_name", :string
      raise "Something broke"
    end
  }.new

  migrator = ActiveRecord::Migrator.new(:up, [migration], 100)

  e = assert_raise(StandardError) { migrator.migrate }

  assert_equal "An error has occurred, this and all later migrations canceled:\n\nSomething broke", e.message

  assert_no_column Person, :last_name,
    "On error, the Migrator should revert schema changes but it did not."
end
test_migrator_one_up_with_exception_and_rollback_using_run() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 293
def test_migrator_one_up_with_exception_and_rollback_using_run
  assert_no_column Person, :last_name

  migration = Class.new(ActiveRecord::Migration::Current) {
    def version; 100 end
    def migrate(x)
      add_column "people", "last_name", :string
      raise "Something broke"
    end
  }.new

  migrator = ActiveRecord::Migrator.new(:up, [migration], 100)

  e = assert_raise(StandardError) { migrator.run }

  assert_equal "An error has occurred, this and all later migrations canceled:\n\nSomething broke", e.message

  assert_no_column Person, :last_name,
    "On error, the Migrator should revert schema changes but it did not."
end
test_migrator_one_up_with_unavailable_lock() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 640
def test_migrator_one_up_with_unavailable_lock
  assert_no_column Person, :last_name

  migration = Class.new(ActiveRecord::Migration::Current) {
    def version; 100 end
    def migrate(x)
      add_column "people", "last_name", :string
    end
  }.new

  migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
  lock_id = migrator.send(:generate_migrator_advisory_lock_id)

  with_another_process_holding_lock(lock_id) do
    assert_raise(ActiveRecord::ConcurrentMigrationError) { migrator.migrate }
  end

  assert_no_column Person, :last_name,
    "without an advisory lock, the Migrator should not make any changes, but it did."
end
test_migrator_one_up_with_unavailable_lock_using_run() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 661
def test_migrator_one_up_with_unavailable_lock_using_run
  assert_no_column Person, :last_name

  migration = Class.new(ActiveRecord::Migration::Current) {
    def version; 100 end
    def migrate(x)
      add_column "people", "last_name", :string
    end
  }.new

  migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
  lock_id = migrator.send(:generate_migrator_advisory_lock_id)

  with_another_process_holding_lock(lock_id) do
    assert_raise(ActiveRecord::ConcurrentMigrationError) { migrator.run }
  end

  assert_no_column Person, :last_name,
    "without an advisory lock, the Migrator should not make any changes, but it did."
end
test_migrator_versions() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 78
def test_migrator_versions
  migrations_path = MIGRATIONS_ROOT + "/valid"
  old_path = ActiveRecord::Migrator.migrations_paths
  ActiveRecord::Migrator.migrations_paths = migrations_path

  ActiveRecord::Migrator.up(migrations_path)
  assert_equal 3, ActiveRecord::Migrator.current_version
  assert_equal false, ActiveRecord::Migrator.needs_migration?

  ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid")
  assert_equal 0, ActiveRecord::Migrator.current_version
  assert_equal true, ActiveRecord::Migrator.needs_migration?

  ActiveRecord::SchemaMigration.create!(version: 3)
  assert_equal true, ActiveRecord::Migrator.needs_migration?
ensure
  ActiveRecord::Migrator.migrations_paths = old_path
end
test_out_of_range_integer_limit_should_raise() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 584
def test_out_of_range_integer_limit_should_raise
  e = assert_raise(ActiveRecord::ActiveRecordError, "integer limit didn't raise") do
    Person.connection.create_table :test_integer_limits, force: true do |t|
      t.column :bigone, :integer, limit: 10
    end
  end

  assert_match(/No integer type has byte size 10/, e.message)
ensure
  Person.connection.drop_table :test_integer_limits, if_exists: true
end
test_out_of_range_text_limit_should_raise() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 598
def test_out_of_range_text_limit_should_raise
  e = assert_raise(ActiveRecord::ActiveRecordError, "text limit didn't raise") do
    Person.connection.create_table :test_text_limits, force: true do |t|
      t.text :bigtext, limit: 0xfffffffff
    end
  end

  assert_match(/No text type has byte length #{0xfffffffff}/, e.message)
ensure
  Person.connection.drop_table :test_text_limits, if_exists: true
end
test_proper_table_name_on_migration() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 424
def test_proper_table_name_on_migration
  reminder_class = new_isolated_reminder_class
  migration = ActiveRecord::Migration.new
  assert_equal "table", migration.proper_table_name("table")
  assert_equal "table", migration.proper_table_name(:table)
  assert_equal "reminders", migration.proper_table_name(reminder_class)
  reminder_class.reset_table_name
  assert_equal reminder_class.table_name, migration.proper_table_name(reminder_class)

  # Use the model's own prefix/suffix if a model is given
  ActiveRecord::Base.table_name_prefix = "ARprefix_"
  ActiveRecord::Base.table_name_suffix = "_ARsuffix"
  reminder_class.table_name_prefix = "prefix_"
  reminder_class.table_name_suffix = "_suffix"
  reminder_class.reset_table_name
  assert_equal "prefix_reminders_suffix", migration.proper_table_name(reminder_class)
  reminder_class.table_name_prefix = ""
  reminder_class.table_name_suffix = ""
  reminder_class.reset_table_name

  # Use AR::Base's prefix/suffix if string or symbol is given
  ActiveRecord::Base.table_name_prefix = "prefix_"
  ActiveRecord::Base.table_name_suffix = "_suffix"
  reminder_class.reset_table_name
  assert_equal "prefix_table_suffix", migration.proper_table_name("table", migration.table_name_options)
  assert_equal "prefix_table_suffix", migration.proper_table_name(:table, migration.table_name_options)
end
test_rename_table_with_prefix_and_suffix() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 452
def test_rename_table_with_prefix_and_suffix
  assert !Thing.table_exists?
  ActiveRecord::Base.table_name_prefix = "p_"
  ActiveRecord::Base.table_name_suffix = "_s"
  Thing.reset_table_name
  Thing.reset_sequence_name
  WeNeedThings.up
  Thing.reset_column_information

  assert Thing.create("content" => "hello world")
  assert_equal "hello world", Thing.first.content

  RenameThings.up
  Thing.table_name = "p_awesome_things_s"

  assert_equal "hello world", Thing.first.content
ensure
  Thing.reset_table_name
  Thing.reset_sequence_name
end
test_schema_migrations_table_name() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 341
def test_schema_migrations_table_name
  original_schema_migrations_table_name = ActiveRecord::Base.schema_migrations_table_name

  assert_equal "schema_migrations", ActiveRecord::SchemaMigration.table_name
  ActiveRecord::Base.table_name_prefix = "prefix_"
  ActiveRecord::Base.table_name_suffix = "_suffix"
  Reminder.reset_table_name
  assert_equal "prefix_schema_migrations_suffix", ActiveRecord::SchemaMigration.table_name
  ActiveRecord::Base.schema_migrations_table_name = "changed"
  Reminder.reset_table_name
  assert_equal "prefix_changed_suffix", ActiveRecord::SchemaMigration.table_name
  ActiveRecord::Base.table_name_prefix = ""
  ActiveRecord::Base.table_name_suffix = ""
  Reminder.reset_table_name
  assert_equal "changed", ActiveRecord::SchemaMigration.table_name
ensure
  ActiveRecord::Base.schema_migrations_table_name = original_schema_migrations_table_name
  Reminder.reset_table_name
end
version() click to toggle source
# File activerecord/test/cases/migration_test.rb, line 276
def version; 100 end

Private Instance Methods

new_isolated_reminder_class() click to toggle source

This is needed to isolate class_attribute assignments like `table_name_prefix` for each test case.

# File activerecord/test/cases/migration_test.rb, line 686
def new_isolated_reminder_class
  Class.new(Reminder) {
    def self.name; "Reminder"; end
    def self.base_class; self; end
  }
end
with_another_process_holding_lock(lock_id) { || ... } click to toggle source
# File activerecord/test/cases/migration_test.rb, line 693
def with_another_process_holding_lock(lock_id)
  thread_lock = Concurrent::CountDownLatch.new
  test_terminated = Concurrent::CountDownLatch.new

  other_process = Thread.new do
    begin
      conn = ActiveRecord::Base.connection_pool.checkout
      conn.get_advisory_lock(lock_id)
      thread_lock.count_down
      test_terminated.wait # hold the lock open until we tested everything
    ensure
      conn.release_advisory_lock(lock_id)
      ActiveRecord::Base.connection_pool.checkin(conn)
    end
  end

  thread_lock.wait # wait until the 'other process' has the lock

  yield

  test_terminated.count_down
  other_process.join
end