diff options
Diffstat (limited to 'activerecord/test')
4 files changed, 318 insertions, 92 deletions
diff --git a/activerecord/test/cases/invertible_migration_test.rb b/activerecord/test/cases/invertible_migration_test.rb index 8f1cdd47ea..cf4e39c4ef 100644 --- a/activerecord/test/cases/invertible_migration_test.rb +++ b/activerecord/test/cases/invertible_migration_test.rb @@ -17,6 +17,37 @@ module ActiveRecord end end + class InvertibleRevertMigration < SilentMigration + def change + revert do + create_table("horses") do |t| + t.column :content, :text + t.column :remind_at, :datetime + end + end + end + end + + class InvertibleByPartsMigration < SilentMigration + attr_writer :test + def change + create_table("new_horses") do |t| + t.column :breed, :string + end + reversible do |dir| + @test.yield :both + dir.up { @test.yield :up } + dir.down { @test.yield :down } + end + revert do + create_table("horses") do |t| + t.column :content, :text + t.column :remind_at, :datetime + end + end + end + end + class NonInvertibleMigration < SilentMigration def change create_table("horses") do |t| @@ -40,6 +71,23 @@ module ActiveRecord end end + class RevertWholeMigration < SilentMigration + def initialize(name = self.class.name, version = nil, migration) + @migration = migration + super(name, version) + end + + def change + revert @migration + end + end + + class NestedRevertWholeMigration < RevertWholeMigration + def change + revert { super } + end + end + def teardown if ActiveRecord::Base.connection.table_exists?("horses") ActiveRecord::Base.connection.drop_table("horses") @@ -67,6 +115,83 @@ module ActiveRecord assert !migration.connection.table_exists?("horses") end + def test_migrate_revert + migration = InvertibleMigration.new + revert = InvertibleRevertMigration.new + migration.migrate :up + revert.migrate :up + assert !migration.connection.table_exists?("horses") + revert.migrate :down + assert migration.connection.table_exists?("horses") + migration.migrate :down + assert !migration.connection.table_exists?("horses") + end + + def test_migrate_revert_by_part + InvertibleMigration.new.migrate :up + received = [] + migration = InvertibleByPartsMigration.new + migration.test = ->(dir){ + assert migration.connection.table_exists?("horses") + assert migration.connection.table_exists?("new_horses") + received << dir + } + migration.migrate :up + assert_equal [:both, :up], received + assert !migration.connection.table_exists?("horses") + assert migration.connection.table_exists?("new_horses") + migration.migrate :down + assert_equal [:both, :up, :both, :down], received + assert migration.connection.table_exists?("horses") + assert !migration.connection.table_exists?("new_horses") + end + + def test_migrate_revert_whole_migration + migration = InvertibleMigration.new + [LegacyMigration, InvertibleMigration].each do |klass| + revert = RevertWholeMigration.new(klass) + migration.migrate :up + revert.migrate :up + assert !migration.connection.table_exists?("horses") + revert.migrate :down + assert migration.connection.table_exists?("horses") + migration.migrate :down + assert !migration.connection.table_exists?("horses") + end + end + + def test_migrate_nested_revert_whole_migration + revert = NestedRevertWholeMigration.new(InvertibleRevertMigration) + revert.migrate :down + assert revert.connection.table_exists?("horses") + revert.migrate :up + assert !revert.connection.table_exists?("horses") + end + + def test_revert_order + block = Proc.new{|t| t.string :name } + recorder = ActiveRecord::Migration::CommandRecorder.new(ActiveRecord::Base.connection) + recorder.instance_eval do + create_table("apples", &block) + revert do + create_table("bananas", &block) + revert do + create_table("clementines") + create_table("dates") + end + create_table("elderberries") + end + revert do + create_table("figs") + create_table("grapes") + end + end + assert_equal [[:create_table, ["apples"], block], [:drop_table, ["elderberries"], nil], + [:create_table, ["clementines"], nil], [:create_table, ["dates"], nil], + [:drop_table, ["bananas"], block], [:drop_table, ["grapes"], nil], + [:drop_table, ["figs"], nil]], recorder.commands + end + def test_legacy_up LegacyMigration.migrate :up assert ActiveRecord::Base.connection.table_exists?("horses"), "horses should exist" diff --git a/activerecord/test/cases/migration/change_table_test.rb b/activerecord/test/cases/migration/change_table_test.rb index 8fb03cdee0..ac1ad176db 100644 --- a/activerecord/test/cases/migration/change_table_test.rb +++ b/activerecord/test/cases/migration/change_table_test.rb @@ -3,21 +3,8 @@ require "cases/migration/helper" module ActiveRecord class Migration class TableTest < ActiveRecord::TestCase - class MockConnection < MiniTest::Mock - def native_database_types - { - :string => 'varchar(255)', - :integer => 'integer', - } - end - - def type_to_sql(type, limit, precision, scale) - native_database_types[type] - end - end - def setup - @connection = MockConnection.new + @connection = MiniTest::Mock.new end def teardown @@ -98,26 +85,18 @@ module ActiveRecord end end - def string_column - @connection.native_database_types[:string] - end - - def integer_column - @connection.native_database_types[:integer] - end - def test_integer_creates_integer_column with_change_table do |t| - @connection.expect :add_column, nil, [:delete_me, :foo, integer_column, {}] - @connection.expect :add_column, nil, [:delete_me, :bar, integer_column, {}] + @connection.expect :add_column, nil, [:delete_me, :foo, :integer, {}] + @connection.expect :add_column, nil, [:delete_me, :bar, :integer, {}] t.integer :foo, :bar end end def test_string_creates_string_column with_change_table do |t| - @connection.expect :add_column, nil, [:delete_me, :foo, string_column, {}] - @connection.expect :add_column, nil, [:delete_me, :bar, string_column, {}] + @connection.expect :add_column, nil, [:delete_me, :foo, :string, {}] + @connection.expect :add_column, nil, [:delete_me, :bar, :string, {}] t.string :foo, :bar end end @@ -194,14 +173,14 @@ module ActiveRecord def test_remove_drops_single_column with_change_table do |t| - @connection.expect :remove_column, nil, [:delete_me, :bar] + @connection.expect :remove_columns, nil, [:delete_me, :bar] t.remove :bar end end def test_remove_drops_multiple_columns with_change_table do |t| - @connection.expect :remove_column, nil, [:delete_me, :bar, :baz] + @connection.expect :remove_columns, nil, [:delete_me, :bar, :baz] t.remove :bar, :baz end end diff --git a/activerecord/test/cases/migration/command_recorder_test.rb b/activerecord/test/cases/migration/command_recorder_test.rb index f2213ee6aa..2cad8a6d96 100644 --- a/activerecord/test/cases/migration/command_recorder_test.rb +++ b/activerecord/test/cases/migration/command_recorder_test.rb @@ -26,7 +26,7 @@ module ActiveRecord }.new) assert recorder.respond_to?(:create_table), 'respond_to? create_table' recorder.send(:create_table, :horses) - assert_equal [[:create_table, [:horses]]], recorder.commands + assert_equal [[:create_table, [:horses], nil]], recorder.commands end def test_unknown_commands_delegate @@ -34,10 +34,15 @@ module ActiveRecord assert_equal 'bar', recorder.foo end - def test_unknown_commands_raise_exception_if_they_cannot_delegate - @recorder.record :execute, ['some sql'] + def test_inverse_of_raise_exception_on_unknown_commands assert_raises(ActiveRecord::IrreversibleMigration) do - @recorder.inverse + @recorder.inverse_of :execute, ['some sql'] + end + end + + def test_irreversible_commands_raise_exception + assert_raises(ActiveRecord::IrreversibleMigration) do + @recorder.revert{ @recorder.execute 'some sql' } end end @@ -46,121 +51,196 @@ module ActiveRecord assert_equal 1, @recorder.commands.length end - def test_inverse - @recorder.record :create_table, [:system_settings] - assert_equal 1, @recorder.inverse.length - - @recorder.record :rename_table, [:old, :new] - assert_equal 2, @recorder.inverse.length + def test_inverted_commands_are_reversed + @recorder.revert do + @recorder.record :create_table, [:hello] + @recorder.record :create_table, [:world] + end + tables = @recorder.commands.map{|_cmd, args, _block| args} + assert_equal [[:world], [:hello]], tables end - def test_inverted_commands_are_reveresed - @recorder.record :create_table, [:hello] - @recorder.record :create_table, [:world] - tables = @recorder.inverse.map(&:last) - assert_equal [[:world], [:hello]], tables + def test_revert_order + block = Proc.new{|t| t.string :name } + @recorder.instance_eval do + create_table("apples", &block) + revert do + create_table("bananas", &block) + revert do + create_table("clementines", &block) + create_table("dates") + end + create_table("elderberries") + end + revert do + create_table("figs", &block) + create_table("grapes") + end + end + assert_equal [[:create_table, ["apples"], block], [:drop_table, ["elderberries"], nil], + [:create_table, ["clementines"], block], [:create_table, ["dates"], nil], + [:drop_table, ["bananas"], block], [:drop_table, ["grapes"], nil], + [:drop_table, ["figs"], block]], @recorder.commands + end + + def test_invert_change_table + @recorder.revert do + @recorder.change_table :fruits do |t| + t.string :name + t.rename :kind, :cultivar + end + end + assert_equal [ + [:rename_column, [:fruits, :cultivar, :kind]], + [:remove_column, [:fruits, :name, :string, {}], nil], + ], @recorder.commands + + assert_raises(ActiveRecord::IrreversibleMigration) do + @recorder.revert do + @recorder.change_table :fruits do |t| + t.remove :kind + end + end + end end def test_invert_create_table - @recorder.record :create_table, [:system_settings] - drop_table = @recorder.inverse.first - assert_equal [:drop_table, [:system_settings]], drop_table + @recorder.revert do + @recorder.record :create_table, [:system_settings] + end + drop_table = @recorder.commands.first + assert_equal [:drop_table, [:system_settings], nil], drop_table + end + + def test_invert_create_table_with_options_and_block + block = Proc.new{} + drop_table = @recorder.inverse_of :create_table, [:people_reminders, id: false], &block + assert_equal [:drop_table, [:people_reminders, id: false], block], drop_table + end + + def test_invert_drop_table + block = Proc.new{} + create_table = @recorder.inverse_of :drop_table, [:people_reminders, id: false], &block + assert_equal [:create_table, [:people_reminders, id: false], block], create_table end - def test_invert_create_table_with_options - @recorder.record :create_table, [:people_reminders, {:id => false}] - drop_table = @recorder.inverse.first - assert_equal [:drop_table, [:people_reminders]], drop_table + def test_invert_drop_table_without_a_block_nor_option + assert_raises(ActiveRecord::IrreversibleMigration) do + @recorder.inverse_of :drop_table, [:people_reminders] + end end def test_invert_create_join_table - @recorder.record :create_join_table, [:musics, :artists] - drop_table = @recorder.inverse.first - assert_equal [:drop_table, [:artists_musics]], drop_table + drop_join_table = @recorder.inverse_of :create_join_table, [:musics, :artists] + assert_equal [:drop_join_table, [:musics, :artists], nil], drop_join_table end def test_invert_create_join_table_with_table_name - @recorder.record :create_join_table, [:musics, :artists, {:table_name => :catalog}] - drop_table = @recorder.inverse.first - assert_equal [:drop_table, [:catalog]], drop_table + drop_join_table = @recorder.inverse_of :create_join_table, [:musics, :artists, table_name: :catalog] + assert_equal [:drop_join_table, [:musics, :artists, table_name: :catalog], nil], drop_join_table + end + + def test_invert_drop_join_table + block = Proc.new{} + create_join_table = @recorder.inverse_of :drop_join_table, [:musics, :artists, table_name: :catalog], &block + assert_equal [:create_join_table, [:musics, :artists, table_name: :catalog], block], create_join_table end def test_invert_rename_table - @recorder.record :rename_table, [:old, :new] - rename = @recorder.inverse.first + rename = @recorder.inverse_of :rename_table, [:old, :new] assert_equal [:rename_table, [:new, :old]], rename end def test_invert_add_column - @recorder.record :add_column, [:table, :column, :type, {}] - remove = @recorder.inverse.first - assert_equal [:remove_column, [:table, :column]], remove + remove = @recorder.inverse_of :add_column, [:table, :column, :type, {}] + assert_equal [:remove_column, [:table, :column, :type, {}], nil], remove + end + + def test_invert_remove_column + add = @recorder.inverse_of :remove_column, [:table, :column, :type, {}] + assert_equal [:add_column, [:table, :column, :type, {}], nil], add + end + + def test_invert_remove_column_without_type + assert_raises(ActiveRecord::IrreversibleMigration) do + @recorder.inverse_of :remove_column, [:table, :column] + end end def test_invert_rename_column - @recorder.record :rename_column, [:table, :old, :new] - rename = @recorder.inverse.first + rename = @recorder.inverse_of :rename_column, [:table, :old, :new] assert_equal [:rename_column, [:table, :new, :old]], rename end def test_invert_add_index - @recorder.record :add_index, [:table, [:one, :two], {:options => true}] - remove = @recorder.inverse.first - assert_equal [:remove_index, [:table, {:column => [:one, :two]}]], remove + remove = @recorder.inverse_of :add_index, [:table, [:one, :two], options: true] + assert_equal [:remove_index, [:table, {column: [:one, :two], options: true}]], remove end def test_invert_add_index_with_name - @recorder.record :add_index, [:table, [:one, :two], {:name => "new_index"}] - remove = @recorder.inverse.first - assert_equal [:remove_index, [:table, {:name => "new_index"}]], remove + remove = @recorder.inverse_of :add_index, [:table, [:one, :two], name: "new_index"] + assert_equal [:remove_index, [:table, {column: [:one, :two], name: "new_index"}]], remove end def test_invert_add_index_with_no_options - @recorder.record :add_index, [:table, [:one, :two]] - remove = @recorder.inverse.first - assert_equal [:remove_index, [:table, {:column => [:one, :two]}]], remove + remove = @recorder.inverse_of :add_index, [:table, [:one, :two]] + assert_equal [:remove_index, [:table, {column: [:one, :two]}]], remove + end + + def test_invert_remove_index + add = @recorder.inverse_of :remove_index, [:table, {column: [:one, :two], options: true}] + assert_equal [:add_index, [:table, [:one, :two], options: true]], add + end + + def test_invert_remove_index_with_name + add = @recorder.inverse_of :remove_index, [:table, {column: [:one, :two], name: "new_index"}] + assert_equal [:add_index, [:table, [:one, :two], name: "new_index"]], add + end + + def test_invert_remove_index_with_no_special_options + add = @recorder.inverse_of :remove_index, [:table, {column: [:one, :two]}] + assert_equal [:add_index, [:table, [:one, :two], {}]], add + end + + def test_invert_remove_index_with_no_column + assert_raises(ActiveRecord::IrreversibleMigration) do + @recorder.inverse_of :remove_index, [:table, name: "new_index"] + end end def test_invert_rename_index - @recorder.record :rename_index, [:table, :old, :new] - rename = @recorder.inverse.first + rename = @recorder.inverse_of :rename_index, [:table, :old, :new] assert_equal [:rename_index, [:table, :new, :old]], rename end def test_invert_add_timestamps - @recorder.record :add_timestamps, [:table] - remove = @recorder.inverse.first - assert_equal [:remove_timestamps, [:table]], remove + remove = @recorder.inverse_of :add_timestamps, [:table] + assert_equal [:remove_timestamps, [:table], nil], remove end def test_invert_remove_timestamps - @recorder.record :remove_timestamps, [:table] - add = @recorder.inverse.first - assert_equal [:add_timestamps, [:table]], add + add = @recorder.inverse_of :remove_timestamps, [:table] + assert_equal [:add_timestamps, [:table], nil], add end def test_invert_add_reference - @recorder.record :add_reference, [:table, :taggable, { polymorphic: true }] - remove = @recorder.inverse.first - assert_equal [:remove_reference, [:table, :taggable, { polymorphic: true }]], remove + remove = @recorder.inverse_of :add_reference, [:table, :taggable, { polymorphic: true }] + assert_equal [:remove_reference, [:table, :taggable, { polymorphic: true }], nil], remove end def test_invert_add_belongs_to_alias - @recorder.record :add_belongs_to, [:table, :user] - remove = @recorder.inverse.first - assert_equal [:remove_reference, [:table, :user]], remove + remove = @recorder.inverse_of :add_belongs_to, [:table, :user] + assert_equal [:remove_reference, [:table, :user], nil], remove end def test_invert_remove_reference - @recorder.record :remove_reference, [:table, :taggable, { polymorphic: true }] - add = @recorder.inverse.first - assert_equal [:add_reference, [:table, :taggable, { polymorphic: true }]], add + add = @recorder.inverse_of :remove_reference, [:table, :taggable, { polymorphic: true }] + assert_equal [:add_reference, [:table, :taggable, { polymorphic: true }], nil], add end def test_invert_remove_belongs_to_alias - @recorder.record :remove_belongs_to, [:table, :user] - add = @recorder.inverse.first - assert_equal [:add_reference, [:table, :user]], add + add = @recorder.inverse_of :remove_belongs_to, [:table, :user] + assert_equal [:add_reference, [:table, :user], nil], add end end end diff --git a/activerecord/test/cases/migration/create_join_table_test.rb b/activerecord/test/cases/migration/create_join_table_test.rb index f262bbaad7..c099854ad8 100644 --- a/activerecord/test/cases/migration/create_join_table_test.rb +++ b/activerecord/test/cases/migration/create_join_table_test.rb @@ -78,6 +78,48 @@ module ActiveRecord assert_equal [%w(artist_id music_id)], connection.indexes(:artists_musics).map(&:columns) end + + def test_drop_join_table + connection.create_join_table :artists, :musics + connection.drop_join_table :artists, :musics + + assert !connection.tables.include?('artists_musics') + end + + def test_drop_join_table_with_strings + connection.create_join_table :artists, :musics + connection.drop_join_table 'artists', 'musics' + + assert !connection.tables.include?('artists_musics') + end + + def test_drop_join_table_with_the_proper_order + connection.create_join_table :videos, :musics + connection.drop_join_table :videos, :musics + + assert !connection.tables.include?('musics_videos') + end + + def test_drop_join_table_with_the_table_name + connection.create_join_table :artists, :musics, table_name: :catalog + connection.drop_join_table :artists, :musics, table_name: :catalog + + assert !connection.tables.include?('catalog') + end + + def test_drop_join_table_with_the_table_name_as_string + connection.create_join_table :artists, :musics, table_name: 'catalog' + connection.drop_join_table :artists, :musics, table_name: 'catalog' + + assert !connection.tables.include?('catalog') + end + + def test_create_join_table_with_column_options + connection.create_join_table :artists, :musics, column_options: {null: true} + connection.drop_join_table :artists, :musics, column_options: {null: true} + + assert !connection.tables.include?('artists_musics') + end end end end |