schema_dumper_test.rb 6.5 KB
Newer Older
1
require "cases/helper"
J
Jeremy Kemper 已提交
2
require 'active_record/schema_dumper'
3 4 5
require 'stringio'


6 7 8 9 10 11 12
class SchemaDumperTest < ActiveRecord::TestCase
  def standard_dump
    stream = StringIO.new
    ActiveRecord::SchemaDumper.ignore_tables = []
    ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
    stream.string
  end
J
Jeremy Kemper 已提交
13

14 15 16 17 18 19
  def test_schema_dump
    output = standard_dump
    assert_match %r{create_table "accounts"}, output
    assert_match %r{create_table "authors"}, output
    assert_no_match %r{create_table "schema_migrations"}, output
  end
J
Jeremy Kemper 已提交
20

21 22 23 24
  def test_schema_dump_excludes_sqlite_sequence
    output = standard_dump
    assert_no_match %r{create_table "sqlite_sequence"}, output
  end
25

26 27 28 29 30 31 32 33
  def assert_line_up(lines, pattern, required = false)
    return assert(true) if lines.empty?
    matches = lines.map { |line| line.match(pattern) }
    assert matches.all? if required
    matches.compact!
    return assert(true) if matches.empty?
    assert_equal 1, matches.map{ |match| match.offset(0).first }.uniq.length
  end
34

35 36 37
  def column_definition_lines(output = standard_dump)
    output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map{ |m| m.last.split(/\n/) }
  end
38

39 40 41
  def test_types_line_up
    column_definition_lines.each do |column_set|
      next if column_set.empty?
42

