diff options
Diffstat (limited to 'activerecord/test')
-rw-r--r-- | activerecord/test/cases/column_definition_test.rb | 7 | ||||
-rw-r--r-- | activerecord/test/cases/defaults_test.rb | 86 | ||||
-rw-r--r-- | activerecord/test/cases/schema_dumper_test.rb | 78 |
3 files changed, 111 insertions, 60 deletions
diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb index 989beaa5c8..a65bb89052 100644 --- a/activerecord/test/cases/column_definition_test.rb +++ b/activerecord/test/cases/column_definition_test.rb @@ -60,14 +60,13 @@ module ActiveRecord end def test_should_not_set_default_for_blob_and_text_data_types - text_type = MySQL::TypeMetadata.new( - SqlTypeMetadata.new(type: :text)) + text_type = MySQL::TypeMetadata.new(SqlTypeMetadata.new(type: :text)) text_column = MySQL::Column.new("title", nil, text_type) - assert_equal nil, text_column.default + assert_nil text_column.default not_null_text_column = MySQL::Column.new("title", nil, text_type, false) - assert_equal "", not_null_text_column.default + assert_nil not_null_text_column.default end def test_has_default_should_return_false_for_blob_and_text_data_types diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb index f94815d34c..fcaff38f82 100644 --- a/activerecord/test/cases/defaults_test.rb +++ b/activerecord/test/cases/defaults_test.rb @@ -127,92 +127,66 @@ if current_adapter?(:Mysql2Adapter) ActiveRecord::Base.establish_connection connection end - # MySQL cannot have defaults on text/blob columns. It reports the - # default value as null. + # Strict mode controls how MySQL handles invalid or missing values + # in data-change statements such as INSERT or UPDATE. A value can be + # invalid for several reasons. For example, it might have the wrong + # data type for the column, or it might be out of range. A value is + # missing when a new row to be inserted does not contain a value for + # a non-NULL column that has no explicit DEFAULT clause in its definition. + # (For a NULL column, NULL is inserted if the value is missing.) # - # Despite this, in non-strict mode, MySQL will use an empty string - # as the default value of the field, if no other value is - # specified. + # If strict mode is not in effect, MySQL inserts adjusted values for + # invalid or missing values and produces warnings. In strict mode, + # you can produce this behavior by using INSERT IGNORE or UPDATE IGNORE. # - # Therefore, in non-strict mode, we want column.default to report - # an empty string as its default, to be consistent with that. - # - # In strict mode, column.default should be nil. - def test_mysql_text_not_null_defaults_non_strict + # https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-strict + def test_mysql_not_null_defaults_non_strict using_strict(false) do - with_text_blob_not_null_table do |klass| + with_mysql_not_null_table do |klass| record = klass.new - assert_equal "", record.non_null_blob - assert_equal "", record.non_null_text - - assert_nil record.null_blob - assert_nil record.null_text + assert_nil record.non_null_integer + assert_nil record.non_null_string + assert_nil record.non_null_text + assert_nil record.non_null_blob record.save! record.reload + assert_equal 0, record.non_null_integer + assert_equal "", record.non_null_string assert_equal "", record.non_null_text assert_equal "", record.non_null_blob - - assert_nil record.null_text - assert_nil record.null_blob end end end - def test_mysql_text_not_null_defaults_strict + def test_mysql_not_null_defaults_strict using_strict(true) do - with_text_blob_not_null_table do |klass| + with_mysql_not_null_table do |klass| record = klass.new - assert_nil record.non_null_blob + assert_nil record.non_null_integer + assert_nil record.non_null_string assert_nil record.non_null_text - assert_nil record.null_blob - assert_nil record.null_text + assert_nil record.non_null_blob assert_raises(ActiveRecord::StatementInvalid) { klass.create } end end end - def with_text_blob_not_null_table + def with_mysql_not_null_table klass = Class.new(ActiveRecord::Base) - klass.table_name = "test_mysql_text_not_null_defaults" + klass.table_name = "test_mysql_not_null_defaults" klass.connection.create_table klass.table_name do |t| - t.column :non_null_text, :text, null: false - t.column :non_null_blob, :blob, null: false - t.column :null_text, :text, null: true - t.column :null_blob, :blob, null: true + t.integer :non_null_integer, null: false + t.string :non_null_string, null: false + t.text :non_null_text, null: false + t.blob :non_null_blob, null: false end yield klass ensure klass.connection.drop_table(klass.table_name) rescue nil end - - # MySQL uses an implicit default 0 rather than NULL unless in strict mode. - # We use an implicit NULL so schema.rb is compatible with other databases. - def test_mysql_integer_not_null_defaults - klass = Class.new(ActiveRecord::Base) - klass.table_name = "test_integer_not_null_default_zero" - klass.connection.create_table klass.table_name do |t| - t.column :zero, :integer, null: false, default: 0 - t.column :omit, :integer, null: false - end - - assert_equal "0", klass.columns_hash["zero"].default - assert !klass.columns_hash["zero"].null - assert_equal nil, klass.columns_hash["omit"].default - assert !klass.columns_hash["omit"].null - - assert_raise(ActiveRecord::StatementInvalid) { klass.create! } - - assert_nothing_raised do - instance = klass.create!(omit: 1) - assert_equal 0, instance.zero - assert_equal 1, instance.omit - end - ensure - klass.connection.drop_table(klass.table_name) rescue nil - end end end diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 33baf84ef2..23cfe46d7f 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -442,3 +442,81 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase assert_match %r{t\.time\s+"time_with_default",\s+default: '2000-01-01 07:17:04'}, output end end + +class SchemaDumperNoStandardizedArgumentWidthsTest < ActiveRecord::TestCase + include SchemaDumpingHelper + + setup do + ActiveRecord::SchemaDumper.standardized_argument_widths = false + ActiveRecord::SchemaMigration.create_table + end + + teardown do + ActiveRecord::SchemaDumper.standardized_argument_widths = true + end + + def standard_dump + @@standard_dump ||= perform_schema_dump + end + + def perform_schema_dump + dump_all_table_schema [] + end + + def assert_no_line_up(lines, pattern) + return assert(true) if lines.empty? + matches = lines.map { |line| line.match(pattern) } + matches.compact! + return assert(true) if matches.empty? + line_matches = lines.map { |line| [line, line.match(pattern)] }.select { |line, match| match } + assert line_matches.all? { |line, match| + start = match.offset(0).first + line[start - 2..start - 1] == ", " + } + end + + def column_definition_lines(output = standard_dump) + output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map { |m| m.last.split(/\n/) } + end + + def test_arguments_no_line_up + column_definition_lines.each do |column_set| + assert_no_line_up(column_set, /default: /) + assert_no_line_up(column_set, /limit: /) + assert_no_line_up(column_set, /null: /) + end + end +end + +class SchemaDumperNoStandardizedTypeWidthsTest < ActiveRecord::TestCase + include SchemaDumpingHelper + + setup do + ActiveRecord::SchemaDumper.standardized_type_widths = false + ActiveRecord::SchemaMigration.create_table + end + + teardown do + ActiveRecord::SchemaDumper.standardized_type_widths = true + end + + def standard_dump + @@standard_dump ||= perform_schema_dump + end + + def perform_schema_dump + dump_all_table_schema [] + 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_no_line_up + column_definition_lines.each do |column_set| + next if column_set.empty? + + assert column_set.all? { |column| !column.match(/\bt\.\w+\s{2,}/) } + end + end +end |