aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb6
-rw-r--r--activerecord/test/cases/associations/eager_test.rb22
-rw-r--r--activerecord/test/cases/column_definition_test.rb7
-rw-r--r--activerecord/test/cases/defaults_test.rb86
-rw-r--r--activerecord/test/cases/migration_test.rb17
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb78
-rw-r--r--activerecord/test/models/post.rb1
7 files changed, 149 insertions, 68 deletions
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index 4b8d06be4b..e6af93a53e 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -88,12 +88,6 @@ module ActiveRecord
assert_equal expect.to_i, result.rows.first.first
end
- def test_sql_for_insert_with_returning_disabled
- connection = connection_without_insert_returning
- sql, binds = connection.sql_for_insert("sql", nil, nil, nil, "binds")
- assert_equal ["sql", "binds"], [sql, binds]
- end
-
def test_serial_sequence
assert_equal "public.accounts_id_seq",
@connection.serial_sequence("accounts", "id")
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 2c826acf96..6011c552b2 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -1424,6 +1424,24 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert david.readonly_comments.first.readonly?
end
+ test "eager-loading non-readonly association" do
+ # has_one
+ firm = Firm.where(id: "1").eager_load(:account).first!
+ assert_not firm.account.readonly?
+
+ # has_and_belongs_to_many
+ project = Project.where(id: "2").eager_load(:developers).first!
+ assert_not project.developers.first.readonly?
+
+ # has_many :through
+ david = Author.where(id: "1").eager_load(:comments).first!
+ assert_not david.comments.first.readonly?
+
+ # belongs_to
+ post = Post.where(id: "1").eager_load(:author).first!
+ assert_not post.author.readonly?
+ end
+
test "eager-loading readonly association" do
# has-one
firm = Firm.where(id: "1").eager_load(:readonly_account).first!
@@ -1438,8 +1456,8 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert david.readonly_comments.first.readonly?
# belongs_to
- post = Post.where(id: "1").eager_load(:author).first!
- assert post.author.readonly?
+ post = Post.where(id: "1").eager_load(:readonly_author).first!
+ assert post.readonly_author.readonly?
end
test "preloading a polymorphic association with references to the associated table" do
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/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 76a4592ac5..151f3c8efd 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -551,6 +551,23 @@ class MigrationTest < ActiveRecord::TestCase
end
end
+ if current_adapter?(:SQLite3Adapter)
+ def test_allows_sqlite3_rollback_on_invalid_column_type
+ Person.connection.create_table :something, force: true do |t|
+ t.column :number, :integer
+ t.column :name, :string
+ t.column :foo, :bar
+ end
+ assert Person.connection.column_exists?(:something, :foo)
+ assert_nothing_raised { Person.connection.remove_column :something, :foo, :bar }
+ assert !Person.connection.column_exists?(:something, :foo)
+ assert Person.connection.column_exists?(:something, :name)
+ assert Person.connection.column_exists?(:something, :number)
+ ensure
+ Person.connection.drop_table :something, if_exists: true
+ end
+ end
+
if current_adapter? :OracleAdapter
def test_create_table_with_custom_sequence_name
# table name is 29 chars, the standard sequence name will
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
diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb
index 42eff9cff9..66a99cbcda 100644
--- a/activerecord/test/models/post.rb
+++ b/activerecord/test/models/post.rb
@@ -24,6 +24,7 @@ class Post < ActiveRecord::Base
scope :limit_by, lambda { |l| limit(l) }
belongs_to :author
+ belongs_to :readonly_author, -> { readonly }, class_name: "Author", foreign_key: :author_id
belongs_to :author_with_posts, -> { includes(:posts) }, class_name: "Author", foreign_key: :author_id
belongs_to :author_with_address, -> { includes(:author_address) }, class_name: "Author", foreign_key: :author_id