aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/schema_dumper_test.rb
blob: c6041e4f5c0197334bca11d48cdb238c73aa3c44 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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
121
122
123
124
125
126
127
128
129
130
131
require 'abstract_unit'
require "#{File.dirname(__FILE__)}/../lib/active_record/schema_dumper"
require 'stringio'

if ActiveRecord::Base.connection.respond_to?(:tables)

  class SchemaDumperTest < Test::Unit::TestCase
    def standard_dump
      stream = StringIO.new
      ActiveRecord::SchemaDumper.ignore_tables = []
      ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
      stream.string
    end
    
    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_info"}, output
    end
    
    def test_schema_dump_excludes_sqlite_sequence
      output = standard_dump
      assert_no_match %r{create_table "sqlite_sequence"}, output
    end

    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

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

    def test_types_line_up
      column_definition_lines.each do |column_set|
        next if column_set.empty?

        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
          end
        end

        assert_equal 1, lengths.uniq.length
      end
    end
    
    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 => /)
      end
    end
    
    def test_no_dump_errors
      output = standard_dump
      assert_no_match %r{\# Could not dump table}, output
    end
    
    def test_schema_dump_includes_not_null_columns
      stream = StringIO.new
      
      ActiveRecord::SchemaDumper.ignore_tables = [/^[^r]/]
      ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
      output = stream.string
      assert_match %r{:null => false}, output
    end

    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_info"}, output
    end


    def test_schema_dump_with_regexp_ignored_table
      stream = StringIO.new
      
      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_info"}, output
    end


    def test_schema_dump_illegal_ignored_table_value
      stream = StringIO.new      
      ActiveRecord::SchemaDumper.ignore_tables = [5]      
      assert_raise(StandardError) do
        ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
      end
    end

    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+:default => "",\s+:null => false$}, output
      end

      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"
      end
    end

    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
  end

end