active_schema_test.rb 6.5 KB
Newer Older
1
require "cases/helper"
2

3
class ActiveSchemaTest < ActiveRecord::TestCase
4
  def setup
J
Jon Leighton 已提交
5 6 7 8
    @connection = ActiveRecord::Base.remove_connection
    ActiveRecord::Base.establish_connection(@connection)

    ActiveRecord::Base.connection.singleton_class.class_eval do
9
      alias_method :execute_without_stub, :execute
10
      def execute(sql, name = nil) return sql end
11
    end
12
  end
13

G
Guo Xiang Tan 已提交
14
  teardown do
J
Jon Leighton 已提交
15 16
    ActiveRecord::Base.remove_connection
    ActiveRecord::Base.establish_connection(@connection)
17 18
  end

19
  def test_add_index
20 21
    # add_index calls table_exists? and index_name_exists? which can't work since execute is stubbed
    def (ActiveRecord::Base.connection).table_exists?(*); true; end
J
Jon Leighton 已提交
22 23
    def (ActiveRecord::Base.connection).index_name_exists?(*); false; end

24
    expected = "CREATE  INDEX `index_people_on_last_name`  ON `people` (`last_name`) "
25 26
    assert_equal expected, add_index(:people, :last_name, :length => nil)

27
    expected = "CREATE  INDEX `index_people_on_last_name`  ON `people` (`last_name`(10)) "
28 29
    assert_equal expected, add_index(:people, :last_name, :length => 10)

30
    expected = "CREATE  INDEX `index_people_on_last_name_and_first_name`  ON `people` (`last_name`(15), `first_name`(15)) "
31 32
    assert_equal expected, add_index(:people, [:last_name, :first_name], :length => 15)

33
    expected = "CREATE  INDEX `index_people_on_last_name_and_first_name`  ON `people` (`last_name`(15), `first_name`) "
34 35
    assert_equal expected, add_index(:people, [:last_name, :first_name], :length => {:last_name => 15})

36
    expected = "CREATE  INDEX `index_people_on_last_name_and_first_name`  ON `people` (`last_name`(15), `first_name`(10)) "
37
    assert_equal expected, add_index(:people, [:last_name, :first_name], :length => {:last_name => 15, :first_name => 10})
D
doabit 已提交
38

39 40 41 42 43 44 45 46
    %w(SPATIAL FULLTEXT UNIQUE).each do |type|
      expected = "CREATE #{type} INDEX `index_people_on_last_name`  ON `people` (`last_name`) "
      assert_equal expected, add_index(:people, :last_name, :type => type)
    end

    %w(btree hash).each do |using|
      expected = "CREATE  INDEX `index_people_on_last_name` USING #{using} ON `people` (`last_name`) "
      assert_equal expected, add_index(:people, :last_name, :using => using)
D
doabit 已提交
47 48
    end

49
    expected = "CREATE  INDEX `index_people_on_last_name` USING btree ON `people` (`last_name`(10)) "
D
doabit 已提交
50 51
    assert_equal expected, add_index(:people, :last_name, :length => 10, :using => :btree)

52 53 54
    expected = "CREATE  INDEX `index_people_on_last_name` USING btree ON `people` (`last_name`(10)) ALGORITHM = COPY"
    assert_equal expected, add_index(:people, :last_name, :length => 10, using: :btree, algorithm: :copy)

55 56 57 58
    assert_raise ArgumentError do
      add_index(:people, :last_name, algorithm: :coyp)
    end

59
    expected = "CREATE  INDEX `index_people_on_last_name_and_first_name` USING btree ON `people` (`last_name`(15), `first_name`(15)) "
D
doabit 已提交
60
    assert_equal expected, add_index(:people, [:last_name, :first_name], :length => 15, :using => :btree)
61 62
  end

63
  def test_drop_table
64
    assert_equal "DROP TABLE `people`", drop_table(:people)
65
  end
66

67
  if current_adapter?(:MysqlAdapter, :Mysql2Adapter)