43 44 45
      lengths = column_set.map do |column|
        if match = column.match(/t\.(?:integer|decimal|float|datetime|timestamp|time|date|text|binary|string|boolean)\s+"/)
          match[0].length
46 47
        end
      end
J
Jeremy Kemper 已提交
48

49
      assert_equal 1, lengths.uniq.length
50
    end
51
  end
J
Jeremy Kemper 已提交
52

53 54 55 56 57
  def test_arguments_line_up
    column_definition_lines.each do |column_set|
      assert_line_up(column_set, /:default => /)
      assert_line_up(column_set, /:limit => /)
      assert_line_up(column_set, /:null => /)
58
    end
59
  end
J
Jeremy Kemper 已提交
60

61 62 63 64
  def test_no_dump_errors
    output = standard_dump
    assert_no_match %r{\# Could not dump table}, output
  end
J
Jeremy Kemper 已提交
65

66 67
  def test_schema_dump_includes_not_null_columns
    stream = StringIO.new
68

69 70 71 72 73
    ActiveRecord::SchemaDumper.ignore_tables = [/^[^r]/]
    ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
    output = stream.string
    assert_match %r{:null => false}, output
  end
J
Jeremy Kemper 已提交
74

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
  def test_schema_dump_includes_limit_constraint_for_integer_columns
    stream = StringIO.new

    ActiveRecord::SchemaDumper.ignore_tables = [/^(?!integer_limits)/]
    ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
    output = stream.string

    if current_adapter?(:PostgreSQLAdapter)
      assert_match %r{c_int_1.*:limit => 2}, output
      assert_match %r{c_int_2.*:limit => 2}, output

      # int 3 is 4 bytes in postgresql
      assert_match %r{c_int_3.*}, output
      assert_no_match %r{c_int_3.*:limit}, output

      assert_match %r{c_int_4.*}, output
      assert_no_match %r{c_int_4.*:limit}, output
    elsif current_adapter?(:MysqlAdapter)
      assert_match %r{c_int_1.*:limit => 2}, output
      assert_match %r{c_int_2.*:limit => 2}, output
      assert_match %r{c_int_3.*:limit => 3}, output

      assert_match %r{c_int_4.*}, output
      assert_no_match %r{c_int_4.*:limit}, output
    elsif current_adapter?(:SQLiteAdapter)
      assert_match %r{c_int_1.*:limit => 1}, output
      assert_match %r{c_int_2.*:limit => 2}, output
      assert_match %r{c_int_3.*:limit => 3}, output
      assert_match %r{c_int_4.*:limit => 4}, output
    end
    assert_match %r{c_int_without_limit.*}, output
    assert_no_match %r{c_int_without_limit.*:limit}, output

    if current_adapter?(:SQLiteAdapter)
      assert_match %r{c_int_5.*:limit => 5}, output
      assert_match %r{c_int_6.*:limit => 6}, output
      assert_match %r{c_int_7.*:limit => 7}, output
      assert_match %r{c_int_8.*:limit => 8}, output
    else
      assert_match %r{c_int_5.*:limit => 8}, output
      assert_match %r{c_int_6.*:limit => 8}, output
      assert_match %r{c_int_7.*:limit => 8}, output
      assert_match %r{c_int_8.*:limit => 8}, output
    end
  end

121 122 123 124 125 126 127 128 129 130 131 132 133
  def test_schema_dump_with_string_ignored_table
    stream = StringIO.new

    ActiveRecord::SchemaDumper.ignore_tables = ['accounts']
    ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
    output = stream.string
    assert_no_match %r{create_table "accounts"}, output
    assert_match %r{create_table "authors"}, output
    assert_no_match %r{create_table "schema_migrations"}, output
  end

  def test_schema_dump_with_regexp_ignored_table
    stream = StringIO.new
134

135 136 137 138 139 140 141
    ActiveRecord::SchemaDumper.ignore_tables = [/^account/]
    ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
    output = stream.string
    assert_no_match %r{create_table "accounts"}, output
    assert_match %r{create_table "authors"}, output
    assert_no_match %r{create_table "schema_migrations"}, output
  end
J
Jeremy Kemper 已提交
142

143 144 145 146
  def test_schema_dump_illegal_ignored_table_value
    stream = StringIO.new
    ActiveRecord::SchemaDumper.ignore_tables = [5]
    assert_raise(StandardError) do
147 148
      ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
    end
149
  end
150

151 152 153 154
  if current_adapter?(:MysqlAdapter)
    def test_schema_dump_should_not_add_default_value_for_mysql_text_field
      output = standard_dump
      assert_match %r{t.text\s+"body",\s+:null => false$}, output
155
    end
156

157 158 159 160 161
    def test_mysql_schema_dump_should_honor_nonstandard_primary_keys
      output = standard_dump
      match = output.match(%r{create_table "movies"(.*)do})
      assert_not_nil(match, "nonstandardpk table not found")
      assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved"
162 163
    end

164 165 166 167 168 169 170 171 172 173
    def test_schema_dump_includes_length_for_mysql_blob_and_text_fields
      output = standard_dump
      assert_match %r{t.binary\s+"tiny_blob",\s+:limit => 255$}, output
      assert_match %r{t.binary\s+"normal_blob"$}, output
      assert_match %r{t.binary\s+"medium_blob",\s+:limit => 16777215$}, output
      assert_match %r{t.binary\s+"long_blob",\s+:limit => 2147483647$}, output
      assert_match %r{t.text\s+"tiny_text",\s+:limit => 255$}, output
      assert_match %r{t.text\s+"normal_text"$}, output
      assert_match %r{t.text\s+"medium_text",\s+:limit => 16777215$}, output
      assert_match %r{t.text\s+"long_text",\s+:limit => 2147483647$}, output
174
    end
175
  end
176

177 178 179 180 181 182 183
  def test_schema_dump_includes_decimal_options
    stream = StringIO.new
    ActiveRecord::SchemaDumper.ignore_tables = [/^[^n]/]
    ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
    output = stream.string
    assert_match %r{:precision => 3,[[:space:]]+:scale => 2,[[:space:]]+:default => 2.78}, output
  end
184
end