schema_dumper_test.rb 6.6 KB
Newer Older
1
require "cases/helper"
2 3 4
require 'stringio'


5 6 7 8 9 10 11
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 已提交
12

13 14 15 16 17 18
  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 已提交
19

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

25 26 27 28 29
  def test_schema_dump_includes_camelcase_table_name
    output = standard_dump
    assert_match %r{create_table "CamelCase"}, output
  end

30 31 32 33 34 35 36 37
  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
38

39 40 41
  def column_definition_lines(output = standard_dump)
    output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map{ |m| m.last.split(/\n/) }
  end
42

43 44 45
  def test_types_line_up
    column_definition_lines.each do |column_set|
      next if column_set.empty?
46

47 48 49
      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
50 51
        end
      end
J
Jeremy Kemper 已提交
52

53
      assert_equal 1, lengths.uniq.length
54
    end
55
  end
J
Jeremy Kemper 已提交
56

57 58 59 60 61
  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 => /)
62
    end
63
  end
J
Jeremy Kemper 已提交
64

65 66 67 68
  def test_no_dump_errors
    output = standard_dump
    assert_no_match %r{\# Could not dump table}, output
  end
J
Jeremy Kemper 已提交
69

70 71
  def test_schema_dump_includes_not_null_columns
    stream = StringIO.new
72

73 74 75 76 77
    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 已提交
78

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  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)
J
Jeremy Kemper 已提交
97
      assert_match %r{c_int_1.*:limit => 1}, output
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
      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

125 126 127 128 129 130 131 132 133 134 135 136 137
  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
138

139 140 141 142 143 144 145
    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 已提交
146

147 148 149 150
  def test_schema_dump_illegal_ignored_table_value
    stream = StringIO.new
    ActiveRecord::SchemaDumper.ignore_tables = [5]
    assert_raise(StandardError) do
151 152
      ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
    end
153
  end
154

155 156 157 158
  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
159
    end
160

161 162 163 164 165
    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"
166 167
    end

168 169 170 171 172 173 174 175 176 177
    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
178
    end
179
  end
180

181 182 183 184 185 186 187
  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
188
end