68 69 70 71 72
    def test_create_mysql_database_with_encoding
      assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8`", create_database(:matt)
      assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, {:charset => 'latin1'})
      assert_equal "CREATE DATABASE `matt_aimonetti` DEFAULT CHARACTER SET `big5` COLLATE `big5_chinese_ci`", create_database(:matt_aimonetti, {:charset => :big5, :collation => :big5_chinese_ci})
    end
73 74 75 76 77

    def test_recreate_mysql_database_with_encoding
      create_database(:luca, {:charset => 'latin1'})
      assert_equal "CREATE DATABASE `luca` DEFAULT CHARACTER SET `latin1`", recreate_database(:luca, {:charset => 'latin1'})
    end
78 79
  end

80
  def test_add_column
81
    assert_equal "ALTER TABLE `people` ADD `last_name` varchar(255)", add_column(:people, :last_name, :string)
82
  end
83

84
  def test_add_column_with_limit
85
    assert_equal "ALTER TABLE `people` ADD `key` varchar(32)", add_column(:people, :key, :string, :limit => 32)
86
  end
87

88 89 90
  def test_drop_table_with_specific_database
    assert_equal "DROP TABLE `otherdb`.`people`", drop_table('otherdb.people')
  end
J
Jeremy Kemper 已提交
91

92
  def test_add_timestamps
93 94
    with_real_execute do
      begin
A
Anupam Choudhury 已提交
95
        ActiveRecord::Base.connection.create_table :delete_me
96 97 98 99 100 101
        ActiveRecord::Base.connection.add_timestamps :delete_me
        assert column_present?('delete_me', 'updated_at', 'datetime')
        assert column_present?('delete_me', 'created_at', 'datetime')
      ensure
        ActiveRecord::Base.connection.drop_table :delete_me rescue nil
      end
102 103
    end
  end
104 105

  def test_remove_timestamps
106 107 108 109 110 111 112 113 114 115 116
    with_real_execute do
      begin
        ActiveRecord::Base.connection.create_table :delete_me do |t|
          t.timestamps
        end
        ActiveRecord::Base.connection.remove_timestamps :delete_me
        assert !column_present?('delete_me', 'updated_at', 'datetime')
        assert !column_present?('delete_me', 'created_at', 'datetime')
      ensure
        ActiveRecord::Base.connection.drop_table :delete_me rescue nil
      end
117 118 119
    end
  end

120 121
  def test_indexes_in_create
    begin
122 123
      ActiveRecord::Base.connection.stubs(:table_exists?).with(:temp).returns(false)
      ActiveRecord::Base.connection.stubs(:index_name_exists?).with(:index_temp_on_zip).returns(false)
124
      expected = "CREATE TEMPORARY TABLE `temp` ( INDEX `index_temp_on_zip`  (`zip`) ) ENGINE=InnoDB AS SELECT id, name, zip FROM a_really_complicated_query"
125 126 127 128 129 130 131
      actual = ActiveRecord::Base.connection.create_table(:temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query") do |t|
        t.index :zip
      end
      assert_equal expected, actual
    end
  end

132
  private
133
    def with_real_execute
J
Jon Leighton 已提交
134
      ActiveRecord::Base.connection.singleton_class.class_eval do
135
        alias_method :execute_with_stub, :execute
136
        remove_method :execute
137 138
        alias_method :execute, :execute_without_stub
      end
J
Jon Leighton 已提交
139

140 141
      yield
    ensure
J
Jon Leighton 已提交
142
      ActiveRecord::Base.connection.singleton_class.class_eval do
143
        remove_method :execute
144 145 146 147
        alias_method :execute, :execute_with_stub
      end
    end

148 149 150
    def method_missing(method_symbol, *arguments)
      ActiveRecord::Base.connection.send(method_symbol, *arguments)
    end
151 152 153 154 155

    def column_present?(table_name, column_name, type)
      results = ActiveRecord::Base.connection.select_all("SHOW FIELDS FROM #{table_name} LIKE '#{column_name}'")
      results.first && results.first['Type'] == type
    end
156
end