diff options
Diffstat (limited to 'activerecord/test/cases')
231 files changed, 10285 insertions, 9189 deletions
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index 34e3bc9d66..8fa0645b0f 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -33,10 +33,10 @@ module ActiveRecord def test_tables tables = nil ActiveSupport::Deprecation.silence { tables = @connection.tables } - assert tables.include?("accounts") - assert tables.include?("authors") - assert tables.include?("tasks") - assert tables.include?("topics") + assert_includes tables, "accounts" + assert_includes tables, "authors" + assert_includes tables, "tasks" + assert_includes tables, "topics" end def test_table_exists? @@ -53,10 +53,10 @@ module ActiveRecord def test_data_sources data_sources = @connection.data_sources - assert data_sources.include?("accounts") - assert data_sources.include?("authors") - assert data_sources.include?("tasks") - assert data_sources.include?("topics") + assert_includes data_sources, "accounts" + assert_includes data_sources, "authors" + assert_includes data_sources, "tasks" + assert_includes data_sources, "topics" end def test_data_source_exists? @@ -73,7 +73,7 @@ module ActiveRecord indexes = @connection.indexes("accounts") assert indexes.empty? - @connection.add_index :accounts, :firm_id, :name => idx_name + @connection.add_index :accounts, :firm_id, name: idx_name indexes = @connection.indexes("accounts") assert_equal "accounts", indexes.first.table assert_equal idx_name, indexes.first.name @@ -84,47 +84,47 @@ module ActiveRecord end ensure - @connection.remove_index(:accounts, :name => idx_name) rescue nil + @connection.remove_index(:accounts, name: idx_name) rescue nil end def test_remove_index_when_name_and_wrong_column_name_specified index_name = "accounts_idx" - @connection.add_index :accounts, :firm_id, :name => index_name + @connection.add_index :accounts, :firm_id, name: index_name assert_raises ArgumentError do - @connection.remove_index :accounts, :name => index_name, :column => :wrong_column_name + @connection.remove_index :accounts, name: index_name, column: :wrong_column_name end ensure - @connection.remove_index(:accounts, :name => index_name) + @connection.remove_index(:accounts, name: index_name) end def test_current_database if @connection.respond_to?(:current_database) - assert_equal ARTest.connection_config['arunit']['database'], @connection.current_database + assert_equal ARTest.connection_config["arunit"]["database"], @connection.current_database end end if current_adapter?(:Mysql2Adapter) def test_charset assert_not_nil @connection.charset - assert_not_equal 'character_set_database', @connection.charset - assert_equal @connection.show_variable('character_set_database'), @connection.charset + assert_not_equal "character_set_database", @connection.charset + assert_equal @connection.show_variable("character_set_database"), @connection.charset end def test_collation assert_not_nil @connection.collation - assert_not_equal 'collation_database', @connection.collation - assert_equal @connection.show_variable('collation_database'), @connection.collation + assert_not_equal "collation_database", @connection.collation + assert_equal @connection.show_variable("collation_database"), @connection.collation end def test_show_nonexistent_variable_returns_nil - assert_nil @connection.show_variable('foo_bar_baz') + assert_nil @connection.show_variable("foo_bar_baz") end def test_not_specifying_database_name_for_cross_database_selects begin assert_nothing_raised do - ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['arunit'].except(:database)) + ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["arunit"].except(:database)) config = ARTest.connection_config ActiveRecord::Base.connection.execute( @@ -145,9 +145,9 @@ module ActiveRecord alias_method :table_alias_length, :test_table_alias_length end - assert_equal 'posts', @connection.table_alias_for('posts') - assert_equal 'posts_comm', @connection.table_alias_for('posts_comments') - assert_equal 'dbo_posts', @connection.table_alias_for('dbo.posts') + assert_equal "posts", @connection.table_alias_for("posts") + assert_equal "posts_comm", @connection.table_alias_for("posts_comments") + assert_equal "dbo_posts", @connection.table_alias_for("dbo.posts") class << @connection remove_method :table_alias_length @@ -157,20 +157,20 @@ module ActiveRecord # test resetting sequences in odd tables in PostgreSQL if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!) - require 'models/movie' - require 'models/subscriber' + require "models/movie" + require "models/subscriber" def test_reset_empty_table_with_custom_pk Movie.delete_all - Movie.connection.reset_pk_sequence! 'movies' - assert_equal 1, Movie.create(:name => 'fight club').id + Movie.connection.reset_pk_sequence! "movies" + assert_equal 1, Movie.create(name: "fight club").id end def test_reset_table_with_non_integer_pk Subscriber.delete_all - Subscriber.connection.reset_pk_sequence! 'subscribers' - sub = Subscriber.new(:name => 'robert drake') - sub.id = 'bob drake' + Subscriber.connection.reset_pk_sequence! "subscribers" + sub = Subscriber.new(name: "robert drake") + sub.id = "bob drake" assert_nothing_raised { sub.save! } end end @@ -201,7 +201,7 @@ module ActiveRecord def test_foreign_key_violations_are_translated_to_specific_exception_with_validate_false klass_has_fk = Class.new(ActiveRecord::Base) do - self.table_name = 'fk_test_has_fk' + self.table_name = "fk_test_has_fk" end error = assert_raises(ActiveRecord::InvalidForeignKey) do @@ -215,7 +215,7 @@ module ActiveRecord def test_value_limit_violations_are_translated_to_specific_exception error = assert_raises(ActiveRecord::ValueTooLong) do - Event.create(title: 'abcdefgh') + Event.create(title: "abcdefgh") end assert_not_nil error.cause @@ -245,21 +245,21 @@ module ActiveRecord end def test_select_methods_passing_a_association_relation - author = Author.create!(name: 'john') - Post.create!(author: author, title: 'foo', body: 'bar') - query = author.posts.where(title: 'foo').select(:title) - assert_equal({"title" => "foo"}, @connection.select_one(query.arel, nil, query.bound_attributes)) - assert_equal({"title" => "foo"}, @connection.select_one(query)) + author = Author.create!(name: "john") + Post.create!(author: author, title: "foo", body: "bar") + query = author.posts.where(title: "foo").select(:title) + assert_equal({ "title" => "foo" }, @connection.select_one(query.arel, nil, query.bound_attributes)) + assert_equal({ "title" => "foo" }, @connection.select_one(query)) assert @connection.select_all(query).is_a?(ActiveRecord::Result) assert_equal "foo", @connection.select_value(query) assert_equal ["foo"], @connection.select_values(query) end def test_select_methods_passing_a_relation - Post.create!(title: 'foo', body: 'bar') - query = Post.where(title: 'foo').select(:title) - assert_equal({"title" => "foo"}, @connection.select_one(query.arel, nil, query.bound_attributes)) - assert_equal({"title" => "foo"}, @connection.select_one(query)) + Post.create!(title: "foo", body: "bar") + query = Post.where(title: "foo").select(:title) + assert_equal({ "title" => "foo" }, @connection.select_one(query.arel, nil, query.bound_attributes)) + assert_equal({ "title" => "foo" }, @connection.select_one(query)) assert @connection.select_all(query).is_a?(ActiveRecord::Result) assert_equal "foo", @connection.select_value(query) assert_equal ["foo"], @connection.select_values(query) @@ -273,7 +273,7 @@ module ActiveRecord def test_log_invalid_encoding error = assert_raise ActiveRecord::StatementInvalid do @connection.send :log, "SELECT 'ы' FROM DUAL" do - raise 'ы'.force_encoding(Encoding::ASCII_8BIT) + raise "ы".force_encoding(Encoding::ASCII_8BIT) end end diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb index 99f97c7914..a70eb5a094 100644 --- a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb +++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/connection_helper' +require "support/connection_helper" class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase include ConnectionHelper @@ -21,56 +21,56 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase def (ActiveRecord::Base.connection).index_name_exists?(*); false; end expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`) " - assert_equal expected, add_index(:people, :last_name, :length => nil) + assert_equal expected, add_index(:people, :last_name, length: nil) expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`(10)) " - assert_equal expected, add_index(:people, :last_name, :length => 10) + assert_equal expected, add_index(:people, :last_name, length: 10) expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(15)) " - assert_equal expected, add_index(:people, [:last_name, :first_name], :length => 15) + assert_equal expected, add_index(:people, [:last_name, :first_name], length: 15) expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`) " - assert_equal expected, add_index(:people, [:last_name, :first_name], :length => {:last_name => 15}) + assert_equal expected, add_index(:people, [:last_name, :first_name], length: { last_name: 15 }) expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(10)) " - assert_equal expected, add_index(:people, [:last_name, :first_name], :length => {:last_name => 15, :first_name => 10}) + assert_equal expected, add_index(:people, [:last_name, :first_name], length: { last_name: 15, first_name: 10 }) %w(SPATIAL FULLTEXT UNIQUE).each do |type| expected = "CREATE #{type} INDEX `index_people_on_last_name` ON `people` (`last_name`) " - assert_equal expected, add_index(:people, :last_name, :type => type) + assert_equal expected, add_index(:people, :last_name, type: type) end %w(btree hash).each do |using| expected = "CREATE INDEX `index_people_on_last_name` USING #{using} ON `people` (`last_name`) " - assert_equal expected, add_index(:people, :last_name, :using => using) + assert_equal expected, add_index(:people, :last_name, using: using) end expected = "CREATE INDEX `index_people_on_last_name` USING btree ON `people` (`last_name`(10)) " - assert_equal expected, add_index(:people, :last_name, :length => 10, :using => :btree) + assert_equal expected, add_index(:people, :last_name, length: 10, using: :btree) expected = "CREATE INDEX `index_people_on_last_name` USING btree ON `people` (`last_name`(10)) ALGORITHM = COPY" - assert_equal expected, add_index(:people, :last_name, :length => 10, using: :btree, algorithm: :copy) + assert_equal expected, add_index(:people, :last_name, length: 10, using: :btree, algorithm: :copy) assert_raise ArgumentError do add_index(:people, :last_name, algorithm: :coyp) end expected = "CREATE INDEX `index_people_on_last_name_and_first_name` USING btree ON `people` (`last_name`(15), `first_name`(15)) " - assert_equal expected, add_index(:people, [:last_name, :first_name], :length => 15, :using => :btree) + assert_equal expected, add_index(:people, [:last_name, :first_name], length: 15, using: :btree) end def test_index_in_create def (ActiveRecord::Base.connection).data_source_exists?(*); false; end %w(SPATIAL FULLTEXT UNIQUE).each do |type| - expected = "CREATE TABLE `people` (#{type} INDEX `index_people_on_last_name` (`last_name`) ) ENGINE=InnoDB" + expected = "CREATE TABLE `people` (#{type} INDEX `index_people_on_last_name` (`last_name`)) ENGINE=InnoDB" actual = ActiveRecord::Base.connection.create_table(:people, id: false) do |t| t.index :last_name, type: type end assert_equal expected, actual end - expected = "CREATE TABLE `people` ( INDEX `index_people_on_last_name` USING btree (`last_name`(10)) ) ENGINE=InnoDB" + expected = "CREATE TABLE `people` ( INDEX `index_people_on_last_name` USING btree (`last_name`(10))) ENGINE=InnoDB" actual = ActiveRecord::Base.connection.create_table(:people, id: false) do |t| t.index :last_name, length: 10, using: :btree end @@ -102,13 +102,13 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase def test_create_mysql_database_with_encoding assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8`", create_database(:matt) - assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, {:charset => 'latin1'}) - assert_equal "CREATE DATABASE `matt_aimonetti` DEFAULT CHARACTER SET `big5` COLLATE `big5_chinese_ci`", create_database(:matt_aimonetti, {:charset => :big5, :collation => :big5_chinese_ci}) + assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, charset: "latin1") + assert_equal "CREATE DATABASE `matt_aimonetti` DEFAULT CHARACTER SET `big5` COLLATE `big5_chinese_ci`", create_database(:matt_aimonetti, charset: :big5, collation: :big5_chinese_ci) end def test_recreate_mysql_database_with_encoding - create_database(:luca, {:charset => 'latin1'}) - assert_equal "CREATE DATABASE `luca` DEFAULT CHARACTER SET `latin1`", recreate_database(:luca, {:charset => 'latin1'}) + create_database(:luca, charset: "latin1") + assert_equal "CREATE DATABASE `luca` DEFAULT CHARACTER SET `latin1`", recreate_database(:luca, charset: "latin1") end def test_add_column @@ -116,11 +116,11 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase end def test_add_column_with_limit - assert_equal "ALTER TABLE `people` ADD `key` varchar(32)", add_column(:people, :key, :string, :limit => 32) + assert_equal "ALTER TABLE `people` ADD `key` varchar(32)", add_column(:people, :key, :string, limit: 32) end def test_drop_table_with_specific_database - assert_equal "DROP TABLE `otherdb`.`people`", drop_table('otherdb.people') + assert_equal "DROP TABLE `otherdb`.`people`", drop_table("otherdb.people") end def test_add_timestamps @@ -128,8 +128,8 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase begin ActiveRecord::Base.connection.create_table :delete_me ActiveRecord::Base.connection.add_timestamps :delete_me, null: true - assert column_present?('delete_me', 'updated_at', 'datetime') - assert column_present?('delete_me', 'created_at', 'datetime') + assert column_present?("delete_me", "updated_at", "datetime") + assert column_present?("delete_me", "created_at", "datetime") ensure ActiveRecord::Base.connection.drop_table :delete_me rescue nil end @@ -142,9 +142,9 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase ActiveRecord::Base.connection.create_table :delete_me do |t| t.timestamps null: true end - ActiveRecord::Base.connection.remove_timestamps :delete_me, { null: true } - assert !column_present?('delete_me', 'updated_at', 'datetime') - assert !column_present?('delete_me', 'created_at', 'datetime') + ActiveRecord::Base.connection.remove_timestamps :delete_me, null: true + assert !column_present?("delete_me", "updated_at", "datetime") + assert !column_present?("delete_me", "created_at", "datetime") ensure ActiveRecord::Base.connection.drop_table :delete_me rescue nil end @@ -155,7 +155,7 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase ActiveRecord::Base.connection.stubs(:data_source_exists?).with(:temp).returns(false) ActiveRecord::Base.connection.stubs(:index_name_exists?).with(:index_temp_on_zip).returns(false) - expected = "CREATE TEMPORARY TABLE `temp` ( INDEX `index_temp_on_zip` (`zip`) ) ENGINE=InnoDB AS SELECT id, name, zip FROM a_really_complicated_query" + expected = "CREATE TEMPORARY TABLE `temp` ( INDEX `index_temp_on_zip` (`zip`)) ENGINE=InnoDB AS SELECT id, name, zip FROM a_really_complicated_query" actual = ActiveRecord::Base.connection.create_table(:temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query") do |t| t.index :zip end @@ -185,6 +185,6 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase def column_present?(table_name, column_name, type) results = ActiveRecord::Base.connection.select_all("SHOW FIELDS FROM #{table_name} LIKE '#{column_name}'") - results.first && results.first['Type'] == type + results.first && results.first["Type"] == type end end diff --git a/activerecord/test/cases/adapters/mysql2/bind_parameter_test.rb b/activerecord/test/cases/adapters/mysql2/bind_parameter_test.rb index abdf3dbf5b..8f7c803a21 100644 --- a/activerecord/test/cases/adapters/mysql2/bind_parameter_test.rb +++ b/activerecord/test/cases/adapters/mysql2/bind_parameter_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'models/topic' +require "models/topic" module ActiveRecord module ConnectionAdapters @@ -20,7 +20,7 @@ module ActiveRecord def test_create_question_marks str = "foo?bar" - x = Topic.create!(:title => str, :content => str) + x = Topic.create!(title: str, content: str) x.reload assert_equal str, x.title assert_equal str, x.content @@ -39,7 +39,7 @@ module ActiveRecord def test_create_null_bytes str = "foo\0bar" - x = Topic.create!(:title => str, :content => str) + x = Topic.create!(title: str, content: str) x.reload assert_equal str, x.title assert_equal str, x.content diff --git a/activerecord/test/cases/adapters/mysql2/boolean_test.rb b/activerecord/test/cases/adapters/mysql2/boolean_test.rb index 739bb275ce..2fa39282fb 100644 --- a/activerecord/test/cases/adapters/mysql2/boolean_test.rb +++ b/activerecord/test/cases/adapters/mysql2/boolean_test.rb @@ -86,11 +86,11 @@ class Mysql2BooleanTest < ActiveRecord::Mysql2TestCase end def boolean_column - BooleanType.columns.find { |c| c.name == 'archived' } + BooleanType.columns.find { |c| c.name == "archived" } end def string_column - BooleanType.columns.find { |c| c.name == 'published' } + BooleanType.columns.find { |c| c.name == "published" } end def emulate_booleans(value) diff --git a/activerecord/test/cases/adapters/mysql2/case_sensitivity_test.rb b/activerecord/test/cases/adapters/mysql2/case_sensitivity_test.rb index 9cb05119a2..50ba9ab831 100644 --- a/activerecord/test/cases/adapters/mysql2/case_sensitivity_test.rb +++ b/activerecord/test/cases/adapters/mysql2/case_sensitivity_test.rb @@ -7,46 +7,46 @@ class Mysql2CaseSensitivityTest < ActiveRecord::Mysql2TestCase repair_validations(CollationTest) def test_columns_include_collation_different_from_table - assert_equal 'utf8_bin', CollationTest.columns_hash['string_cs_column'].collation - assert_equal 'utf8_general_ci', CollationTest.columns_hash['string_ci_column'].collation + assert_equal "utf8_bin", CollationTest.columns_hash["string_cs_column"].collation + assert_equal "utf8_general_ci", CollationTest.columns_hash["string_ci_column"].collation end def test_case_sensitive - assert !CollationTest.columns_hash['string_ci_column'].case_sensitive? - assert CollationTest.columns_hash['string_cs_column'].case_sensitive? + assert !CollationTest.columns_hash["string_ci_column"].case_sensitive? + assert CollationTest.columns_hash["string_cs_column"].case_sensitive? end def test_case_insensitive_comparison_for_ci_column - CollationTest.validates_uniqueness_of(:string_ci_column, :case_sensitive => false) - CollationTest.create!(:string_ci_column => 'A') - invalid = CollationTest.new(:string_ci_column => 'a') + CollationTest.validates_uniqueness_of(:string_ci_column, case_sensitive: false) + CollationTest.create!(string_ci_column: "A") + invalid = CollationTest.new(string_ci_column: "a") queries = assert_sql { invalid.save } ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) } assert_no_match(/lower/i, ci_uniqueness_query) end def test_case_insensitive_comparison_for_cs_column - CollationTest.validates_uniqueness_of(:string_cs_column, :case_sensitive => false) - CollationTest.create!(:string_cs_column => 'A') - invalid = CollationTest.new(:string_cs_column => 'a') + CollationTest.validates_uniqueness_of(:string_cs_column, case_sensitive: false) + CollationTest.create!(string_cs_column: "A") + invalid = CollationTest.new(string_cs_column: "a") queries = assert_sql { invalid.save } - cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/)} + cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) } assert_match(/lower/i, cs_uniqueness_query) end def test_case_sensitive_comparison_for_ci_column - CollationTest.validates_uniqueness_of(:string_ci_column, :case_sensitive => true) - CollationTest.create!(:string_ci_column => 'A') - invalid = CollationTest.new(:string_ci_column => 'A') + CollationTest.validates_uniqueness_of(:string_ci_column, case_sensitive: true) + CollationTest.create!(string_ci_column: "A") + invalid = CollationTest.new(string_ci_column: "A") queries = assert_sql { invalid.save } ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) } assert_match(/binary/i, ci_uniqueness_query) end def test_case_sensitive_comparison_for_cs_column - CollationTest.validates_uniqueness_of(:string_cs_column, :case_sensitive => true) - CollationTest.create!(:string_cs_column => 'A') - invalid = CollationTest.new(:string_cs_column => 'A') + CollationTest.validates_uniqueness_of(:string_cs_column, case_sensitive: true) + CollationTest.create!(string_cs_column: "A") + invalid = CollationTest.new(string_cs_column: "A") queries = assert_sql { invalid.save } cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) } assert_no_match(/binary/i, cs_uniqueness_query) @@ -54,8 +54,8 @@ class Mysql2CaseSensitivityTest < ActiveRecord::Mysql2TestCase def test_case_sensitive_comparison_for_binary_column CollationTest.validates_uniqueness_of(:binary_column, case_sensitive: true) - CollationTest.create!(binary_column: 'A') - invalid = CollationTest.new(binary_column: 'A') + CollationTest.create!(binary_column: "A") + invalid = CollationTest.new(binary_column: "A") queries = assert_sql { invalid.save } bin_uniqueness_query = queries.detect { |q| q.match(/binary_column/) } assert_no_match(/\bBINARY\b/, bin_uniqueness_query) diff --git a/activerecord/test/cases/adapters/mysql2/charset_collation_test.rb b/activerecord/test/cases/adapters/mysql2/charset_collation_test.rb index 668c07dacb..8826ad7fd1 100644 --- a/activerecord/test/cases/adapters/mysql2/charset_collation_test.rb +++ b/activerecord/test/cases/adapters/mysql2/charset_collation_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class Mysql2CharsetCollationTest < ActiveRecord::Mysql2TestCase include SchemaDumpingHelper @@ -8,8 +8,8 @@ class Mysql2CharsetCollationTest < ActiveRecord::Mysql2TestCase setup do @connection = ActiveRecord::Base.connection @connection.create_table :charset_collations, force: true do |t| - t.string :string_ascii_bin, charset: 'ascii', collation: 'ascii_bin' - t.text :text_ucs2_unicode_ci, charset: 'ucs2', collation: 'ucs2_unicode_ci' + t.string :string_ascii_bin, charset: "ascii", collation: "ascii_bin" + t.text :text_ucs2_unicode_ci, charset: "ucs2", collation: "ucs2_unicode_ci" end end @@ -18,37 +18,37 @@ class Mysql2CharsetCollationTest < ActiveRecord::Mysql2TestCase end test "string column with charset and collation" do - column = @connection.columns(:charset_collations).find { |c| c.name == 'string_ascii_bin' } + column = @connection.columns(:charset_collations).find { |c| c.name == "string_ascii_bin" } assert_equal :string, column.type - assert_equal 'ascii_bin', column.collation + assert_equal "ascii_bin", column.collation end test "text column with charset and collation" do - column = @connection.columns(:charset_collations).find { |c| c.name == 'text_ucs2_unicode_ci' } + column = @connection.columns(:charset_collations).find { |c| c.name == "text_ucs2_unicode_ci" } assert_equal :text, column.type - assert_equal 'ucs2_unicode_ci', column.collation + assert_equal "ucs2_unicode_ci", column.collation end test "add column with charset and collation" do - @connection.add_column :charset_collations, :title, :string, charset: 'utf8', collation: 'utf8_bin' + @connection.add_column :charset_collations, :title, :string, charset: "utf8", collation: "utf8_bin" - column = @connection.columns(:charset_collations).find { |c| c.name == 'title' } + column = @connection.columns(:charset_collations).find { |c| c.name == "title" } assert_equal :string, column.type - assert_equal 'utf8_bin', column.collation + assert_equal "utf8_bin", column.collation end test "change column with charset and collation" do - @connection.add_column :charset_collations, :description, :string, charset: 'utf8', collation: 'utf8_unicode_ci' - @connection.change_column :charset_collations, :description, :text, charset: 'utf8', collation: 'utf8_general_ci' + @connection.add_column :charset_collations, :description, :string, charset: "utf8", collation: "utf8_unicode_ci" + @connection.change_column :charset_collations, :description, :text, charset: "utf8", collation: "utf8_general_ci" - column = @connection.columns(:charset_collations).find { |c| c.name == 'description' } + column = @connection.columns(:charset_collations).find { |c| c.name == "description" } assert_equal :text, column.type - assert_equal 'utf8_general_ci', column.collation + assert_equal "utf8_general_ci", column.collation end test "schema dump includes collation" do output = dump_table_schema("charset_collations") assert_match %r{t.string\s+"string_ascii_bin",\s+collation: "ascii_bin"$}, output - assert_match %r{t.text\s+"text_ucs2_unicode_ci",\s+limit: 65535,\s+collation: "ucs2_unicode_ci"$}, output + assert_match %r{t.text\s+"text_ucs2_unicode_ci",\s+collation: "ucs2_unicode_ci"$}, output end end diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb index c4715393b3..8d8955e5c9 100644 --- a/activerecord/test/cases/adapters/mysql2/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/connection_helper' +require "support/connection_helper" class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase include ConnectionHelper @@ -9,7 +9,7 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase def setup super @subscriber = SQLSubscriber.new - @subscription = ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber) + @subscription = ActiveSupport::Notifications.subscribe("sql.active_record", @subscriber) @connection = ActiveRecord::Base.connection end @@ -20,9 +20,9 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase def test_bad_connection assert_raise ActiveRecord::NoDatabaseError do - configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'inexistent_activerecord_unittest') + configuration = ActiveRecord::Base.configurations["arunit"].merge(database: "inexistent_activerecord_unittest") connection = ActiveRecord::Base.mysql2_connection(configuration) - connection.drop_table 'ex', if_exists: true + connection.drop_table "ex", if_exists: true end end @@ -39,7 +39,7 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase def test_no_automatic_reconnection_after_timeout assert @connection.active? - @connection.update('set @@wait_timeout=1') + @connection.update("set @@wait_timeout=1") sleep 2 assert !@connection.active? @@ -49,7 +49,7 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase def test_successful_reconnection_after_timeout_with_manual_reconnect assert @connection.active? - @connection.update('set @@wait_timeout=1') + @connection.update("set @@wait_timeout=1") sleep 2 @connection.reconnect! assert @connection.active? @@ -57,15 +57,36 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase def test_successful_reconnection_after_timeout_with_verify assert @connection.active? - @connection.update('set @@wait_timeout=1') + @connection.update("set @@wait_timeout=1") sleep 2 @connection.verify! assert @connection.active? end + def test_execute_after_disconnect + @connection.disconnect! + error = assert_raise(ActiveRecord::StatementInvalid) do + @connection.execute("SELECT 1") + end + assert_match(/closed MySQL connection/, error.message) + end + + def test_quote_after_disconnect + @connection.disconnect! + error = assert_raise(Mysql2::Error) do + @connection.quote("string") + end + assert_match(/closed MySQL connection/, error.message) + end + + def test_active_after_disconnect + @connection.disconnect! + assert_equal false, @connection.active? + end + def test_mysql_connection_collation_is_configured - assert_equal 'utf8_unicode_ci', @connection.show_variable('collation_connection') - assert_equal 'utf8_general_ci', ARUnit2Model.connection.show_variable('collation_connection') + assert_equal "utf8_unicode_ci", @connection.show_variable("collation_connection") + assert_equal "utf8_general_ci", ARUnit2Model.connection.show_variable("collation_connection") end def test_mysql_default_in_strict_mode @@ -92,29 +113,29 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase def test_mysql_sql_mode_variable_overrides_strict_mode run_without_connection do |orig_connection| - ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { 'sql_mode' => 'ansi' })) - result = ActiveRecord::Base.connection.select_value('SELECT @@SESSION.sql_mode') + ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { "sql_mode" => "ansi" })) + result = ActiveRecord::Base.connection.select_value("SELECT @@SESSION.sql_mode") assert_no_match %r(STRICT_ALL_TABLES), result end end def test_passing_arbitary_flags_to_adapter run_without_connection do |orig_connection| - ActiveRecord::Base.establish_connection(orig_connection.merge({flags: Mysql2::Client::COMPRESS})) + ActiveRecord::Base.establish_connection(orig_connection.merge(flags: Mysql2::Client::COMPRESS)) assert_equal (Mysql2::Client::COMPRESS | Mysql2::Client::FOUND_ROWS), ActiveRecord::Base.connection.raw_connection.query_options[:flags] end end def test_passing_flags_by_array_to_adapter run_without_connection do |orig_connection| - ActiveRecord::Base.establish_connection(orig_connection.merge({flags: ['COMPRESS'] })) + ActiveRecord::Base.establish_connection(orig_connection.merge(flags: ["COMPRESS"])) assert_equal ["COMPRESS", "FOUND_ROWS"], ActiveRecord::Base.connection.raw_connection.query_options[:flags] end end def test_mysql_set_session_variable run_without_connection do |orig_connection| - ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:default_week_format => 3}})) + ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { default_week_format: 3 })) session_mode = ActiveRecord::Base.connection.exec_query "SELECT @@SESSION.DEFAULT_WEEK_FORMAT" assert_equal 3, session_mode.rows.first.first.to_i end @@ -122,7 +143,7 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase def test_mysql_set_session_variable_to_default run_without_connection do |orig_connection| - ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:default_week_format => :default}})) + ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { default_week_format: :default })) global_mode = ActiveRecord::Base.connection.exec_query "SELECT @@GLOBAL.DEFAULT_WEEK_FORMAT" session_mode = ActiveRecord::Base.connection.exec_query "SELECT @@SESSION.DEFAULT_WEEK_FORMAT" assert_equal global_mode.rows, session_mode.rows @@ -130,21 +151,21 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase end def test_logs_name_show_variable - @connection.show_variable 'foo' + @connection.show_variable "foo" assert_equal "SCHEMA", @subscriber.logged[0][1] end def test_logs_name_rename_column_sql @connection.execute "CREATE TABLE `bar_baz` (`foo` varchar(255))" @subscriber.logged.clear - @connection.send(:rename_column_sql, 'bar_baz', 'foo', 'foo2') + @connection.send(:rename_column_sql, "bar_baz", "foo", "foo2") assert_equal "SCHEMA", @subscriber.logged[0][1] ensure @connection.execute "DROP TABLE `bar_baz`" end def test_get_and_release_advisory_lock - lock_name = "test_lock_name" + lock_name = "test lock'n'name" got_lock = @connection.get_advisory_lock(lock_name) assert got_lock, "get_advisory_lock should have returned true but it didn't" @@ -155,19 +176,19 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase released_lock = @connection.release_advisory_lock(lock_name) assert released_lock, "expected release_advisory_lock to return true but it didn't" - assert test_lock_free(lock_name), 'expected the test lock to be available after releasing' + assert test_lock_free(lock_name), "expected the test lock to be available after releasing" end def test_release_non_existent_advisory_lock - lock_name = "fake_lock_name" + lock_name = "fake lock'n'name" released_non_existent_lock = @connection.release_advisory_lock(lock_name) assert_equal released_non_existent_lock, false, - 'expected release_advisory_lock to return false when there was no lock to release' + "expected release_advisory_lock to return false when there was no lock to release" end protected - def test_lock_free(lock_name) - @connection.select_value("SELECT IS_FREE_LOCK('#{lock_name}');") == 1 - end + def test_lock_free(lock_name) + @connection.select_value("SELECT IS_FREE_LOCK(#{@connection.quote(lock_name)})") == 1 + end end diff --git a/activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb b/activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb index e349c67c93..135789a57d 100644 --- a/activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +++ b/activerecord/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb @@ -5,23 +5,23 @@ class Mysql2DatetimePrecisionQuotingTest < ActiveRecord::Mysql2TestCase @connection = ActiveRecord::Base.connection end - test 'microsecond precision for MySQL gte 5.6.4' do - stub_version '5.6.4' + test "microsecond precision for MySQL gte 5.6.4" do + stub_version "5.6.4" assert_microsecond_precision end - test 'no microsecond precision for MySQL lt 5.6.4' do - stub_version '5.6.3' + test "no microsecond precision for MySQL lt 5.6.4" do + stub_version "5.6.3" assert_no_microsecond_precision end - test 'microsecond precision for MariaDB gte 5.3.0' do - stub_version '5.5.5-10.1.8-MariaDB-log' + test "microsecond precision for MariaDB gte 5.3.0" do + stub_version "5.5.5-10.1.8-MariaDB-log" assert_microsecond_precision end - test 'no microsecond precision for MariaDB lt 5.3.0' do - stub_version '5.2.9-MariaDB' + test "no microsecond precision for MariaDB lt 5.3.0" do + stub_version "5.2.9-MariaDB" assert_no_microsecond_precision end diff --git a/activerecord/test/cases/adapters/mysql2/enum_test.rb b/activerecord/test/cases/adapters/mysql2/enum_test.rb index 35dbc76d1b..7ad3e3ca2d 100644 --- a/activerecord/test/cases/adapters/mysql2/enum_test.rb +++ b/activerecord/test/cases/adapters/mysql2/enum_test.rb @@ -5,22 +5,17 @@ class Mysql2EnumTest < ActiveRecord::Mysql2TestCase end def test_enum_limit - column = EnumTest.columns_hash['enum_column'] + column = EnumTest.columns_hash["enum_column"] assert_equal 8, column.limit end - def test_should_not_be_blob_or_text_column - column = EnumTest.columns_hash['enum_column'] - assert_not column.blob_or_text_column? - end - def test_should_not_be_unsigned - column = EnumTest.columns_hash['enum_column'] + column = EnumTest.columns_hash["enum_column"] assert_not column.unsigned? end def test_should_not_be_bigint - column = EnumTest.columns_hash['enum_column'] + column = EnumTest.columns_hash["enum_column"] assert_not column.bigint? end end diff --git a/activerecord/test/cases/adapters/mysql2/explain_test.rb b/activerecord/test/cases/adapters/mysql2/explain_test.rb index b783b5fcd9..7916921e5a 100644 --- a/activerecord/test/cases/adapters/mysql2/explain_test.rb +++ b/activerecord/test/cases/adapters/mysql2/explain_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'models/developer' -require 'models/computer' +require "models/developer" +require "models/computer" class Mysql2ExplainTest < ActiveRecord::Mysql2TestCase fixtures :developers diff --git a/activerecord/test/cases/adapters/mysql2/json_test.rb b/activerecord/test/cases/adapters/mysql2/json_test.rb index 9c3fef1b59..630cdb36a4 100644 --- a/activerecord/test/cases/adapters/mysql2/json_test.rb +++ b/activerecord/test/cases/adapters/mysql2/json_test.rb @@ -1,179 +1,195 @@ -require 'cases/helper' -require 'support/schema_dumping_helper' +require "cases/helper" +require "support/schema_dumping_helper" if ActiveRecord::Base.connection.supports_json? -class Mysql2JSONTest < ActiveRecord::Mysql2TestCase - include SchemaDumpingHelper - self.use_transactional_tests = false + class Mysql2JSONTest < ActiveRecord::Mysql2TestCase + include SchemaDumpingHelper + self.use_transactional_tests = false - class JsonDataType < ActiveRecord::Base - self.table_name = 'json_data_type' + class JsonDataType < ActiveRecord::Base + self.table_name = "json_data_type" - store_accessor :settings, :resolution - end + store_accessor :settings, :resolution + end - def setup - @connection = ActiveRecord::Base.connection - begin - @connection.create_table('json_data_type') do |t| - t.json 'payload' - t.json 'settings' + def setup + @connection = ActiveRecord::Base.connection + begin + @connection.create_table("json_data_type") do |t| + t.json "payload" + t.json "settings" + end end end - end - def teardown - @connection.drop_table :json_data_type, if_exists: true - JsonDataType.reset_column_information - end + def teardown + @connection.drop_table :json_data_type, if_exists: true + JsonDataType.reset_column_information + end - def test_column - column = JsonDataType.columns_hash["payload"] - assert_equal :json, column.type - assert_equal 'json', column.sql_type + def test_column + column = JsonDataType.columns_hash["payload"] + assert_equal :json, column.type + assert_equal "json", column.sql_type - type = JsonDataType.type_for_attribute("payload") - assert_not type.binary? - end + type = JsonDataType.type_for_attribute("payload") + assert_not type.binary? + end - def test_change_table_supports_json - @connection.change_table('json_data_type') do |t| - t.json 'users' + def test_change_table_supports_json + @connection.change_table("json_data_type") do |t| + t.json "users" + end + JsonDataType.reset_column_information + column = JsonDataType.columns_hash["users"] + assert_equal :json, column.type end - JsonDataType.reset_column_information - column = JsonDataType.columns_hash['users'] - assert_equal :json, column.type - end - def test_schema_dumping - output = dump_table_schema("json_data_type") - assert_match(/t\.json\s+"settings"/, output) - end + def test_schema_dumping + output = dump_table_schema("json_data_type") + assert_match(/t\.json\s+"settings"/, output) + end - def test_cast_value_on_write - x = JsonDataType.new payload: {"string" => "foo", :symbol => :bar} - assert_equal({"string" => "foo", :symbol => :bar}, x.payload_before_type_cast) - assert_equal({"string" => "foo", "symbol" => "bar"}, x.payload) - x.save - assert_equal({"string" => "foo", "symbol" => "bar"}, x.reload.payload) - end + def test_cast_value_on_write + x = JsonDataType.new payload: { "string" => "foo", :symbol => :bar } + assert_equal({ "string" => "foo", :symbol => :bar }, x.payload_before_type_cast) + assert_equal({ "string" => "foo", "symbol" => "bar" }, x.payload) + x.save + assert_equal({ "string" => "foo", "symbol" => "bar" }, x.reload.payload) + end - def test_type_cast_json - type = JsonDataType.type_for_attribute("payload") + def test_type_cast_json + type = JsonDataType.type_for_attribute("payload") - data = "{\"a_key\":\"a_value\"}" - hash = type.deserialize(data) - assert_equal({'a_key' => 'a_value'}, hash) - assert_equal({'a_key' => 'a_value'}, type.deserialize(data)) + data = "{\"a_key\":\"a_value\"}" + hash = type.deserialize(data) + assert_equal({ "a_key" => "a_value" }, hash) + assert_equal({ "a_key" => "a_value" }, type.deserialize(data)) - assert_equal({}, type.deserialize("{}")) - assert_equal({'key'=>nil}, type.deserialize('{"key": null}')) - assert_equal({'c'=>'}','"a"'=>'b "a b'}, type.deserialize(%q({"c":"}", "\"a\"":"b \"a b"}))) - end + assert_equal({}, type.deserialize("{}")) + assert_equal({ "key"=>nil }, type.deserialize('{"key": null}')) + assert_equal({ "c"=>"}",'"a"'=>'b "a b' }, type.deserialize(%q({"c":"}", "\"a\"":"b \"a b"}))) + end - def test_rewrite - @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')" - x = JsonDataType.first - x.payload = { '"a\'' => 'b' } - assert x.save! - end + def test_rewrite + @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')" + x = JsonDataType.first + x.payload = { '"a\'' => "b" } + assert x.save! + end - def test_select - @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')" - x = JsonDataType.first - assert_equal({'k' => 'v'}, x.payload) - end + def test_select + @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')" + x = JsonDataType.first + assert_equal({ "k" => "v" }, x.payload) + end - def test_select_multikey - @connection.execute %q|insert into json_data_type (payload) VALUES ('{"k1":"v1", "k2":"v2", "k3":[1,2,3]}')| - x = JsonDataType.first - assert_equal({'k1' => 'v1', 'k2' => 'v2', 'k3' => [1,2,3]}, x.payload) - end + def test_select_multikey + @connection.execute %q|insert into json_data_type (payload) VALUES ('{"k1":"v1", "k2":"v2", "k3":[1,2,3]}')| + x = JsonDataType.first + assert_equal({ "k1" => "v1", "k2" => "v2", "k3" => [1,2,3] }, x.payload) + end - def test_null_json - @connection.execute %q|insert into json_data_type (payload) VALUES(null)| - x = JsonDataType.first - assert_equal(nil, x.payload) - end + def test_null_json + @connection.execute "insert into json_data_type (payload) VALUES(null)" + x = JsonDataType.first + assert_equal(nil, x.payload) + end - def test_select_array_json_value - @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')| - x = JsonDataType.first - assert_equal(['v0', {'k1' => 'v1'}], x.payload) - end + def test_select_array_json_value + @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')| + x = JsonDataType.first + assert_equal(["v0", { "k1" => "v1" }], x.payload) + end - def test_rewrite_array_json_value - @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')| - x = JsonDataType.first - x.payload = ['v1', {'k2' => 'v2'}, 'v3'] - assert x.save! - end + def test_select_nil_json_after_create + json = JsonDataType.create(payload: nil) + x = JsonDataType.where(payload:nil).first + assert_equal(json, x) + end - def test_with_store_accessors - x = JsonDataType.new(resolution: "320×480") - assert_equal "320×480", x.resolution + def test_select_nil_json_after_update + json = JsonDataType.create(payload: "foo") + x = JsonDataType.where(payload:nil).first + assert_equal(nil, x) - x.save! - x = JsonDataType.first - assert_equal "320×480", x.resolution + json.update_attributes payload: nil + x = JsonDataType.where(payload:nil).first + assert_equal(json.reload, x) + end - x.resolution = "640×1136" - x.save! + def test_rewrite_array_json_value + @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')| + x = JsonDataType.first + x.payload = ["v1", { "k2" => "v2" }, "v3"] + assert x.save! + end - x = JsonDataType.first - assert_equal "640×1136", x.resolution - end + def test_with_store_accessors + x = JsonDataType.new(resolution: "320×480") + assert_equal "320×480", x.resolution - def test_duplication_with_store_accessors - x = JsonDataType.new(resolution: "320×480") - assert_equal "320×480", x.resolution + x.save! + x = JsonDataType.first + assert_equal "320×480", x.resolution - y = x.dup - assert_equal "320×480", y.resolution - end + x.resolution = "640×1136" + x.save! - def test_yaml_round_trip_with_store_accessors - x = JsonDataType.new(resolution: "320×480") - assert_equal "320×480", x.resolution + x = JsonDataType.first + assert_equal "640×1136", x.resolution + end - y = YAML.load(YAML.dump(x)) - assert_equal "320×480", y.resolution - end + def test_duplication_with_store_accessors + x = JsonDataType.new(resolution: "320×480") + assert_equal "320×480", x.resolution - def test_changes_in_place - json = JsonDataType.new - assert_not json.changed? + y = x.dup + assert_equal "320×480", y.resolution + end - json.payload = { 'one' => 'two' } - assert json.changed? - assert json.payload_changed? + def test_yaml_round_trip_with_store_accessors + x = JsonDataType.new(resolution: "320×480") + assert_equal "320×480", x.resolution - json.save! - assert_not json.changed? + y = YAML.load(YAML.dump(x)) + assert_equal "320×480", y.resolution + end - json.payload['three'] = 'four' - assert json.payload_changed? + def test_changes_in_place + json = JsonDataType.new + assert_not json.changed? - json.save! - json.reload + json.payload = { "one" => "two" } + assert json.changed? + assert json.payload_changed? - assert_equal({ 'one' => 'two', 'three' => 'four' }, json.payload) - assert_not json.changed? - end + json.save! + assert_not json.changed? - def test_assigning_string_literal - json = JsonDataType.create(payload: "foo") - assert_equal "foo", json.payload - end + json.payload["three"] = "four" + assert json.payload_changed? - def test_assigning_number - json = JsonDataType.create(payload: 1.234) - assert_equal 1.234, json.payload - end + json.save! + json.reload - def test_assigning_boolean - json = JsonDataType.create(payload: true) - assert_equal true, json.payload + assert_equal({ "one" => "two", "three" => "four" }, json.payload) + assert_not json.changed? + end + + def test_assigning_string_literal + json = JsonDataType.create(payload: "foo") + assert_equal "foo", json.payload + end + + def test_assigning_number + json = JsonDataType.create(payload: 1.234) + assert_equal 1.234, json.payload + end + + def test_assigning_boolean + json = JsonDataType.create(payload: true) + assert_equal true, json.payload + end end end -end diff --git a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb index 61dd0828d0..69336eb906 100644 --- a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb +++ b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb @@ -11,15 +11,15 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase def test_exec_query_nothing_raises_with_no_result_queries assert_nothing_raised do with_example_table do - @conn.exec_query('INSERT INTO ex (number) VALUES (1)') - @conn.exec_query('DELETE FROM ex WHERE number = 1') + @conn.exec_query("INSERT INTO ex (number) VALUES (1)") + @conn.exec_query("DELETE FROM ex WHERE number = 1") end end end def test_valid_column with_example_table do - column = @conn.columns('ex').find { |col| col.name == 'id' } + column = @conn.columns("ex").find { |col| col.name == "id" } assert @conn.valid_type?(column.type) end end @@ -45,8 +45,8 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase def test_columns_for_distinct_with_case assert_equal( - 'posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0', - @conn.columns_for_distinct('posts.id', + "posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0", + @conn.columns_for_distinct("posts.id", ["CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END"]) ) end @@ -67,7 +67,7 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase private - def with_example_table(definition = 'id int auto_increment primary key, number int, data varchar(255)', &block) - super(@conn, 'ex', definition, &block) - end + def with_example_table(definition = "id int auto_increment primary key, number int, data varchar(255)", &block) + super(@conn, "ex", definition, &block) + end end diff --git a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb index ffb4e2c5cf..776549eb7a 100644 --- a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb +++ b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb @@ -4,24 +4,24 @@ require "cases/helper" # reserved word names (ie: group, order, values, etc...) class Mysql2ReservedWordTest < ActiveRecord::Mysql2TestCase class Group < ActiveRecord::Base - Group.table_name = 'group' + Group.table_name = "group" belongs_to :select has_one :values end class Select < ActiveRecord::Base - Select.table_name = 'select' + Select.table_name = "select" has_many :groups end class Values < ActiveRecord::Base - Values.table_name = 'values' + Values.table_name = "values" end class Distinct < ActiveRecord::Base - Distinct.table_name = 'distinct' + Distinct.table_name = "distinct" has_and_belongs_to_many :selects - has_many :values, :through => :groups + has_many :values, through: :groups end def setup @@ -30,15 +30,15 @@ class Mysql2ReservedWordTest < ActiveRecord::Mysql2TestCase # we call execute directly here (and do similar below) because ActiveRecord::Base#create_table() # will fail with these table names if these test cases fail - create_tables_directly 'group'=>'id int auto_increment primary key, `order` varchar(255), select_id int', - 'select'=>'id int auto_increment primary key', - 'values'=>'id int auto_increment primary key, group_id int', - 'distinct'=>'id int auto_increment primary key', - 'distinct_select'=>'distinct_id int, select_id int' + create_tables_directly "group"=>"id int auto_increment primary key, `order` varchar(255), select_id int", + "select"=>"id int auto_increment primary key", + "values"=>"id int auto_increment primary key, group_id int", + "distinct"=>"id int auto_increment primary key", + "distinct_select"=>"distinct_id int, select_id int" end teardown do - drop_tables_directly ['group', 'select', 'values', 'distinct', 'distinct_select', 'order'] + drop_tables_directly ["group", "select", "values", "distinct", "distinct_select", "order"] end # create tables with reserved-word names and columns @@ -57,9 +57,9 @@ class Mysql2ReservedWordTest < ActiveRecord::Mysql2TestCase # alter column with a reserved-word name in a table with a reserved-word name def test_change_columns - assert_nothing_raised { @connection.change_column_default(:group, :order, 'whatever') } + assert_nothing_raised { @connection.change_column_default(:group, :order, "whatever") } #the quoting here will reveal any double quoting issues in change_column's interaction with the column method in the adapter - assert_nothing_raised { @connection.change_column('group', 'order', :Int, :default => 0) } + assert_nothing_raised { @connection.change_column("group", "order", :Int, default: 0) } assert_nothing_raised { @connection.rename_column(:group, :order, :values) } end @@ -78,11 +78,11 @@ class Mysql2ReservedWordTest < ActiveRecord::Mysql2TestCase create_test_fixtures :select, :distinct, :group, :values, :distinct_select x = nil assert_nothing_raised { x = Group.new } - x.order = 'x' + x.order = "x" assert_nothing_raised { x.save } - x.order = 'y' + x.order = "y" assert_nothing_raised { x.save } - assert_nothing_raised { Group.find_by_order('y') } + assert_nothing_raised { Group.find_by_order("y") } assert_nothing_raised { Group.find(1) } end @@ -124,29 +124,28 @@ class Mysql2ReservedWordTest < ActiveRecord::Mysql2TestCase end def test_associations_work_with_reserved_words - assert_nothing_raised { Select.all.merge!(:includes => [:groups]).to_a } + assert_nothing_raised { Select.all.merge!(includes: [:groups]).to_a } end #the following functions were added to DRY test cases private - # custom fixture loader, uses FixtureSet#create_fixtures and appends base_path to the current file's path - def create_test_fixtures(*fixture_names) - ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT + "/reserved_words", fixture_names) - end - - # custom drop table, uses execute on connection to drop a table if it exists. note: escapes table_name - def drop_tables_directly(table_names, connection = @connection) - table_names.each do |name| - connection.drop_table name, if_exists: true + # custom fixture loader, uses FixtureSet#create_fixtures and appends base_path to the current file's path + def create_test_fixtures(*fixture_names) + ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT + "/reserved_words", fixture_names) end - end - # custom create table, uses execute on connection to create a table, note: escapes table_name, does NOT escape columns - def create_tables_directly (tables, connection = @connection) - tables.each do |table_name, column_properties| - connection.execute("CREATE TABLE `#{table_name}` ( #{column_properties} )") + # custom drop table, uses execute on connection to drop a table if it exists. note: escapes table_name + def drop_tables_directly(table_names, connection = @connection) + table_names.each do |name| + connection.drop_table name, if_exists: true + end end - end + # custom create table, uses execute on connection to create a table, note: escapes table_name, does NOT escape columns + def create_tables_directly (tables, connection = @connection) + tables.each do |table_name, column_properties| + connection.execute("CREATE TABLE `#{table_name}` ( #{column_properties} )") + end + end end diff --git a/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb b/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb index 7c89fda582..fa54aac6b3 100644 --- a/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb +++ b/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb @@ -18,7 +18,7 @@ class SchemaMigrationsTest < ActiveRecord::Mysql2TestCase connection.initialize_schema_migrations_table - assert connection.column_exists?(table_name, :version, :string, collation: 'utf8_general_ci') + assert connection.column_exists?(table_name, :version, :string, collation: "utf8_general_ci") end end @@ -29,31 +29,31 @@ class SchemaMigrationsTest < ActiveRecord::Mysql2TestCase connection.initialize_internal_metadata_table - assert connection.column_exists?(table_name, :key, :string, collation: 'utf8_general_ci') + assert connection.column_exists?(table_name, :key, :string, collation: "utf8_general_ci") end end private - def with_encoding_utf8mb4 - database_name = connection.current_database - database_info = connection.select_one("SELECT * FROM information_schema.schemata WHERE schema_name = '#{database_name}'") + def with_encoding_utf8mb4 + database_name = connection.current_database + database_info = connection.select_one("SELECT * FROM information_schema.schemata WHERE schema_name = '#{database_name}'") - original_charset = database_info["DEFAULT_CHARACTER_SET_NAME"] - original_collation = database_info["DEFAULT_COLLATION_NAME"] + original_charset = database_info["DEFAULT_CHARACTER_SET_NAME"] + original_collation = database_info["DEFAULT_COLLATION_NAME"] - execute("ALTER DATABASE #{database_name} DEFAULT CHARACTER SET utf8mb4") + execute("ALTER DATABASE #{database_name} DEFAULT CHARACTER SET utf8mb4") - yield - ensure - execute("ALTER DATABASE #{database_name} DEFAULT CHARACTER SET #{original_charset} COLLATE #{original_collation}") - end + yield + ensure + execute("ALTER DATABASE #{database_name} DEFAULT CHARACTER SET #{original_charset} COLLATE #{original_collation}") + end - def connection - @connection ||= ActiveRecord::Base.connection - end + def connection + @connection ||= ActiveRecord::Base.connection + end - def execute(sql) - connection.execute(sql) - end + def execute(sql) + connection.execute(sql) + end end diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb index 43957791b1..aea930cfe6 100644 --- a/activerecord/test/cases/adapters/mysql2/schema_test.rb +++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'models/post' -require 'models/comment' +require "models/post" +require "models/comment" module ActiveRecord module ConnectionAdapters @@ -16,7 +16,7 @@ module ActiveRecord @omgpost = Class.new(ActiveRecord::Base) do self.inheritance_column = :disabled self.table_name = "#{db}.#{table}" - def self.name; 'Post'; end + def self.name; "Post"; end end end @@ -31,13 +31,13 @@ module ActiveRecord t.float :float_25, limit: 25 end - column_no_limit = @connection.columns(:mysql_doubles).find { |c| c.name == 'float_no_limit' } - column_short = @connection.columns(:mysql_doubles).find { |c| c.name == 'float_short' } - column_long = @connection.columns(:mysql_doubles).find { |c| c.name == 'float_long' } + column_no_limit = @connection.columns(:mysql_doubles).find { |c| c.name == "float_no_limit" } + column_short = @connection.columns(:mysql_doubles).find { |c| c.name == "float_short" } + column_long = @connection.columns(:mysql_doubles).find { |c| c.name == "float_long" } - column_23 = @connection.columns(:mysql_doubles).find { |c| c.name == 'float_23' } - column_24 = @connection.columns(:mysql_doubles).find { |c| c.name == 'float_24' } - column_25 = @connection.columns(:mysql_doubles).find { |c| c.name == 'float_25' } + column_23 = @connection.columns(:mysql_doubles).find { |c| c.name == "float_23" } + column_24 = @connection.columns(:mysql_doubles).find { |c| c.name == "float_24" } + column_25 = @connection.columns(:mysql_doubles).find { |c| c.name == "float_25" } # Mysql floats are precision 0..24, Mysql doubles are precision 25..53 assert_equal 24, column_no_limit.limit @@ -56,7 +56,7 @@ module ActiveRecord end def test_primary_key - assert_equal 'id', @omgpost.primary_key + assert_equal "id", @omgpost.primary_key end def test_data_source_exists? @@ -69,18 +69,18 @@ module ActiveRecord end def test_dump_indexes - index_a_name = 'index_key_tests_on_snack' - index_b_name = 'index_key_tests_on_pizza' - index_c_name = 'index_key_tests_on_awesome' + index_a_name = "index_key_tests_on_snack" + index_b_name = "index_key_tests_on_pizza" + index_c_name = "index_key_tests_on_awesome" - table = 'key_tests' + table = "key_tests" indexes = @connection.indexes(table).sort_by(&:name) assert_equal 3,indexes.size - index_a = indexes.select{|i| i.name == index_a_name}[0] - index_b = indexes.select{|i| i.name == index_b_name}[0] - index_c = indexes.select{|i| i.name == index_c_name}[0] + index_a = indexes.select { |i| i.name == index_a_name }[0] + index_b = indexes.select { |i| i.name == index_b_name }[0] + index_c = indexes.select { |i| i.name == index_c_name }[0] assert_equal :btree, index_a.using assert_nil index_a.type assert_equal :btree, index_b.using @@ -103,3 +103,24 @@ module ActiveRecord end end end + +class Mysql2AnsiQuotesTest < ActiveRecord::Mysql2TestCase + def setup + @connection = ActiveRecord::Base.connection + @connection.execute("SET SESSION sql_mode='ANSI_QUOTES'") + end + + def teardown + @connection.reconnect! + end + + def test_primary_key_method_with_ansi_quotes + assert_equal "id", @connection.primary_key("topics") + end + + def test_foreign_keys_method_with_ansi_quotes + fks = @connection.foreign_keys("lessons_students") + assert_equal([["lessons_students", "students", :cascade]], + fks.map { |fk| [fk.from_table, fk.to_table, fk.on_delete] }) + end +end diff --git a/activerecord/test/cases/adapters/mysql2/sp_test.rb b/activerecord/test/cases/adapters/mysql2/sp_test.rb index 4197ba45f1..4182532535 100644 --- a/activerecord/test/cases/adapters/mysql2/sp_test.rb +++ b/activerecord/test/cases/adapters/mysql2/sp_test.rb @@ -1,13 +1,13 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' +require "models/topic" +require "models/reply" class Mysql2StoredProcedureTest < ActiveRecord::Mysql2TestCase fixtures :topics def setup @connection = ActiveRecord::Base.connection - unless ActiveRecord::Base.connection.version >= '5.6.0' + unless ActiveRecord::Base.connection.version >= "5.6.0" skip("no stored procedure support") end end @@ -17,19 +17,19 @@ class Mysql2StoredProcedureTest < ActiveRecord::Mysql2TestCase # In MySQL 5.6, CLIENT_MULTI_RESULTS is enabled by default. # http://dev.mysql.com/doc/refman/5.6/en/call.html def test_multi_results - rows = @connection.select_rows('CALL ten();') + rows = @connection.select_rows("CALL ten();") assert_equal 10, rows[0][0].to_i, "ten() did not return 10 as expected: #{rows.inspect}" assert @connection.active?, "Bad connection use by 'Mysql2Adapter.select_rows'" end def test_multi_results_from_select_one - row = @connection.select_one('CALL topics(1);') - assert_equal 'David', row['author_name'] + row = @connection.select_one("CALL topics(1);") + assert_equal "David", row["author_name"] assert @connection.active?, "Bad connection use by 'Mysql2Adapter.select_one'" end def test_multi_results_from_find_by_sql - topics = Topic.find_by_sql 'CALL topics(3);' + topics = Topic.find_by_sql "CALL topics(3);" assert_equal 3, topics.size assert @connection.active?, "Bad connection use by 'Mysql2Adapter.select'" end diff --git a/activerecord/test/cases/adapters/mysql2/sql_types_test.rb b/activerecord/test/cases/adapters/mysql2/sql_types_test.rb index 4926bc2267..bee42d48f1 100644 --- a/activerecord/test/cases/adapters/mysql2/sql_types_test.rb +++ b/activerecord/test/cases/adapters/mysql2/sql_types_test.rb @@ -2,10 +2,10 @@ require "cases/helper" class Mysql2SqlTypesTest < ActiveRecord::Mysql2TestCase def test_binary_types - assert_equal 'varbinary(64)', type_to_sql(:binary, 64) - assert_equal 'varbinary(4095)', type_to_sql(:binary, 4095) - assert_equal 'blob', type_to_sql(:binary, 4096) - assert_equal 'blob', type_to_sql(:binary) + assert_equal "varbinary(64)", type_to_sql(:binary, 64) + assert_equal "varbinary(4095)", type_to_sql(:binary, 4095) + assert_equal "blob", type_to_sql(:binary, 4096) + assert_equal "blob", type_to_sql(:binary) end def type_to_sql(*args) diff --git a/activerecord/test/cases/adapters/mysql2/table_options_test.rb b/activerecord/test/cases/adapters/mysql2/table_options_test.rb index af121ee7d9..61a8ce9bc0 100644 --- a/activerecord/test/cases/adapters/mysql2/table_options_test.rb +++ b/activerecord/test/cases/adapters/mysql2/table_options_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class Mysql2TableOptionsTest < ActiveRecord::Mysql2TestCase include SchemaDumpingHelper diff --git a/activerecord/test/cases/adapters/mysql2/transaction_test.rb b/activerecord/test/cases/adapters/mysql2/transaction_test.rb new file mode 100644 index 0000000000..edd5353ee3 --- /dev/null +++ b/activerecord/test/cases/adapters/mysql2/transaction_test.rb @@ -0,0 +1,55 @@ +require "cases/helper" +require "support/connection_helper" + +module ActiveRecord + class Mysql2TransactionTest < ActiveRecord::Mysql2TestCase + self.use_transactional_tests = false + + class Sample < ActiveRecord::Base + self.table_name = "samples" + end + + setup do + @connection = ActiveRecord::Base.connection + @connection.clear_cache! + + @connection.transaction do + @connection.drop_table "samples", if_exists: true + @connection.create_table("samples") do |t| + t.integer "value" + end + end + + Sample.reset_column_information + end + + teardown do + @connection.drop_table "samples", if_exists: true + end + + test "raises Deadlocked when a deadlock is encountered" do + assert_raises(ActiveRecord::Deadlocked) do + s1 = Sample.create value: 1 + s2 = Sample.create value: 2 + + thread = Thread.new do + Sample.transaction do + s1.lock! + sleep 1 + s2.update_attributes value: 1 + end + end + + sleep 0.5 + + Sample.transaction do + s2.lock! + sleep 1 + s1.update_attributes value: 2 + end + + thread.join + end + end + end +end diff --git a/activerecord/test/cases/adapters/mysql2/unsigned_type_test.rb b/activerecord/test/cases/adapters/mysql2/unsigned_type_test.rb index 0a9703263e..3df11ce11b 100644 --- a/activerecord/test/cases/adapters/mysql2/unsigned_type_test.rb +++ b/activerecord/test/cases/adapters/mysql2/unsigned_type_test.rb @@ -28,10 +28,10 @@ class Mysql2UnsignedTypeTest < ActiveRecord::Mysql2TestCase end test "minus value is out of range" do - assert_raise(RangeError) do + assert_raise(ActiveModel::RangeError) do UnsignedType.create(unsigned_integer: -10) end - assert_raise(RangeError) do + assert_raise(ActiveModel::RangeError) do UnsignedType.create(unsigned_bigint: -10) end assert_raise(ActiveRecord::StatementInvalid) do diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb index 439e2ce6f7..d3c65f3d94 100644 --- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase def setup @@ -15,12 +15,12 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase def test_create_database_with_encoding assert_equal %(CREATE DATABASE "matt" ENCODING = 'utf8'), create_database(:matt) - assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, :encoding => :latin1) - assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, 'encoding' => :latin1) + assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, encoding: :latin1) + assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, "encoding" => :latin1) end def test_create_database_with_collation_and_ctype - assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'UTF8' LC_COLLATE = 'ja_JP.UTF8' LC_CTYPE = 'ja_JP.UTF8'), create_database(:aimonetti, :encoding => :"UTF8", :collation => :"ja_JP.UTF8", :ctype => :"ja_JP.UTF8") + assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'UTF8' LC_COLLATE = 'ja_JP.UTF8' LC_CTYPE = 'ja_JP.UTF8'), create_database(:aimonetti, encoding: :"UTF8", collation: :"ja_JP.UTF8", ctype: :"ja_JP.UTF8") end def test_add_index @@ -31,10 +31,10 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase assert_equal expected, add_index(:people, :last_name, unique: true, where: "state = 'active'") expected = %(CREATE UNIQUE INDEX "index_people_on_lower_last_name" ON "people" (lower(last_name))) - assert_equal expected, add_index(:people, 'lower(last_name)', unique: true) + assert_equal expected, add_index(:people, "lower(last_name)", unique: true) expected = %(CREATE UNIQUE INDEX "index_people_on_last_name_varchar_pattern_ops" ON "people" (last_name varchar_pattern_ops)) - assert_equal expected, add_index(:people, 'last_name varchar_pattern_ops', unique: true) + assert_equal expected, add_index(:people, "last_name varchar_pattern_ops", unique: true) expected = %(CREATE INDEX CONCURRENTLY "index_people_on_last_name" ON "people" ("last_name")) assert_equal expected, add_index(:people, :last_name, algorithm: :concurrently) @@ -50,7 +50,7 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase assert_equal expected, add_index(:people, :last_name, using: type, unique: true, where: "state = 'active'") expected = %(CREATE UNIQUE INDEX "index_people_on_lower_last_name" ON "people" USING #{type} (lower(last_name))) - assert_equal expected, add_index(:people, 'lower(last_name)', using: type, unique: true) + assert_equal expected, add_index(:people, "lower(last_name)", using: type, unique: true) end assert_raise ArgumentError do @@ -63,7 +63,7 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase def test_remove_index # remove_index calls index_name_for_remove which can't work since execute is stubbed ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_for_remove) do |*| - 'index_people_on_last_name' + "index_people_on_last_name" end expected = %(DROP INDEX CONCURRENTLY "index_people_on_last_name") @@ -81,6 +81,12 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase assert_equal expected, remove_index(:people, name: "index_people_on_last_name", algorithm: :concurrently) end + def test_remove_index_with_wrong_option + assert_raises ArgumentError do + remove_index(:people, coulmn: :last_name) + end + end + private def method_missing(method_symbol, *arguments) ActiveRecord::Base.connection.send(method_symbol, *arguments) diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb index 380a90d765..97960b6c51 100644 --- a/activerecord/test/cases/adapters/postgresql/array_test.rb +++ b/activerecord/test/cases/adapters/postgresql/array_test.rb @@ -1,35 +1,35 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper include InTimeZone class PgArray < ActiveRecord::Base - self.table_name = 'pg_arrays' + self.table_name = "pg_arrays" end def setup @connection = ActiveRecord::Base.connection - enable_extension!('hstore', @connection) + enable_extension!("hstore", @connection) @connection.transaction do - @connection.create_table('pg_arrays') do |t| - t.string 'tags', array: true - t.integer 'ratings', array: true + @connection.create_table("pg_arrays") do |t| + t.string "tags", array: true + t.integer "ratings", array: true t.datetime :datetimes, array: true t.hstore :hstores, array: true end end PgArray.reset_column_information - @column = PgArray.columns_hash['tags'] + @column = PgArray.columns_hash["tags"] @type = PgArray.type_for_attribute("tags") end teardown do - @connection.drop_table 'pg_arrays', if_exists: true - disable_extension!('hstore', @connection) + @connection.drop_table "pg_arrays", if_exists: true + disable_extension!("hstore", @connection) end def test_column @@ -38,26 +38,26 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase assert @column.array? assert_not @type.binary? - ratings_column = PgArray.columns_hash['ratings'] + ratings_column = PgArray.columns_hash["ratings"] assert_equal :integer, ratings_column.type assert ratings_column.array? end def test_default - @connection.add_column 'pg_arrays', 'score', :integer, array: true, default: [4, 4, 2] + @connection.add_column "pg_arrays", "score", :integer, array: true, default: [4, 4, 2] PgArray.reset_column_information - assert_equal([4, 4, 2], PgArray.column_defaults['score']) + assert_equal([4, 4, 2], PgArray.column_defaults["score"]) assert_equal([4, 4, 2], PgArray.new.score) ensure PgArray.reset_column_information end def test_default_strings - @connection.add_column 'pg_arrays', 'names', :string, array: true, default: ["foo", "bar"] + @connection.add_column "pg_arrays", "names", :string, array: true, default: ["foo", "bar"] PgArray.reset_column_information - assert_equal(["foo", "bar"], PgArray.column_defaults['names']) + assert_equal(["foo", "bar"], PgArray.column_defaults["names"]) assert_equal(["foo", "bar"], PgArray.new.names) ensure PgArray.reset_column_information @@ -68,10 +68,10 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase @connection.change_column :pg_arrays, :snippets, :text, array: true, default: [] PgArray.reset_column_information - column = PgArray.columns_hash['snippets'] + column = PgArray.columns_hash["snippets"] assert_equal :text, column.type - assert_equal [], PgArray.column_defaults['snippets'] + assert_equal [], PgArray.column_defaults["snippets"] assert column.array? end @@ -88,17 +88,17 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase @connection.change_column_default :pg_arrays, :tags, [] PgArray.reset_column_information - assert_equal [], PgArray.column_defaults['tags'] + assert_equal [], PgArray.column_defaults["tags"] end def test_type_cast_array - assert_equal(['1', '2', '3'], @type.deserialize('{1,2,3}')) - assert_equal([], @type.deserialize('{}')) - assert_equal([nil], @type.deserialize('{NULL}')) + assert_equal(["1", "2", "3"], @type.deserialize("{1,2,3}")) + assert_equal([], @type.deserialize("{}")) + assert_equal([nil], @type.deserialize("{NULL}")) end def test_type_cast_integers - x = PgArray.new(ratings: ['1', '2']) + x = PgArray.new(ratings: ["1", "2"]) assert_equal([1, 2], x.ratings) @@ -117,15 +117,15 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase def test_select_with_strings @connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')" x = PgArray.first - assert_equal(['1','2','3'], x.tags) + assert_equal(["1","2","3"], x.tags) end def test_rewrite_with_strings @connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')" x = PgArray.first - x.tags = ['1','2','3','4'] + x.tags = ["1","2","3","4"] x.save! - assert_equal ['1','2','3','4'], x.reload.tags + assert_equal ["1","2","3","4"], x.reload.tags end def test_select_with_integers @@ -137,25 +137,25 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase def test_rewrite_with_integers @connection.execute "insert into pg_arrays (ratings) VALUES ('{1,2,3}')" x = PgArray.first - x.ratings = [2, '3', 4] + x.ratings = [2, "3", 4] x.save! assert_equal [2, 3, 4], x.reload.ratings end def test_multi_dimensional_with_strings - assert_cycle(:tags, [[['1'], ['2']], [['2'], ['3']]]) + assert_cycle(:tags, [[["1"], ["2"]], [["2"], ["3"]]]) end def test_with_empty_strings - assert_cycle(:tags, [ '1', '2', '', '4', '', '5' ]) + assert_cycle(:tags, [ "1", "2", "", "4", "", "5" ]) end def test_with_multi_dimensional_empty_strings - assert_cycle(:tags, [[['1', '2'], ['', '4'], ['', '5']]]) + assert_cycle(:tags, [[["1", "2"], ["", "4"], ["", "5"]]]) end def test_with_arbitrary_whitespace - assert_cycle(:tags, [[['1', '2'], [' ', '4'], [' ', '5']]]) + assert_cycle(:tags, [[["1", "2"], [" ", "4"], [" ", "5"]]]) end def test_multi_dimensional_with_integers @@ -163,34 +163,39 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase end def test_strings_with_quotes - assert_cycle(:tags, ['this has','some "s that need to be escaped"']) + assert_cycle(:tags, ["this has",'some "s that need to be escaped"']) end def test_strings_with_commas - assert_cycle(:tags, ['this,has','many,values']) + assert_cycle(:tags, ["this,has","many,values"]) end def test_strings_with_array_delimiters - assert_cycle(:tags, ['{','}']) + assert_cycle(:tags, ["{","}"]) end def test_strings_with_null_strings - assert_cycle(:tags, ['NULL','NULL']) + assert_cycle(:tags, ["NULL","NULL"]) end def test_contains_nils - assert_cycle(:tags, ['1',nil,nil]) + assert_cycle(:tags, ["1",nil,nil]) end def test_insert_fixture tag_values = ["val1", "val2", "val3_with_'_multiple_quote_'_chars"] - @connection.insert_fixture({"tags" => tag_values}, "pg_arrays" ) + @connection.insert_fixture({ "tags" => tag_values }, "pg_arrays" ) assert_equal(PgArray.last.tags, tag_values) end def test_attribute_for_inspect_for_array_field + record = PgArray.new { |a| a.ratings = (1..10).to_a } + assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", record.attribute_for_inspect(:ratings)) + end + + def test_attribute_for_inspect_for_array_field_for_large_array record = PgArray.new { |a| a.ratings = (1..11).to_a } - assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]", record.attribute_for_inspect(:ratings)) + assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]", record.attribute_for_inspect(:ratings)) end def test_escaping @@ -206,14 +211,14 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase x = PgArray.create!(tags: tags) x.reload - assert_equal x.tags_before_type_cast, PgArray.type_for_attribute('tags').serialize(tags) + assert_equal x.tags_before_type_cast, PgArray.type_for_attribute("tags").serialize(tags) end def test_quoting_non_standard_delimiters strings = ["hello,", "world;"] oid = ActiveRecord::ConnectionAdapters::PostgreSQL::OID - comma_delim = oid::Array.new(ActiveRecord::Type::String.new, ',') - semicolon_delim = oid::Array.new(ActiveRecord::Type::String.new, ';') + comma_delim = oid::Array.new(ActiveRecord::Type::String.new, ",") + semicolon_delim = oid::Array.new(ActiveRecord::Type::String.new, ";") assert_equal %({"hello,",world;}), comma_delim.serialize(strings) assert_equal %({hello,;"world;"}), semicolon_delim.serialize(strings) @@ -231,13 +236,13 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase end def test_mutate_value_in_array - x = PgArray.create!(hstores: [{ a: 'a' }, { b: 'b' }]) + x = PgArray.create!(hstores: [{ a: "a" }, { b: "b" }]) - x.hstores.first['a'] = 'c' + x.hstores.first["a"] = "c" x.save! x.reload - assert_equal [{ 'a' => 'c' }, { 'b' => 'b' }], x.hstores + assert_equal [{ "a" => "c" }, { "b" => "b" }], x.hstores assert_not x.changed? end @@ -285,6 +290,12 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase assert_equal record.tags, record.reload.tags end + def test_where_by_attribute_with_array + tags = ["black", "blue"] + record = PgArray.create!(tags: tags) + assert_equal record, PgArray.where(tags: tags).take + end + def test_uniqueness_validation klass = Class.new(PgArray) do validates_uniqueness_of :tags @@ -300,18 +311,24 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase assert_equal ["has already been taken"], e2.errors[:tags], "Should have uniqueness message for tags" end - private - def assert_cycle field, array - # test creation - x = PgArray.create!(field => array) - x.reload - assert_equal(array, x.public_send(field)) - - # test updating - x = PgArray.create!(field => []) - x.public_send("#{field}=", array) - x.save! - x.reload - assert_equal(array, x.public_send(field)) + def test_encoding_arrays_of_utf8_strings + string_with_utf8 = "nový" + assert_equal [string_with_utf8], @type.deserialize(@type.serialize([string_with_utf8])) + assert_equal [[string_with_utf8]], @type.deserialize(@type.serialize([[string_with_utf8]])) end + + private + def assert_cycle(field, array) + # test creation + x = PgArray.create!(field => array) + x.reload + assert_equal(array, x.public_send(field)) + + # test updating + x = PgArray.create!(field => []) + x.public_send("#{field}=", array) + x.save! + x.reload + assert_equal(array, x.public_send(field)) + end end diff --git a/activerecord/test/cases/adapters/postgresql/bit_string_test.rb b/activerecord/test/cases/adapters/postgresql/bit_string_test.rb index cec6081aec..7712e809a2 100644 --- a/activerecord/test/cases/adapters/postgresql/bit_string_test.rb +++ b/activerecord/test/cases/adapters/postgresql/bit_string_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'support/connection_helper' -require 'support/schema_dumping_helper' +require "support/connection_helper" +require "support/schema_dumping_helper" class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase include ConnectionHelper @@ -10,7 +10,7 @@ class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase def setup @connection = ActiveRecord::Base.connection - @connection.create_table('postgresql_bit_strings', :force => true) do |t| + @connection.create_table("postgresql_bit_strings", force: true) do |t| t.bit :a_bit, default: "00000011", limit: 8 t.bit_varying :a_bit_varying, default: "0011", limit: 4 t.bit :another_bit @@ -20,7 +20,7 @@ class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase def teardown return unless @connection - @connection.drop_table 'postgresql_bit_strings', if_exists: true + @connection.drop_table "postgresql_bit_strings", if_exists: true end def test_bit_string_column @@ -44,10 +44,10 @@ class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase end def test_default - assert_equal "00000011", PostgresqlBitString.column_defaults['a_bit'] + assert_equal "00000011", PostgresqlBitString.column_defaults["a_bit"] assert_equal "00000011", PostgresqlBitString.new.a_bit - assert_equal "0011", PostgresqlBitString.column_defaults['a_bit_varying'] + assert_equal "0011", PostgresqlBitString.column_defaults["a_bit_varying"] assert_equal "0011", PostgresqlBitString.new.a_bit_varying end @@ -65,10 +65,11 @@ class PostgresqlBitStringTest < ActiveRecord::PostgreSQLTestCase end def test_roundtrip - PostgresqlBitString.create! a_bit: "00001010", a_bit_varying: "0101" - record = PostgresqlBitString.first + record = PostgresqlBitString.create!(a_bit: "00001010", a_bit_varying: "0101") assert_equal "00001010", record.a_bit assert_equal "0101", record.a_bit_varying + assert_nil record.another_bit + assert_nil record.another_bit_varying record.a_bit = "11111111" record.a_bit_varying = "0xF" diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb index 7adc070430..dc0df8715a 100644 --- a/activerecord/test/cases/adapters/postgresql/bytea_test.rb +++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb @@ -1,29 +1,29 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper class ByteaDataType < ActiveRecord::Base - self.table_name = 'bytea_data_type' + self.table_name = "bytea_data_type" end def setup @connection = ActiveRecord::Base.connection begin @connection.transaction do - @connection.create_table('bytea_data_type') do |t| - t.binary 'payload' - t.binary 'serialized' + @connection.create_table("bytea_data_type") do |t| + t.binary "payload" + t.binary "serialized" end end end - @column = ByteaDataType.columns_hash['payload'] + @column = ByteaDataType.columns_hash["payload"] @type = ByteaDataType.type_for_attribute("payload") end teardown do - @connection.drop_table 'bytea_data_type', if_exists: true + @connection.drop_table "bytea_data_type", if_exists: true end def test_column @@ -32,7 +32,7 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase end def test_binary_columns_are_limitless_the_upper_limit_is_one_GB - assert_equal 'bytea', @connection.type_to_sql(:binary, 100_000) + assert_equal "bytea", @connection.type_to_sql(:binary, 100_000) assert_raise ActiveRecord::ActiveRecordError do @connection.type_to_sql :binary, 4294967295 end @@ -42,8 +42,8 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase assert @column data = "\u001F\x8B" - assert_equal('UTF-8', data.encoding.name) - assert_equal('ASCII-8BIT', @type.deserialize(data).encoding.name) + assert_equal("UTF-8", data.encoding.name) + assert_equal("ASCII-8BIT", @type.deserialize(data).encoding.name) end def test_type_cast_binary_value @@ -88,14 +88,14 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase def test_via_to_sql_with_complicating_connection Thread.new do other_conn = ActiveRecord::Base.connection - other_conn.execute('SET standard_conforming_strings = off') + other_conn.execute("SET standard_conforming_strings = off") end.join test_via_to_sql end def test_write_binary - data = File.read(File.join(File.dirname(__FILE__), '..', '..', '..', 'assets', 'example.log')) + data = File.read(File.join(File.dirname(__FILE__), "..", "..", "..", "assets", "example.log")) assert(data.size > 1) record = ByteaDataType.create(payload: data) assert_not record.new_record? diff --git a/activerecord/test/cases/adapters/postgresql/change_schema_test.rb b/activerecord/test/cases/adapters/postgresql/change_schema_test.rb index bc12df668d..ea642069d2 100644 --- a/activerecord/test/cases/adapters/postgresql/change_schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/change_schema_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class Migration @@ -19,17 +19,17 @@ module ActiveRecord def test_change_string_to_date connection.change_column :strings, :somedate, :timestamp, using: 'CAST("somedate" AS timestamp)' - assert_equal :datetime, connection.columns(:strings).find { |c| c.name == 'somedate' }.type + assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type end def test_change_type_with_symbol connection.change_column :strings, :somedate, :timestamp, cast_as: :timestamp - assert_equal :datetime, connection.columns(:strings).find { |c| c.name == 'somedate' }.type + assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type end def test_change_type_with_array connection.change_column :strings, :somedate, :timestamp, array: true, cast_as: :timestamp - column = connection.columns(:strings).find { |c| c.name == 'somedate' } + column = connection.columns(:strings).find { |c| c.name == "somedate" } assert_equal :datetime, column.type assert column.array? end diff --git a/activerecord/test/cases/adapters/postgresql/citext_test.rb b/activerecord/test/cases/adapters/postgresql/citext_test.rb index bd62041e79..ca95e4b626 100644 --- a/activerecord/test/cases/adapters/postgresql/citext_test.rb +++ b/activerecord/test/cases/adapters/postgresql/citext_test.rb @@ -1,49 +1,49 @@ -require 'cases/helper' -require 'support/schema_dumping_helper' +require "cases/helper" +require "support/schema_dumping_helper" if ActiveRecord::Base.connection.supports_extensions? class PostgresqlCitextTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper class Citext < ActiveRecord::Base - self.table_name = 'citexts' + self.table_name = "citexts" end def setup @connection = ActiveRecord::Base.connection - enable_extension!('citext', @connection) + enable_extension!("citext", @connection) - @connection.create_table('citexts') do |t| - t.citext 'cival' + @connection.create_table("citexts") do |t| + t.citext "cival" end end teardown do - @connection.drop_table 'citexts', if_exists: true - disable_extension!('citext', @connection) + @connection.drop_table "citexts", if_exists: true + disable_extension!("citext", @connection) end def test_citext_enabled - assert @connection.extension_enabled?('citext') + assert @connection.extension_enabled?("citext") end def test_column - column = Citext.columns_hash['cival'] + column = Citext.columns_hash["cival"] assert_equal :citext, column.type - assert_equal 'citext', column.sql_type + assert_equal "citext", column.sql_type assert_not column.array? - type = Citext.type_for_attribute('cival') + type = Citext.type_for_attribute("cival") assert_not type.binary? end def test_change_table_supports_json @connection.transaction do - @connection.change_table('citexts') do |t| - t.citext 'username' + @connection.change_table("citexts") do |t| + t.citext "username" end Citext.reset_column_information - column = Citext.columns_hash['username'] + column = Citext.columns_hash["username"] assert_equal :citext, column.type raise ActiveRecord::Rollback # reset the schema change @@ -53,7 +53,7 @@ if ActiveRecord::Base.connection.supports_extensions? end def test_write - x = Citext.new(cival: 'Some CI Text') + x = Citext.new(cival: "Some CI Text") x.save! citext = Citext.first assert_equal "Some CI Text", citext.cival @@ -66,8 +66,8 @@ if ActiveRecord::Base.connection.supports_extensions? def test_select_case_insensitive @connection.execute "insert into citexts (cival) values('Cased Text')" - x = Citext.where(cival: 'cased text').first - assert_equal 'Cased Text', x.cival + x = Citext.where(cival: "cased text").first + assert_equal "Cased Text", x.cival end def test_schema_dump_with_shorthand diff --git a/activerecord/test/cases/adapters/postgresql/collation_test.rb b/activerecord/test/cases/adapters/postgresql/collation_test.rb index 8470329c35..b39e298a5d 100644 --- a/activerecord/test/cases/adapters/postgresql/collation_test.rb +++ b/activerecord/test/cases/adapters/postgresql/collation_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class PostgresqlCollationTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper @@ -7,8 +7,8 @@ class PostgresqlCollationTest < ActiveRecord::PostgreSQLTestCase def setup @connection = ActiveRecord::Base.connection @connection.create_table :postgresql_collations, force: true do |t| - t.string :string_c, collation: 'C' - t.text :text_posix, collation: 'POSIX' + t.string :string_c, collation: "C" + t.text :text_posix, collation: "POSIX" end end @@ -17,32 +17,32 @@ class PostgresqlCollationTest < ActiveRecord::PostgreSQLTestCase end test "string column with collation" do - column = @connection.columns(:postgresql_collations).find { |c| c.name == 'string_c' } + column = @connection.columns(:postgresql_collations).find { |c| c.name == "string_c" } assert_equal :string, column.type - assert_equal 'C', column.collation + assert_equal "C", column.collation end test "text column with collation" do - column = @connection.columns(:postgresql_collations).find { |c| c.name == 'text_posix' } + column = @connection.columns(:postgresql_collations).find { |c| c.name == "text_posix" } assert_equal :text, column.type - assert_equal 'POSIX', column.collation + assert_equal "POSIX", column.collation end test "add column with collation" do - @connection.add_column :postgresql_collations, :title, :string, collation: 'C' + @connection.add_column :postgresql_collations, :title, :string, collation: "C" - column = @connection.columns(:postgresql_collations).find { |c| c.name == 'title' } + column = @connection.columns(:postgresql_collations).find { |c| c.name == "title" } assert_equal :string, column.type - assert_equal 'C', column.collation + assert_equal "C", column.collation end test "change column with collation" do @connection.add_column :postgresql_collations, :description, :string - @connection.change_column :postgresql_collations, :description, :text, collation: 'POSIX' + @connection.change_column :postgresql_collations, :description, :text, collation: "POSIX" - column = @connection.columns(:postgresql_collations).find { |c| c.name == 'description' } + column = @connection.columns(:postgresql_collations).find { |c| c.name == "description" } assert_equal :text, column.type - assert_equal 'POSIX', column.collation + assert_equal "POSIX", column.collation end test "schema dump includes collation" do diff --git a/activerecord/test/cases/adapters/postgresql/composite_test.rb b/activerecord/test/cases/adapters/postgresql/composite_test.rb index 1de87e5f01..1da2a9e2ac 100644 --- a/activerecord/test/cases/adapters/postgresql/composite_test.rb +++ b/activerecord/test/cases/adapters/postgresql/composite_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/connection_helper' +require "support/connection_helper" module PostgresqlCompositeBehavior include ConnectionHelper @@ -20,7 +20,7 @@ module PostgresqlCompositeBehavior street VARCHAR(90) ); SQL - @connection.create_table('postgresql_composites') do |t| + @connection.create_table("postgresql_composites") do |t| t.column :address, :full_address end end @@ -29,8 +29,8 @@ module PostgresqlCompositeBehavior def teardown super - @connection.drop_table 'postgresql_composites', if_exists: true - @connection.execute 'DROP TYPE IF EXISTS full_address' + @connection.drop_table "postgresql_composites", if_exists: true + @connection.execute "DROP TYPE IF EXISTS full_address" reset_connection PostgresqlComposite.reset_column_information end @@ -69,12 +69,12 @@ class PostgresqlCompositeTest < ActiveRecord::PostgreSQLTestCase end private - def ensure_warning_is_issued - warning = capture(:stderr) do - PostgresqlComposite.columns_hash + def ensure_warning_is_issued + warning = capture(:stderr) do + PostgresqlComposite.columns_hash + end + assert_match(/unknown OID \d+: failed to recognize type of 'address'\. It will be treated as String\./, warning) end - assert_match(/unknown OID \d+: failed to recognize type of 'address'\. It will be treated as String\./, warning) - end end class PostgresqlCompositeWithCustomOIDTest < ActiveRecord::PostgreSQLTestCase @@ -126,7 +126,7 @@ class PostgresqlCompositeWithCustomOIDTest < ActiveRecord::PostgreSQLTestCase composite.address = FullAddress.new("Paris", "Rue Basse") composite.save! - assert_equal 'Paris', composite.reload.address.city - assert_equal 'Rue Basse', composite.reload.address.street + assert_equal "Paris", composite.reload.address.city + assert_equal "Rue Basse", composite.reload.address.street end end diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb index f8403bfe1a..48c82cb7b9 100644 --- a/activerecord/test/cases/adapters/postgresql/connection_test.rb +++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/connection_helper' +require "support/connection_helper" module ActiveRecord class PostgresqlConnectionTest < ActiveRecord::PostgreSQLTestCase @@ -13,7 +13,7 @@ module ActiveRecord def setup super @subscriber = SQLSubscriber.new - @subscription = ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber) + @subscription = ActiveSupport::Notifications.subscribe("sql.active_record", @subscriber) @connection = ActiveRecord::Base.connection end @@ -23,10 +23,10 @@ module ActiveRecord end def test_truncate - count = ActiveRecord::Base.connection.execute("select count(*) from comments").first['count'].to_i + count = ActiveRecord::Base.connection.execute("select count(*) from comments").first["count"].to_i assert_operator count, :>, 0 ActiveRecord::Base.connection.truncate("comments") - count = ActiveRecord::Base.connection.execute("select count(*) from comments").first['count'].to_i + count = ActiveRecord::Base.connection.execute("select count(*) from comments").first["count"].to_i assert_equal 0, count end @@ -54,85 +54,85 @@ module ActiveRecord NonExistentTable.establish_connection(params) # Verify the connection param has been applied. - expect = NonExistentTable.connection.query('show geqo').first.first - assert_equal 'off', expect + expect = NonExistentTable.connection.query("show geqo").first.first + assert_equal "off", expect end def test_reset - @connection.query('ROLLBACK') - @connection.query('SET geqo TO off') + @connection.query("ROLLBACK") + @connection.query("SET geqo TO off") # Verify the setting has been applied. - expect = @connection.query('show geqo').first.first - assert_equal 'off', expect + expect = @connection.query("show geqo").first.first + assert_equal "off", expect @connection.reset! # Verify the setting has been cleared. - expect = @connection.query('show geqo').first.first - assert_equal 'on', expect + expect = @connection.query("show geqo").first.first + assert_equal "on", expect end def test_reset_with_transaction - @connection.query('ROLLBACK') - @connection.query('SET geqo TO off') + @connection.query("ROLLBACK") + @connection.query("SET geqo TO off") # Verify the setting has been applied. - expect = @connection.query('show geqo').first.first - assert_equal 'off', expect + expect = @connection.query("show geqo").first.first + assert_equal "off", expect - @connection.query('BEGIN') + @connection.query("BEGIN") @connection.reset! # Verify the setting has been cleared. - expect = @connection.query('show geqo').first.first - assert_equal 'on', expect + expect = @connection.query("show geqo").first.first + assert_equal "on", expect end def test_tables_logs_name - ActiveSupport::Deprecation.silence { @connection.tables('hello') } - assert_equal 'SCHEMA', @subscriber.logged[0][1] + ActiveSupport::Deprecation.silence { @connection.tables("hello") } + assert_equal "SCHEMA", @subscriber.logged[0][1] end def test_indexes_logs_name - @connection.indexes('items', 'hello') - assert_equal 'SCHEMA', @subscriber.logged[0][1] + @connection.indexes("items", "hello") + assert_equal "SCHEMA", @subscriber.logged[0][1] end def test_table_exists_logs_name - ActiveSupport::Deprecation.silence { @connection.table_exists?('items') } - assert_equal 'SCHEMA', @subscriber.logged[0][1] + ActiveSupport::Deprecation.silence { @connection.table_exists?("items") } + assert_equal "SCHEMA", @subscriber.logged[0][1] end def test_table_alias_length_logs_name @connection.instance_variable_set("@table_alias_length", nil) @connection.table_alias_length - assert_equal 'SCHEMA', @subscriber.logged[0][1] + assert_equal "SCHEMA", @subscriber.logged[0][1] end def test_current_database_logs_name @connection.current_database - assert_equal 'SCHEMA', @subscriber.logged[0][1] + assert_equal "SCHEMA", @subscriber.logged[0][1] end def test_encoding_logs_name @connection.encoding - assert_equal 'SCHEMA', @subscriber.logged[0][1] + assert_equal "SCHEMA", @subscriber.logged[0][1] end def test_schema_names_logs_name @connection.schema_names - assert_equal 'SCHEMA', @subscriber.logged[0][1] + assert_equal "SCHEMA", @subscriber.logged[0][1] end if ActiveRecord::Base.connection.prepared_statements def test_statement_key_is_logged bind = Relation::QueryAttribute.new(nil, 1, Type::Value.new) - @connection.exec_query('SELECT $1::integer', 'SQL', [bind], prepare: true) + @connection.exec_query("SELECT $1::integer", "SQL", [bind], prepare: true) name = @subscriber.payloads.last[:statement_name] assert name res = @connection.exec_query("EXPLAIN (FORMAT JSON) EXECUTE #{name}(1)") - plan = res.column_types['QUERY PLAN'].deserialize res.rows.first.first + plan = res.column_types["QUERY PLAN"].deserialize res.rows.first.first assert_operator plan.length, :>, 0 end end @@ -146,7 +146,7 @@ module ActiveRecord # To restart PostgreSQL 9.1 on OS X, installed via MacPorts, ... # sudo su postgres -c "pg_ctl restart -D /opt/local/var/db/postgresql91/defaultdb/ -m fast" def test_reconnection_after_actual_disconnection_with_verify - original_connection_pid = @connection.query('select pg_backend_pid()') + original_connection_pid = @connection.query("select pg_backend_pid()") # Sanity check. assert @connection.active? @@ -155,8 +155,8 @@ module ActiveRecord secondary_connection = ActiveRecord::Base.connection_pool.checkout secondary_connection.query("select pg_terminate_backend(#{original_connection_pid.first.first})") ActiveRecord::Base.connection_pool.checkin(secondary_connection) - elsif ARTest.config['with_manual_interventions'] - puts 'Kill the connection now (e.g. by restarting the PostgreSQL ' + + elsif ARTest.config["with_manual_interventions"] + puts "Kill the connection now (e.g. by restarting the PostgreSQL " + 'server with the "-m fast" option) and then press enter.' $stdin.gets else @@ -172,7 +172,7 @@ module ActiveRecord # If we get no exception here, then either we re-connected successfully, or # we never actually got disconnected. - new_connection_pid = @connection.query('select pg_backend_pid()') + new_connection_pid = @connection.query("select pg_backend_pid()") assert_not_equal original_connection_pid, new_connection_pid, "umm -- looks like you didn't break the connection, because we're still " + @@ -184,7 +184,7 @@ module ActiveRecord def test_set_session_variable_true run_without_connection do |orig_connection| - ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => true}})) + ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { debug_print_plan: true })) set_true = ActiveRecord::Base.connection.exec_query "SHOW DEBUG_PRINT_PLAN" assert_equal set_true.rows, [["on"]] end @@ -192,7 +192,7 @@ module ActiveRecord def test_set_session_variable_false run_without_connection do |orig_connection| - ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => false}})) + ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { debug_print_plan: false })) set_false = ActiveRecord::Base.connection.exec_query "SHOW DEBUG_PRINT_PLAN" assert_equal set_false.rows, [["off"]] end @@ -201,14 +201,14 @@ module ActiveRecord def test_set_session_variable_nil run_without_connection do |orig_connection| # This should be a no-op that does not raise an error - ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => nil}})) + ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { debug_print_plan: nil })) end end def test_set_session_variable_default run_without_connection do |orig_connection| # This should execute a query that does not raise an error - ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:debug_print_plan => :default}})) + ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { debug_print_plan: :default })) end end @@ -224,14 +224,14 @@ module ActiveRecord got_lock = @connection.get_advisory_lock(lock_id) assert got_lock, "get_advisory_lock should have returned true but it didn't" - advisory_lock = @connection.query(list_advisory_locks).find {|l| l[1] == lock_id} + advisory_lock = @connection.query(list_advisory_locks).find { |l| l[1] == lock_id } assert advisory_lock, "expected to find an advisory lock with lock_id #{lock_id} but there wasn't one" released_lock = @connection.release_advisory_lock(lock_id) assert released_lock, "expected release_advisory_lock to return true but it didn't" - advisory_locks = @connection.query(list_advisory_locks).select {|l| l[1] == lock_id} + advisory_locks = @connection.query(list_advisory_locks).select { |l| l[1] == lock_id } assert_empty advisory_locks, "expected to have released advisory lock with lock_id #{lock_id} but it was still held" end @@ -241,17 +241,17 @@ module ActiveRecord with_warning_suppression do released_non_existent_lock = @connection.release_advisory_lock(fake_lock_id) assert_equal released_non_existent_lock, false, - 'expected release_advisory_lock to return false when there was no lock to release' + "expected release_advisory_lock to return false when there was no lock to release" end end protected - def with_warning_suppression - log_level = @connection.client_min_messages - @connection.client_min_messages = 'error' - yield - @connection.client_min_messages = log_level - end + def with_warning_suppression + log_level = @connection.client_min_messages + @connection.client_min_messages = "error" + yield + @connection.client_min_messages = log_level + end end end diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb index 232c25cb3b..0ac8b7339b 100644 --- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb +++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb @@ -1,6 +1,5 @@ require "cases/helper" -require 'support/ddl_helper' - +require "support/ddl_helper" class PostgresqlTime < ActiveRecord::Base end @@ -38,8 +37,8 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase end def test_time_values - assert_equal '-1 years -2 days', @first_time.time_interval - assert_equal '-21 days', @first_time.scaled_time_interval + assert_equal "-1 years -2 days", @first_time.time_interval + assert_equal "-21 days", @first_time.scaled_time_interval end def test_oid_values @@ -47,10 +46,10 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase end def test_update_time - @first_time.time_interval = '2 years 3 minutes' + @first_time.time_interval = "2 years 3 minutes" assert @first_time.save assert @first_time.reload - assert_equal '2 years 00:03:00', @first_time.time_interval + assert_equal "2 years 00:03:00", @first_time.time_interval end def test_update_oid @@ -62,7 +61,7 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase end def test_text_columns_are_limitless_the_upper_limit_is_one_GB - assert_equal 'text', @connection.type_to_sql(:text, 100_000) + assert_equal "text", @connection.type_to_sql(:text, 100_000) assert_raise ActiveRecord::ActiveRecordError do @connection.type_to_sql :text, 4294967295 end @@ -77,15 +76,15 @@ class PostgresqlInternalDataTypeTest < ActiveRecord::PostgreSQLTestCase end def test_name_column_type - with_example_table @connection, 'ex', 'data name' do - column = @connection.columns('ex').find { |col| col.name == 'data' } + with_example_table @connection, "ex", "data name" do + column = @connection.columns("ex").find { |col| col.name == "data" } assert_equal :string, column.type end end def test_char_column_type - with_example_table @connection, 'ex', 'data "char"' do - column = @connection.columns('ex').find { |col| col.name == 'data' } + with_example_table @connection, "ex", 'data "char"' do + column = @connection.columns("ex").find { |col| col.name == "data" } assert_equal :string, column.type end end diff --git a/activerecord/test/cases/adapters/postgresql/domain_test.rb b/activerecord/test/cases/adapters/postgresql/domain_test.rb index 6102ddacd1..f1eb8adb15 100644 --- a/activerecord/test/cases/adapters/postgresql/domain_test.rb +++ b/activerecord/test/cases/adapters/postgresql/domain_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/connection_helper' +require "support/connection_helper" class PostgresqlDomainTest < ActiveRecord::PostgreSQLTestCase include ConnectionHelper @@ -12,15 +12,15 @@ class PostgresqlDomainTest < ActiveRecord::PostgreSQLTestCase @connection = ActiveRecord::Base.connection @connection.transaction do @connection.execute "CREATE DOMAIN custom_money as numeric(8,2)" - @connection.create_table('postgresql_domains') do |t| + @connection.create_table("postgresql_domains") do |t| t.column :price, :custom_money end end end teardown do - @connection.drop_table 'postgresql_domains', if_exists: true - @connection.execute 'DROP DOMAIN IF EXISTS custom_money' + @connection.drop_table "postgresql_domains", if_exists: true + @connection.execute "DROP DOMAIN IF EXISTS custom_money" reset_connection end diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb index 6816a6514b..5e5a3158ba 100644 --- a/activerecord/test/cases/adapters/postgresql/enum_test.rb +++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/connection_helper' +require "support/connection_helper" class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase include ConnectionHelper @@ -14,15 +14,15 @@ class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase @connection.execute <<-SQL CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); SQL - @connection.create_table('postgresql_enums') do |t| + @connection.create_table("postgresql_enums") do |t| t.column :current_mood, :mood end end end teardown do - @connection.drop_table 'postgresql_enums', if_exists: true - @connection.execute 'DROP TYPE IF EXISTS mood' + @connection.drop_table "postgresql_enums", if_exists: true + @connection.execute "DROP TYPE IF EXISTS mood" reset_connection end @@ -37,10 +37,10 @@ class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase end def test_enum_defaults - @connection.add_column 'postgresql_enums', 'good_mood', :mood, default: 'happy' + @connection.add_column "postgresql_enums", "good_mood", :mood, default: "happy" PostgresqlEnum.reset_column_information - assert_equal "happy", PostgresqlEnum.column_defaults['good_mood'] + assert_equal "happy", PostgresqlEnum.column_defaults["good_mood"] assert_equal "happy", PostgresqlEnum.new.good_mood ensure PostgresqlEnum.reset_column_information diff --git a/activerecord/test/cases/adapters/postgresql/explain_test.rb b/activerecord/test/cases/adapters/postgresql/explain_test.rb index 29bf2c15ea..7493bce4fb 100644 --- a/activerecord/test/cases/adapters/postgresql/explain_test.rb +++ b/activerecord/test/cases/adapters/postgresql/explain_test.rb @@ -1,20 +1,20 @@ require "cases/helper" -require 'models/developer' -require 'models/computer' +require "models/developer" +require "models/computer" class PostgreSQLExplainTest < ActiveRecord::PostgreSQLTestCase fixtures :developers def test_explain_for_one_query explain = Developer.where(id: 1).explain - assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = \$?1), explain + assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\$1 \[\["id", 1\]\]|1)), explain assert_match %(QUERY PLAN), explain end def test_explain_with_eager_loading explain = Developer.where(id: 1).includes(:audit_logs).explain assert_match %(QUERY PLAN), explain - assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = \$?1), explain + assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\$1 \[\["id", 1\]\]|1)), explain assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" = 1), explain end end diff --git a/activerecord/test/cases/adapters/postgresql/full_text_test.rb b/activerecord/test/cases/adapters/postgresql/full_text_test.rb index bde7513339..5ddfe32007 100644 --- a/activerecord/test/cases/adapters/postgresql/full_text_test.rb +++ b/activerecord/test/cases/adapters/postgresql/full_text_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class PostgresqlFullTextTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper @@ -7,13 +7,13 @@ class PostgresqlFullTextTest < ActiveRecord::PostgreSQLTestCase setup do @connection = ActiveRecord::Base.connection - @connection.create_table('tsvectors') do |t| - t.tsvector 'text_vector' + @connection.create_table("tsvectors") do |t| + t.tsvector "text_vector" end end teardown do - @connection.drop_table 'tsvectors', if_exists: true + @connection.drop_table "tsvectors", if_exists: true end def test_tsvector_column diff --git a/activerecord/test/cases/adapters/postgresql/geometric_test.rb b/activerecord/test/cases/adapters/postgresql/geometric_test.rb index 9e250c2b7c..a65d4d1ad9 100644 --- a/activerecord/test/cases/adapters/postgresql/geometric_test.rb +++ b/activerecord/test/cases/adapters/postgresql/geometric_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'support/connection_helper' -require 'support/schema_dumping_helper' +require "support/connection_helper" +require "support/schema_dumping_helper" class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase include ConnectionHelper @@ -18,7 +18,7 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase def setup @connection = ActiveRecord::Base.connection - @connection.create_table('postgresql_points') do |t| + @connection.create_table("postgresql_points") do |t| t.point :x t.point :y, default: [12.2, 13.3] t.point :z, default: "(14.4,15.5)" @@ -27,22 +27,10 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase t.point :legacy_y, default: [12.2, 13.3] t.point :legacy_z, default: "(14.4,15.5)" end - @connection.create_table('deprecated_points') do |t| - t.point :x - end end teardown do - @connection.drop_table 'postgresql_points', if_exists: true - @connection.drop_table 'deprecated_points', if_exists: true - end - - class DeprecatedPoint < ActiveRecord::Base; end - - def test_deprecated_legacy_type - assert_deprecated do - DeprecatedPoint.new - end + @connection.drop_table "postgresql_points", if_exists: true end def test_column @@ -56,10 +44,10 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase end def test_default - assert_equal ActiveRecord::Point.new(12.2, 13.3), PostgresqlPoint.column_defaults['y'] + assert_equal ActiveRecord::Point.new(12.2, 13.3), PostgresqlPoint.column_defaults["y"] assert_equal ActiveRecord::Point.new(12.2, 13.3), PostgresqlPoint.new.y - assert_equal ActiveRecord::Point.new(14.4, 15.5), PostgresqlPoint.column_defaults['z'] + assert_equal ActiveRecord::Point.new(14.4, 15.5), PostgresqlPoint.column_defaults["z"] assert_equal ActiveRecord::Point.new(14.4, 15.5), PostgresqlPoint.new.z end @@ -104,6 +92,13 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase assert_equal ActiveRecord::Point.new(1, 2), p.x end + def test_empty_string_assignment + assert_nothing_raised { PostgresqlPoint.new(x: "") } + + p = PostgresqlPoint.new(x: "") + assert_equal nil, p.x + end + def test_array_of_points_round_trip expected_value = [ ActiveRecord::Point.new(1, 2), @@ -129,10 +124,10 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase end def test_legacy_default - assert_equal [12.2, 13.3], PostgresqlPoint.column_defaults['legacy_y'] + assert_equal [12.2, 13.3], PostgresqlPoint.column_defaults["legacy_y"] assert_equal [12.2, 13.3], PostgresqlPoint.new.legacy_y - assert_equal [14.4, 15.5], PostgresqlPoint.column_defaults['legacy_z'] + assert_equal [14.4, 15.5], PostgresqlPoint.column_defaults["legacy_z"] assert_equal [14.4, 15.5], PostgresqlPoint.new.legacy_z end @@ -183,51 +178,51 @@ class PostgresqlGeometricTest < ActiveRecord::PostgreSQLTestCase end teardown do - @connection.drop_table 'postgresql_geometrics', if_exists: true + @connection.drop_table "postgresql_geometrics", if_exists: true end def test_geometric_types g = PostgresqlGeometric.new( - :a_line_segment => '(2.0, 3), (5.5, 7.0)', - :a_box => '2.0, 3, 5.5, 7.0', - :a_path => '[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]', - :a_polygon => '((2.0, 3), (5.5, 7.0), (8.5, 11.0))', - :a_circle => '<(5.3, 10.4), 2>' + a_line_segment: "(2.0, 3), (5.5, 7.0)", + a_box: "2.0, 3, 5.5, 7.0", + a_path: "[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]", + a_polygon: "((2.0, 3), (5.5, 7.0), (8.5, 11.0))", + a_circle: "<(5.3, 10.4), 2>" ) g.save! h = PostgresqlGeometric.find(g.id) - assert_equal '[(2,3),(5.5,7)]', h.a_line_segment - assert_equal '(5.5,7),(2,3)', h.a_box # reordered to store upper right corner then bottom left corner - assert_equal '[(2,3),(5.5,7),(8.5,11)]', h.a_path - assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_polygon - assert_equal '<(5.3,10.4),2>', h.a_circle + assert_equal "[(2,3),(5.5,7)]", h.a_line_segment + assert_equal "(5.5,7),(2,3)", h.a_box # reordered to store upper right corner then bottom left corner + assert_equal "[(2,3),(5.5,7),(8.5,11)]", h.a_path + assert_equal "((2,3),(5.5,7),(8.5,11))", h.a_polygon + assert_equal "<(5.3,10.4),2>", h.a_circle end def test_alternative_format g = PostgresqlGeometric.new( - :a_line_segment => '((2.0, 3), (5.5, 7.0))', - :a_box => '(2.0, 3), (5.5, 7.0)', - :a_path => '((2.0, 3), (5.5, 7.0), (8.5, 11.0))', - :a_polygon => '2.0, 3, 5.5, 7.0, 8.5, 11.0', - :a_circle => '((5.3, 10.4), 2)' + a_line_segment: "((2.0, 3), (5.5, 7.0))", + a_box: "(2.0, 3), (5.5, 7.0)", + a_path: "((2.0, 3), (5.5, 7.0), (8.5, 11.0))", + a_polygon: "2.0, 3, 5.5, 7.0, 8.5, 11.0", + a_circle: "((5.3, 10.4), 2)" ) g.save! h = PostgresqlGeometric.find(g.id) - assert_equal '[(2,3),(5.5,7)]', h.a_line_segment - assert_equal '(5.5,7),(2,3)', h.a_box # reordered to store upper right corner then bottom left corner - assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_path - assert_equal '((2,3),(5.5,7),(8.5,11))', h.a_polygon - assert_equal '<(5.3,10.4),2>', h.a_circle + assert_equal "[(2,3),(5.5,7)]", h.a_line_segment + assert_equal "(5.5,7),(2,3)", h.a_box # reordered to store upper right corner then bottom left corner + assert_equal "((2,3),(5.5,7),(8.5,11))", h.a_path + assert_equal "((2,3),(5.5,7),(8.5,11))", h.a_polygon + assert_equal "<(5.3,10.4),2>", h.a_circle end def test_geometric_function - PostgresqlGeometric.create! a_path: '[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]' # [ ] is an open path - PostgresqlGeometric.create! a_path: '((2.0, 3), (5.5, 7.0), (8.5, 11.0))' # ( ) is a closed path + PostgresqlGeometric.create! a_path: "[(2.0, 3), (5.5, 7.0), (8.5, 11.0)]" # [ ] is an open path + PostgresqlGeometric.create! a_path: "((2.0, 3), (5.5, 7.0), (8.5, 11.0))" # ( ) is a closed path objs = PostgresqlGeometric.find_by_sql "SELECT isopen(a_path) FROM postgresql_geometrics ORDER BY id ASC" assert_equal [true, false], objs.map(&:isopen) @@ -263,28 +258,28 @@ class PostgreSQLGeometricLineTest < ActiveRecord::PostgreSQLTestCase teardown do if defined?(@connection) - @connection.drop_table 'postgresql_lines', if_exists: true + @connection.drop_table "postgresql_lines", if_exists: true end end def test_geometric_line_type g = PostgresqlLine.new( - a_line: '{2.0, 3, 5.5}' + a_line: "{2.0, 3, 5.5}" ) g.save! h = PostgresqlLine.find(g.id) - assert_equal '{2,3,5.5}', h.a_line + assert_equal "{2,3,5.5}", h.a_line end def test_alternative_format_line_type g = PostgresqlLine.new( - a_line: '(2.0, 3), (4.0, 6.0)' + a_line: "(2.0, 3), (4.0, 6.0)" ) g.save! h = PostgresqlLine.find(g.id) - assert_equal '{1.5,-1,0}', h.a_line + assert_equal "{1.5,-1,0}", h.a_line end def test_schema_dumping_for_line_type @@ -367,12 +362,12 @@ class PostgreSQLGeometricTypesTest < ActiveRecord::PostgreSQLTestCase private - def assert_column_exists(column_name) - assert connection.column_exists?(table_name, column_name) - end + def assert_column_exists(column_name) + assert connection.column_exists?(table_name, column_name) + end - def assert_type_correct(column_name, type) - column = connection.columns(table_name).find { |c| c.name == column_name.to_s } - assert_equal type, column.type - end + def assert_type_correct(column_name, type) + column = connection.columns(table_name).find { |c| c.name == column_name.to_s } + assert_equal type, column.type + end end diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb index 27cc65a643..9236a67b11 100644 --- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -1,11 +1,11 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" if ActiveRecord::Base.connection.supports_extensions? class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper class Hstore < ActiveRecord::Base - self.table_name = 'hstores' + self.table_name = "hstores" store_accessor :settings, :language, :timezone end @@ -13,40 +13,40 @@ if ActiveRecord::Base.connection.supports_extensions? def setup @connection = ActiveRecord::Base.connection - unless @connection.extension_enabled?('hstore') - @connection.enable_extension 'hstore' + unless @connection.extension_enabled?("hstore") + @connection.enable_extension "hstore" @connection.commit_db_transaction end @connection.reconnect! @connection.transaction do - @connection.create_table('hstores') do |t| - t.hstore 'tags', :default => '' - t.hstore 'payload', array: true - t.hstore 'settings' + @connection.create_table("hstores") do |t| + t.hstore "tags", default: "" + t.hstore "payload", array: true + t.hstore "settings" end end Hstore.reset_column_information - @column = Hstore.columns_hash['tags'] + @column = Hstore.columns_hash["tags"] @type = Hstore.type_for_attribute("tags") end teardown do - @connection.drop_table 'hstores', if_exists: true + @connection.drop_table "hstores", if_exists: true end def test_hstore_included_in_extensions assert @connection.respond_to?(:extensions), "connection should have a list of extensions" - assert @connection.extensions.include?('hstore'), "extension list should include hstore" + assert_includes @connection.extensions, "hstore", "extension list should include hstore" end def test_disable_enable_hstore - assert @connection.extension_enabled?('hstore') - @connection.disable_extension 'hstore' - assert_not @connection.extension_enabled?('hstore') - @connection.enable_extension 'hstore' - assert @connection.extension_enabled?('hstore') + assert @connection.extension_enabled?("hstore") + @connection.disable_extension "hstore" + assert_not @connection.extension_enabled?("hstore") + @connection.enable_extension "hstore" + assert @connection.extension_enabled?("hstore") ensure # Restore column(s) dropped by `drop extension hstore cascade;` load_schema @@ -61,22 +61,22 @@ if ActiveRecord::Base.connection.supports_extensions? end def test_default - @connection.add_column 'hstores', 'permissions', :hstore, default: '"users"=>"read", "articles"=>"write"' + @connection.add_column "hstores", "permissions", :hstore, default: '"users"=>"read", "articles"=>"write"' Hstore.reset_column_information - assert_equal({"users"=>"read", "articles"=>"write"}, Hstore.column_defaults['permissions']) - assert_equal({"users"=>"read", "articles"=>"write"}, Hstore.new.permissions) + assert_equal({ "users"=>"read", "articles"=>"write" }, Hstore.column_defaults["permissions"]) + assert_equal({ "users"=>"read", "articles"=>"write" }, Hstore.new.permissions) ensure Hstore.reset_column_information end def test_change_table_supports_hstore @connection.transaction do - @connection.change_table('hstores') do |t| - t.hstore 'users', default: '' + @connection.change_table("hstores") do |t| + t.hstore "users", default: "" end Hstore.reset_column_information - column = Hstore.columns_hash['users'] + column = Hstore.columns_hash["users"] assert_equal :hstore, column.type raise ActiveRecord::Rollback # reset the schema change @@ -103,18 +103,18 @@ if ActiveRecord::Base.connection.supports_extensions? end def test_cast_value_on_write - x = Hstore.new tags: {"bool" => true, "number" => 5} - assert_equal({"bool" => true, "number" => 5}, x.tags_before_type_cast) - assert_equal({"bool" => "true", "number" => "5"}, x.tags) + x = Hstore.new tags: { "bool" => true, "number" => 5 } + assert_equal({ "bool" => true, "number" => 5 }, x.tags_before_type_cast) + assert_equal({ "bool" => "true", "number" => "5" }, x.tags) x.save - assert_equal({"bool" => "true", "number" => "5"}, x.reload.tags) + assert_equal({ "bool" => "true", "number" => "5" }, x.reload.tags) end def test_type_cast_hstore - assert_equal({'1' => '2'}, @type.deserialize("\"1\"=>\"2\"")) + assert_equal({ "1" => "2" }, @type.deserialize("\"1\"=>\"2\"")) assert_equal({}, @type.deserialize("")) - assert_equal({'key'=>nil}, @type.deserialize('key => NULL')) - assert_equal({'c'=>'}','"a"'=>'b "a b'}, @type.deserialize(%q(c=>"}", "\"a\""=>"b \"a b"))) + assert_equal({ "key"=>nil }, @type.deserialize("key => NULL")) + assert_equal({ "c"=>"}",'"a"'=>'b "a b' }, @type.deserialize(%q(c=>"}", "\"a\""=>"b \"a b"))) end def test_with_store_accessors @@ -156,132 +156,132 @@ if ActiveRecord::Base.connection.supports_extensions? end def test_changes_in_place - hstore = Hstore.create!(settings: { 'one' => 'two' }) - hstore.settings['three'] = 'four' + hstore = Hstore.create!(settings: { "one" => "two" }) + hstore.settings["three"] = "four" hstore.save! hstore.reload - assert_equal 'four', hstore.settings['three'] + assert_equal "four", hstore.settings["three"] assert_not hstore.changed? end def test_gen1 - assert_equal(%q(" "=>""), @type.serialize({' '=>''})) + assert_equal('" "=>""', @type.serialize(" "=>"")) end def test_gen2 - assert_equal(%q(","=>""), @type.serialize({','=>''})) + assert_equal('","=>""', @type.serialize(","=>"")) end def test_gen3 - assert_equal(%q("="=>""), @type.serialize({'='=>''})) + assert_equal('"="=>""', @type.serialize("="=>"")) end def test_gen4 - assert_equal(%q(">"=>""), @type.serialize({'>'=>''})) + assert_equal('">"=>""', @type.serialize(">"=>"")) end def test_parse1 - assert_equal({'a'=>nil,'b'=>nil,'c'=>'NuLl','null'=>'c'}, @type.deserialize('a=>null,b=>NuLl,c=>"NuLl",null=>c')) + assert_equal({ "a"=>nil,"b"=>nil,"c"=>"NuLl","null"=>"c" }, @type.deserialize('a=>null,b=>NuLl,c=>"NuLl",null=>c')) end def test_parse2 - assert_equal({" " => " "}, @type.deserialize("\\ =>\\ ")) + assert_equal({ " " => " " }, @type.deserialize("\\ =>\\ ")) end def test_parse3 - assert_equal({"=" => ">"}, @type.deserialize("==>>")) + assert_equal({ "=" => ">" }, @type.deserialize("==>>")) end def test_parse4 - assert_equal({"=a"=>"q=w"}, @type.deserialize('\=a=>q=w')) + assert_equal({ "=a"=>"q=w" }, @type.deserialize('\=a=>q=w')) end def test_parse5 - assert_equal({"=a"=>"q=w"}, @type.deserialize('"=a"=>q\=w')) + assert_equal({ "=a"=>"q=w" }, @type.deserialize('"=a"=>q\=w')) end def test_parse6 - assert_equal({"\"a"=>"q>w"}, @type.deserialize('"\"a"=>q>w')) + assert_equal({ "\"a"=>"q>w" }, @type.deserialize('"\"a"=>q>w')) end def test_parse7 - assert_equal({"\"a"=>"q\"w"}, @type.deserialize('\"a=>q"w')) + assert_equal({ "\"a"=>"q\"w" }, @type.deserialize('\"a=>q"w')) end def test_rewrite @connection.execute "insert into hstores (tags) VALUES ('1=>2')" x = Hstore.first - x.tags = { '"a\'' => 'b' } + x.tags = { '"a\'' => "b" } assert x.save! end def test_select @connection.execute "insert into hstores (tags) VALUES ('1=>2')" x = Hstore.first - assert_equal({'1' => '2'}, x.tags) + assert_equal({ "1" => "2" }, x.tags) end def test_array_cycle - assert_array_cycle([{"AA" => "BB", "CC" => "DD"}, {"AA" => nil}]) + assert_array_cycle([{ "AA" => "BB", "CC" => "DD" }, { "AA" => nil }]) end def test_array_strings_with_quotes - assert_array_cycle([{'this has' => 'some "s that need to be escaped"'}]) + assert_array_cycle([{ "this has" => 'some "s that need to be escaped"' }]) end def test_array_strings_with_commas - assert_array_cycle([{'this,has' => 'many,values'}]) + assert_array_cycle([{ "this,has" => "many,values" }]) end def test_array_strings_with_array_delimiters - assert_array_cycle(['{' => '}']) + assert_array_cycle(["{" => "}"]) end def test_array_strings_with_null_strings - assert_array_cycle([{'NULL' => 'NULL'}]) + assert_array_cycle([{ "NULL" => "NULL" }]) end def test_contains_nils - assert_array_cycle([{'NULL' => nil}]) + assert_array_cycle([{ "NULL" => nil }]) end def test_select_multikey @connection.execute "insert into hstores (tags) VALUES ('1=>2,2=>3')" x = Hstore.first - assert_equal({'1' => '2', '2' => '3'}, x.tags) + assert_equal({ "1" => "2", "2" => "3" }, x.tags) end def test_create - assert_cycle('a' => 'b', '1' => '2') + assert_cycle("a" => "b", "1" => "2") end def test_nil - assert_cycle('a' => nil) + assert_cycle("a" => nil) end def test_quotes - assert_cycle('a' => 'b"ar', '1"foo' => '2') + assert_cycle("a" => 'b"ar', '1"foo' => "2") end def test_whitespace - assert_cycle('a b' => 'b ar', '1"foo' => '2') + assert_cycle("a b" => "b ar", '1"foo' => "2") end def test_backslash - assert_cycle('a\\b' => 'b\\ar', '1"foo' => '2') + assert_cycle('a\\b' => 'b\\ar', '1"foo' => "2") end def test_comma - assert_cycle('a, b' => 'bar', '1"foo' => '2') + assert_cycle("a, b" => "bar", '1"foo' => "2") end def test_arrow - assert_cycle('a=>b' => 'bar', '1"foo' => '2') + assert_cycle("a=>b" => "bar", '1"foo' => "2") end def test_quoting_special_characters - assert_cycle('ca' => 'cà', 'ac' => 'àc') + assert_cycle("ca" => "cà", "ac" => "àc") end def test_multiline @@ -300,20 +300,20 @@ if ActiveRecord::Base.connection.supports_extensions? end def test_hstore_with_serialized_attributes - HstoreWithSerialize.create! tags: TagCollection.new({"one" => "two"}) + HstoreWithSerialize.create! tags: TagCollection.new("one" => "two") record = HstoreWithSerialize.first assert_instance_of TagCollection, record.tags - assert_equal({"one" => "two"}, record.tags.to_hash) + assert_equal({ "one" => "two" }, record.tags.to_hash) record.tags = TagCollection.new("three" => "four") record.save! - assert_equal({"three" => "four"}, HstoreWithSerialize.first.tags.to_hash) + assert_equal({ "three" => "four" }, HstoreWithSerialize.first.tags.to_hash) end def test_clone_hstore_with_serialized_attributes - HstoreWithSerialize.create! tags: TagCollection.new({"one" => "two"}) + HstoreWithSerialize.create! tags: TagCollection.new("one" => "two") record = HstoreWithSerialize.first dupe = record.dup - assert_equal({"one" => "two"}, dupe.tags.to_hash) + assert_equal({ "one" => "two" }, dupe.tags.to_hash) end def test_schema_dump_with_shorthand @@ -322,32 +322,32 @@ if ActiveRecord::Base.connection.supports_extensions? end private - def assert_array_cycle(array) - # test creation - x = Hstore.create!(payload: array) - x.reload - assert_equal(array, x.payload) - - # test updating - x = Hstore.create!(payload: []) - x.payload = array - x.save! - x.reload - assert_equal(array, x.payload) - end - - def assert_cycle(hash) - # test creation - x = Hstore.create!(:tags => hash) - x.reload - assert_equal(hash, x.tags) + def assert_array_cycle(array) + # test creation + x = Hstore.create!(payload: array) + x.reload + assert_equal(array, x.payload) + + # test updating + x = Hstore.create!(payload: []) + x.payload = array + x.save! + x.reload + assert_equal(array, x.payload) + end - # test updating - x = Hstore.create!(:tags => {}) - x.tags = hash - x.save! - x.reload - assert_equal(hash, x.tags) - end + def assert_cycle(hash) + # test creation + x = Hstore.create!(tags: hash) + x.reload + assert_equal(hash, x.tags) + + # test updating + x = Hstore.create!(tags: {}) + x.tags = hash + x.save! + x.reload + assert_equal(hash, x.tags) + end end end diff --git a/activerecord/test/cases/adapters/postgresql/infinity_test.rb b/activerecord/test/cases/adapters/postgresql/infinity_test.rb index bfda933fa4..19b00258b6 100644 --- a/activerecord/test/cases/adapters/postgresql/infinity_test.rb +++ b/activerecord/test/cases/adapters/postgresql/infinity_test.rb @@ -15,7 +15,7 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase end teardown do - @connection.drop_table 'postgresql_infinities', if_exists: true + @connection.drop_table "postgresql_infinities", if_exists: true end test "type casting infinity on a float column" do @@ -25,11 +25,11 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase end test "type casting string on a float column" do - record = PostgresqlInfinity.new(float: 'Infinity') + record = PostgresqlInfinity.new(float: "Infinity") assert_equal Float::INFINITY, record.float - record = PostgresqlInfinity.new(float: '-Infinity') + record = PostgresqlInfinity.new(float: "-Infinity") assert_equal(-Float::INFINITY, record.float) - record = PostgresqlInfinity.new(float: 'NaN') + record = PostgresqlInfinity.new(float: "NaN") assert_send [record.float, :nan?] end diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb index 663de680b5..273b2c1c7b 100644 --- a/activerecord/test/cases/adapters/postgresql/json_test.rb +++ b/activerecord/test/cases/adapters/postgresql/json_test.rb @@ -1,11 +1,11 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" module PostgresqlJSONSharedTestCases include SchemaDumpingHelper class JsonDataType < ActiveRecord::Base - self.table_name = 'json_data_type' + self.table_name = "json_data_type" store_accessor :settings, :resolution end @@ -13,9 +13,9 @@ module PostgresqlJSONSharedTestCases def setup @connection = ActiveRecord::Base.connection begin - @connection.create_table('json_data_type') do |t| - t.public_send column_type, 'payload', default: {} # t.json 'payload', default: {} - t.public_send column_type, 'settings' # t.json 'settings' + @connection.create_table("json_data_type") do |t| + t.public_send column_type, "payload", default: {} # t.json 'payload', default: {} + t.public_send column_type, "settings" # t.json 'settings' end rescue ActiveRecord::StatementInvalid skip "do not test on PostgreSQL without #{column_type} type." @@ -38,22 +38,22 @@ module PostgresqlJSONSharedTestCases end def test_default - @connection.add_column 'json_data_type', 'permissions', column_type, default: {"users": "read", "posts": ["read", "write"]} + @connection.add_column "json_data_type", "permissions", column_type, default: { "users": "read", "posts": ["read", "write"] } JsonDataType.reset_column_information - assert_equal({"users"=>"read", "posts"=>["read", "write"]}, JsonDataType.column_defaults['permissions']) - assert_equal({"users"=>"read", "posts"=>["read", "write"]}, JsonDataType.new.permissions) + assert_equal({ "users"=>"read", "posts"=>["read", "write"] }, JsonDataType.column_defaults["permissions"]) + assert_equal({ "users"=>"read", "posts"=>["read", "write"] }, JsonDataType.new.permissions) ensure JsonDataType.reset_column_information end def test_change_table_supports_json @connection.transaction do - @connection.change_table('json_data_type') do |t| - t.public_send column_type, 'users', default: '{}' # t.json 'users', default: '{}' + @connection.change_table("json_data_type") do |t| + t.public_send column_type, "users", default: "{}" # t.json 'users', default: '{}' end JsonDataType.reset_column_information - column = JsonDataType.columns_hash['users'] + column = JsonDataType.columns_hash["users"] assert_equal column_type, column.type raise ActiveRecord::Rollback # reset the schema change @@ -68,11 +68,11 @@ module PostgresqlJSONSharedTestCases end def test_cast_value_on_write - x = JsonDataType.new payload: {"string" => "foo", :symbol => :bar} - assert_equal({"string" => "foo", :symbol => :bar}, x.payload_before_type_cast) - assert_equal({"string" => "foo", "symbol" => "bar"}, x.payload) + x = JsonDataType.new payload: { "string" => "foo", :symbol => :bar } + assert_equal({ "string" => "foo", :symbol => :bar }, x.payload_before_type_cast) + assert_equal({ "string" => "foo", "symbol" => "bar" }, x.payload) x.save - assert_equal({"string" => "foo", "symbol" => "bar"}, x.reload.payload) + assert_equal({ "string" => "foo", "symbol" => "bar" }, x.reload.payload) end def test_type_cast_json @@ -80,49 +80,65 @@ module PostgresqlJSONSharedTestCases data = "{\"a_key\":\"a_value\"}" hash = type.deserialize(data) - assert_equal({'a_key' => 'a_value'}, hash) - assert_equal({'a_key' => 'a_value'}, type.deserialize(data)) + assert_equal({ "a_key" => "a_value" }, hash) + assert_equal({ "a_key" => "a_value" }, type.deserialize(data)) assert_equal({}, type.deserialize("{}")) - assert_equal({'key'=>nil}, type.deserialize('{"key": null}')) - assert_equal({'c'=>'}','"a"'=>'b "a b'}, type.deserialize(%q({"c":"}", "\"a\"":"b \"a b"}))) + assert_equal({ "key"=>nil }, type.deserialize('{"key": null}')) + assert_equal({ "c"=>"}",'"a"'=>'b "a b' }, type.deserialize(%q({"c":"}", "\"a\"":"b \"a b"}))) end def test_rewrite @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')" x = JsonDataType.first - x.payload = { '"a\'' => 'b' } + x.payload = { '"a\'' => "b" } assert x.save! end def test_select @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')" x = JsonDataType.first - assert_equal({'k' => 'v'}, x.payload) + assert_equal({ "k" => "v" }, x.payload) end def test_select_multikey @connection.execute %q|insert into json_data_type (payload) VALUES ('{"k1":"v1", "k2":"v2", "k3":[1,2,3]}')| x = JsonDataType.first - assert_equal({'k1' => 'v1', 'k2' => 'v2', 'k3' => [1,2,3]}, x.payload) + assert_equal({ "k1" => "v1", "k2" => "v2", "k3" => [1,2,3] }, x.payload) end def test_null_json - @connection.execute %q|insert into json_data_type (payload) VALUES(null)| + @connection.execute "insert into json_data_type (payload) VALUES(null)" x = JsonDataType.first assert_equal(nil, x.payload) end + def test_select_nil_json_after_create + json = JsonDataType.create(payload: nil) + x = JsonDataType.where(payload:nil).first + assert_equal(json, x) + end + + def test_select_nil_json_after_update + json = JsonDataType.create(payload: "foo") + x = JsonDataType.where(payload:nil).first + assert_equal(nil, x) + + json.update_attributes payload: nil + x = JsonDataType.where(payload:nil).first + assert_equal(json.reload, x) + end + def test_select_array_json_value @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')| x = JsonDataType.first - assert_equal(['v0', {'k1' => 'v1'}], x.payload) + assert_equal(["v0", { "k1" => "v1" }], x.payload) end def test_rewrite_array_json_value @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')| x = JsonDataType.first - x.payload = ['v1', {'k2' => 'v2'}, 'v3'] + x.payload = ["v1", { "k2" => "v2" }, "v3"] assert x.save! end @@ -161,20 +177,20 @@ module PostgresqlJSONSharedTestCases json = JsonDataType.new assert_not json.changed? - json.payload = { 'one' => 'two' } + json.payload = { "one" => "two" } assert json.changed? assert json.payload_changed? json.save! assert_not json.changed? - json.payload['three'] = 'four' + json.payload["three"] = "four" assert json.payload_changed? json.save! json.reload - assert_equal({ 'one' => 'two', 'three' => 'four' }, json.payload) + assert_equal({ "one" => "two", "three" => "four" }, json.payload) assert_not json.changed? end diff --git a/activerecord/test/cases/adapters/postgresql/ltree_test.rb b/activerecord/test/cases/adapters/postgresql/ltree_test.rb index 56516c82b4..2b5ac1cac6 100644 --- a/activerecord/test/cases/adapters/postgresql/ltree_test.rb +++ b/activerecord/test/cases/adapters/postgresql/ltree_test.rb @@ -1,20 +1,20 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class PostgresqlLtreeTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper class Ltree < ActiveRecord::Base - self.table_name = 'ltrees' + self.table_name = "ltrees" end def setup @connection = ActiveRecord::Base.connection - enable_extension!('ltree', @connection) + enable_extension!("ltree", @connection) @connection.transaction do - @connection.create_table('ltrees') do |t| - t.ltree 'path' + @connection.create_table("ltrees") do |t| + t.ltree "path" end end rescue ActiveRecord::StatementInvalid @@ -22,28 +22,28 @@ class PostgresqlLtreeTest < ActiveRecord::PostgreSQLTestCase end teardown do - @connection.drop_table 'ltrees', if_exists: true + @connection.drop_table "ltrees", if_exists: true end def test_column - column = Ltree.columns_hash['path'] + column = Ltree.columns_hash["path"] assert_equal :ltree, column.type assert_equal "ltree", column.sql_type assert_not column.array? - type = Ltree.type_for_attribute('path') + type = Ltree.type_for_attribute("path") assert_not type.binary? end def test_write - ltree = Ltree.new(path: '1.2.3.4') + ltree = Ltree.new(path: "1.2.3.4") assert ltree.save! end def test_select @connection.execute "insert into ltrees (path) VALUES ('1.2.3')" ltree = Ltree.first - assert_equal '1.2.3', ltree.path + assert_equal "1.2.3", ltree.path end def test_schema_dump_with_shorthand diff --git a/activerecord/test/cases/adapters/postgresql/money_test.rb b/activerecord/test/cases/adapters/postgresql/money_test.rb index c031178479..1b5d8362af 100644 --- a/activerecord/test/cases/adapters/postgresql/money_test.rb +++ b/activerecord/test/cases/adapters/postgresql/money_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper @@ -9,14 +9,14 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase setup do @connection = ActiveRecord::Base.connection @connection.execute("set lc_monetary = 'C'") - @connection.create_table('postgresql_moneys', force: true) do |t| + @connection.create_table("postgresql_moneys", force: true) do |t| t.money "wealth" t.money "depth", default: "150.55" end end teardown do - @connection.drop_table 'postgresql_moneys', if_exists: true + @connection.drop_table "postgresql_moneys", if_exists: true end def test_column @@ -31,7 +31,7 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase end def test_default - assert_equal BigDecimal.new("150.55"), PostgresqlMoney.column_defaults['depth'] + assert_equal BigDecimal.new("150.55"), PostgresqlMoney.column_defaults["depth"] assert_equal BigDecimal.new("150.55"), PostgresqlMoney.new.depth end @@ -46,7 +46,7 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase end def test_money_type_cast - type = PostgresqlMoney.type_for_attribute('wealth') + type = PostgresqlMoney.type_for_attribute("wealth") assert_equal(12345678.12, type.cast("$12,345,678.12")) assert_equal(12345678.12, type.cast("$12.345.678,12")) assert_equal(-1.15, type.cast("-$1.15")) @@ -63,7 +63,7 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase money = PostgresqlMoney.create(wealth: "987.65") assert_equal 987.65, money.wealth - new_value = BigDecimal.new('123.45') + new_value = BigDecimal.new("123.45") money.wealth = new_value money.save! money.reload @@ -80,7 +80,7 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase def test_update_all_with_money_big_decimal money = PostgresqlMoney.create! - PostgresqlMoney.update_all(wealth: '123.45'.to_d) + PostgresqlMoney.update_all(wealth: "123.45".to_d) money.reload assert_equal 123.45, money.wealth diff --git a/activerecord/test/cases/adapters/postgresql/network_test.rb b/activerecord/test/cases/adapters/postgresql/network_test.rb index fe6ee4e2d9..a33b0ef8a7 100644 --- a/activerecord/test/cases/adapters/postgresql/network_test.rb +++ b/activerecord/test/cases/adapters/postgresql/network_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class PostgresqlNetworkTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper @@ -7,15 +7,15 @@ class PostgresqlNetworkTest < ActiveRecord::PostgreSQLTestCase setup do @connection = ActiveRecord::Base.connection - @connection.create_table('postgresql_network_addresses', force: true) do |t| - t.inet 'inet_address', default: "192.168.1.1" - t.cidr 'cidr_address', default: "192.168.1.0/24" - t.macaddr 'mac_address', default: "ff:ff:ff:ff:ff:ff" + @connection.create_table("postgresql_network_addresses", force: true) do |t| + t.inet "inet_address", default: "192.168.1.1" + t.cidr "cidr_address", default: "192.168.1.0/24" + t.macaddr "mac_address", default: "ff:ff:ff:ff:ff:ff" end end teardown do - @connection.drop_table 'postgresql_network_addresses', if_exists: true + @connection.drop_table "postgresql_network_addresses", if_exists: true end def test_cidr_column @@ -49,33 +49,33 @@ class PostgresqlNetworkTest < ActiveRecord::PostgreSQLTestCase end def test_network_types - PostgresqlNetworkAddress.create(cidr_address: '192.168.0.0/24', - inet_address: '172.16.1.254/32', - mac_address: '01:23:45:67:89:0a') + PostgresqlNetworkAddress.create(cidr_address: "192.168.0.0/24", + inet_address: "172.16.1.254/32", + mac_address: "01:23:45:67:89:0a") address = PostgresqlNetworkAddress.first - assert_equal IPAddr.new('192.168.0.0/24'), address.cidr_address - assert_equal IPAddr.new('172.16.1.254'), address.inet_address - assert_equal '01:23:45:67:89:0a', address.mac_address + assert_equal IPAddr.new("192.168.0.0/24"), address.cidr_address + assert_equal IPAddr.new("172.16.1.254"), address.inet_address + assert_equal "01:23:45:67:89:0a", address.mac_address - address.cidr_address = '10.1.2.3/32' - address.inet_address = '10.0.0.0/8' - address.mac_address = 'bc:de:f0:12:34:56' + address.cidr_address = "10.1.2.3/32" + address.inet_address = "10.0.0.0/8" + address.mac_address = "bc:de:f0:12:34:56" address.save! assert address.reload - assert_equal IPAddr.new('10.1.2.3/32'), address.cidr_address - assert_equal IPAddr.new('10.0.0.0/8'), address.inet_address - assert_equal 'bc:de:f0:12:34:56', address.mac_address + assert_equal IPAddr.new("10.1.2.3/32"), address.cidr_address + assert_equal IPAddr.new("10.0.0.0/8"), address.inet_address + assert_equal "bc:de:f0:12:34:56", address.mac_address end def test_invalid_network_address - invalid_address = PostgresqlNetworkAddress.new(cidr_address: 'invalid addr', - inet_address: 'invalid addr') + invalid_address = PostgresqlNetworkAddress.new(cidr_address: "invalid addr", + inet_address: "invalid addr") assert_nil invalid_address.cidr_address assert_nil invalid_address.inet_address - assert_equal 'invalid addr', invalid_address.cidr_address_before_type_cast - assert_equal 'invalid addr', invalid_address.inet_address_before_type_cast + assert_equal "invalid addr", invalid_address.cidr_address_before_type_cast + assert_equal "invalid addr", invalid_address.inet_address_before_type_cast assert invalid_address.save invalid_address.reload diff --git a/activerecord/test/cases/adapters/postgresql/numbers_test.rb b/activerecord/test/cases/adapters/postgresql/numbers_test.rb index ba7e7dc9a3..834354dcc9 100644 --- a/activerecord/test/cases/adapters/postgresql/numbers_test.rb +++ b/activerecord/test/cases/adapters/postgresql/numbers_test.rb @@ -5,14 +5,14 @@ class PostgresqlNumberTest < ActiveRecord::PostgreSQLTestCase setup do @connection = ActiveRecord::Base.connection - @connection.create_table('postgresql_numbers', force: true) do |t| - t.column 'single', 'REAL' - t.column 'double', 'DOUBLE PRECISION' + @connection.create_table("postgresql_numbers", force: true) do |t| + t.column "single", "REAL" + t.column "double", "DOUBLE PRECISION" end end teardown do - @connection.drop_table 'postgresql_numbers', if_exists: true + @connection.drop_table "postgresql_numbers", if_exists: true end def test_data_type diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb index 9832df7839..e6af93a53e 100644 --- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb +++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'support/ddl_helper' -require 'support/connection_helper' +require "support/ddl_helper" +require "support/connection_helper" module ActiveRecord module ConnectionAdapters @@ -15,15 +15,15 @@ module ActiveRecord def test_bad_connection assert_raise ActiveRecord::NoDatabaseError do - configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'should_not_exist-cinco-dog-db') + configuration = ActiveRecord::Base.configurations["arunit"].merge(database: "should_not_exist-cinco-dog-db") connection = ActiveRecord::Base.postgresql_connection(configuration) - connection.exec_query('SELECT 1') + connection.exec_query("SELECT 1") end end def test_valid_column with_example_table do - column = @connection.columns('ex').find { |col| col.name == 'id' } + column = @connection.columns("ex").find { |col| col.name == "id" } assert @connection.valid_type?(column.type) end end @@ -34,144 +34,138 @@ module ActiveRecord def test_primary_key with_example_table do - assert_equal 'id', @connection.primary_key('ex') + assert_equal "id", @connection.primary_key("ex") end end def test_primary_key_works_tables_containing_capital_letters - assert_equal 'id', @connection.primary_key('CamelCase') + assert_equal "id", @connection.primary_key("CamelCase") end def test_non_standard_primary_key - with_example_table 'data character varying(255) primary key' do - assert_equal 'data', @connection.primary_key('ex') + with_example_table "data character varying(255) primary key" do + assert_equal "data", @connection.primary_key("ex") end end def test_primary_key_returns_nil_for_no_pk - with_example_table 'id integer' do - assert_nil @connection.primary_key('ex') + with_example_table "id integer" do + assert_nil @connection.primary_key("ex") end end def test_primary_key_raises_error_if_table_not_found assert_raises(ActiveRecord::StatementInvalid) do - @connection.primary_key('unobtainium') + @connection.primary_key("unobtainium") end end def test_exec_insert_with_returning_disabled connection = connection_without_insert_returning - result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id', 'postgresql_partitioned_table_parent_id_seq') - expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first + result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], "id", "postgresql_partitioned_table_parent_id_seq") + expect = connection.query("select max(id) from postgresql_partitioned_table_parent").first.first assert_equal expect.to_i, result.rows.first.first end def test_exec_insert_with_returning_disabled_and_no_sequence_name_given connection = connection_without_insert_returning - result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id') - expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first + result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], "id") + expect = connection.query("select max(id) from postgresql_partitioned_table_parent").first.first assert_equal expect.to_i, result.rows.first.first end def test_exec_insert_default_values_with_returning_disabled_and_no_sequence_name_given connection = connection_without_insert_returning - result = connection.exec_insert("insert into postgresql_partitioned_table_parent DEFAULT VALUES", nil, [], 'id') - expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first + result = connection.exec_insert("insert into postgresql_partitioned_table_parent DEFAULT VALUES", nil, [], "id") + expect = connection.query("select max(id) from postgresql_partitioned_table_parent").first.first assert_equal expect.to_i, result.rows.first.first end def test_exec_insert_default_values_quoted_schema_with_returning_disabled_and_no_sequence_name_given connection = connection_without_insert_returning - result = connection.exec_insert('insert into "public"."postgresql_partitioned_table_parent" DEFAULT VALUES', nil, [], 'id') - expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first + result = connection.exec_insert('insert into "public"."postgresql_partitioned_table_parent" DEFAULT VALUES', nil, [], "id") + expect = connection.query("select max(id) from postgresql_partitioned_table_parent").first.first 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') + assert_equal "public.accounts_id_seq", + @connection.serial_sequence("accounts", "id") assert_raises(ActiveRecord::StatementInvalid) do - @connection.serial_sequence('zomg', 'id') + @connection.serial_sequence("zomg", "id") end end def test_default_sequence_name - assert_equal 'public.accounts_id_seq', - @connection.default_sequence_name('accounts', 'id') + assert_equal "public.accounts_id_seq", + @connection.default_sequence_name("accounts", "id") - assert_equal 'public.accounts_id_seq', - @connection.default_sequence_name('accounts') + assert_equal "public.accounts_id_seq", + @connection.default_sequence_name("accounts") end def test_default_sequence_name_bad_table - assert_equal 'zomg_id_seq', - @connection.default_sequence_name('zomg', 'id') + assert_equal "zomg_id_seq", + @connection.default_sequence_name("zomg", "id") - assert_equal 'zomg_id_seq', - @connection.default_sequence_name('zomg') + assert_equal "zomg_id_seq", + @connection.default_sequence_name("zomg") end def test_pk_and_sequence_for with_example_table do - pk, seq = @connection.pk_and_sequence_for('ex') - assert_equal 'id', pk - assert_equal @connection.default_sequence_name('ex', 'id'), seq.to_s + pk, seq = @connection.pk_and_sequence_for("ex") + assert_equal "id", pk + assert_equal @connection.default_sequence_name("ex", "id"), seq.to_s end end def test_pk_and_sequence_for_with_non_standard_primary_key - with_example_table 'code serial primary key' do - pk, seq = @connection.pk_and_sequence_for('ex') - assert_equal 'code', pk - assert_equal @connection.default_sequence_name('ex', 'code'), seq.to_s + with_example_table "code serial primary key" do + pk, seq = @connection.pk_and_sequence_for("ex") + assert_equal "code", pk + assert_equal @connection.default_sequence_name("ex", "code"), seq.to_s end end def test_pk_and_sequence_for_returns_nil_if_no_seq - with_example_table 'id integer primary key' do - assert_nil @connection.pk_and_sequence_for('ex') + with_example_table "id integer primary key" do + assert_nil @connection.pk_and_sequence_for("ex") end end def test_pk_and_sequence_for_returns_nil_if_no_pk - with_example_table 'id integer' do - assert_nil @connection.pk_and_sequence_for('ex') + with_example_table "id integer" do + assert_nil @connection.pk_and_sequence_for("ex") end end def test_pk_and_sequence_for_returns_nil_if_table_not_found - assert_nil @connection.pk_and_sequence_for('unobtainium') + assert_nil @connection.pk_and_sequence_for("unobtainium") end def test_pk_and_sequence_for_with_collision_pg_class_oid - @connection.exec_query('create table ex(id serial primary key)') - @connection.exec_query('create table ex2(id serial primary key)') + @connection.exec_query("create table ex(id serial primary key)") + @connection.exec_query("create table ex2(id serial primary key)") correct_depend_record = [ "'pg_class'::regclass", "'ex_id_seq'::regclass", - '0', + "0", "'pg_class'::regclass", "'ex'::regclass", - '1', + "1", "'a'" ] collision_depend_record = [ "'pg_attrdef'::regclass", "'ex2_id_seq'::regclass", - '0', + "0", "'pg_class'::regclass", "'ex'::regclass", - '1', + "1", "'a'" ] @@ -185,15 +179,15 @@ module ActiveRecord "INSERT INTO pg_depend VALUES(#{correct_depend_record.join(',')})" ) - seq = @connection.pk_and_sequence_for('ex').last + seq = @connection.pk_and_sequence_for("ex").last assert_equal PostgreSQL::Name.new("public", "ex_id_seq"), seq @connection.exec_query( "DELETE FROM pg_depend WHERE objid = 'ex2_id_seq'::regclass AND refobjid = 'ex'::regclass AND deptype = 'a'" ) ensure - @connection.drop_table 'ex', if_exists: true - @connection.drop_table 'ex2', if_exists: true + @connection.drop_table "ex", if_exists: true + @connection.drop_table "ex2", if_exists: true end def test_table_alias_length @@ -204,74 +198,74 @@ module ActiveRecord def test_exec_no_binds with_example_table do - result = @connection.exec_query('SELECT id, data FROM ex') + result = @connection.exec_query("SELECT id, data FROM ex") assert_equal 0, result.rows.length assert_equal 2, result.columns.length assert_equal %w{ id data }, result.columns - string = @connection.quote('foo') + string = @connection.quote("foo") @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") - result = @connection.exec_query('SELECT id, data FROM ex') + result = @connection.exec_query("SELECT id, data FROM ex") assert_equal 1, result.rows.length assert_equal 2, result.columns.length - assert_equal [[1, 'foo']], result.rows + assert_equal [[1, "foo"]], result.rows end end if ActiveRecord::Base.connection.prepared_statements def test_exec_with_binds with_example_table do - string = @connection.quote('foo') + string = @connection.quote("foo") @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") bind = Relation::QueryAttribute.new("id", 1, Type::Value.new) - result = @connection.exec_query('SELECT id, data FROM ex WHERE id = $1', nil, [bind]) + result = @connection.exec_query("SELECT id, data FROM ex WHERE id = $1", nil, [bind]) assert_equal 1, result.rows.length assert_equal 2, result.columns.length - assert_equal [[1, 'foo']], result.rows + assert_equal [[1, "foo"]], result.rows end end def test_exec_typecasts_bind_vals with_example_table do - string = @connection.quote('foo') + string = @connection.quote("foo") @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") bind = Relation::QueryAttribute.new("id", "1-fuu", Type::Integer.new) - result = @connection.exec_query('SELECT id, data FROM ex WHERE id = $1', nil, [bind]) + result = @connection.exec_query("SELECT id, data FROM ex WHERE id = $1", nil, [bind]) assert_equal 1, result.rows.length assert_equal 2, result.columns.length - assert_equal [[1, 'foo']], result.rows + assert_equal [[1, "foo"]], result.rows end end end def test_partial_index with_example_table do - @connection.add_index 'ex', %w{ id number }, :name => 'partial', :where => "number > 100" - index = @connection.indexes('ex').find { |idx| idx.name == 'partial' } + @connection.add_index "ex", %w{ id number }, name: "partial", where: "number > 100" + index = @connection.indexes("ex").find { |idx| idx.name == "partial" } assert_equal "(number > 100)", index.where end end def test_expression_index with_example_table do - @connection.add_index 'ex', 'mod(id, 10), abs(number)', name: 'expression' - index = @connection.indexes('ex').find { |idx| idx.name == 'expression' } - assert_equal 'mod(id, 10), abs(number)', index.columns + @connection.add_index "ex", "mod(id, 10), abs(number)", name: "expression" + index = @connection.indexes("ex").find { |idx| idx.name == "expression" } + assert_equal "mod(id, 10), abs(number)", index.columns end end def test_index_with_opclass with_example_table do - @connection.add_index 'ex', 'data varchar_pattern_ops', name: 'with_opclass' - index = @connection.indexes('ex').find { |idx| idx.name == 'with_opclass' } - assert_equal 'data varchar_pattern_ops', index.columns + @connection.add_index "ex", "data varchar_pattern_ops", name: "with_opclass" + index = @connection.indexes("ex").find { |idx| idx.name == "with_opclass" } + assert_equal "data varchar_pattern_ops", index.columns end end @@ -292,8 +286,8 @@ module ActiveRecord def test_columns_for_distinct_with_case assert_equal( - 'posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0', - @connection.columns_for_distinct('posts.id', + "posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0", + @connection.columns_for_distinct("posts.id", ["CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END"]) ) end @@ -374,7 +368,7 @@ module ActiveRecord def test_unparsed_defaults_are_at_least_set_when_saving with_example_table "id SERIAL PRIMARY KEY, number INTEGER NOT NULL DEFAULT (4 + 4) * 2 / 4" do number_klass = Class.new(ActiveRecord::Base) do - self.table_name = 'ex' + self.table_name = "ex" end column = number_klass.columns_hash["number"] assert_nil column.default @@ -390,13 +384,13 @@ module ActiveRecord private - def with_example_table(definition = 'id serial primary key, number integer, data character varying(255)', &block) - super(@connection, 'ex', definition, &block) - end + def with_example_table(definition = "id serial primary key, number integer, data character varying(255)", &block) + super(@connection, "ex", definition, &block) + end - def connection_without_insert_returning - ActiveRecord::Base.postgresql_connection(ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false)) - end + def connection_without_insert_returning + ActiveRecord::Base.postgresql_connection(ActiveRecord::Base.configurations["arunit"].merge(insert_returning: false)) + end end end end diff --git a/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb b/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb index f1519db48b..b898929f8a 100644 --- a/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb +++ b/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb @@ -18,5 +18,4 @@ class PreparedStatementsTest < ActiveRecord::PostgreSQLTestCase Developer.where(id: 1) end end - end diff --git a/activerecord/test/cases/adapters/postgresql/quoting_test.rb b/activerecord/test/cases/adapters/postgresql/quoting_test.rb index 5e6f4dbbb8..865a3a5098 100644 --- a/activerecord/test/cases/adapters/postgresql/quoting_test.rb +++ b/activerecord/test/cases/adapters/postgresql/quoting_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'ipaddr' +require "ipaddr" module ActiveRecord module ConnectionAdapters @@ -10,11 +10,11 @@ module ActiveRecord end def test_type_cast_true - assert_equal 't', @conn.type_cast(true) + assert_equal "t", @conn.type_cast(true) end def test_type_cast_false - assert_equal 'f', @conn.type_cast(false) + assert_equal "f", @conn.type_cast(false) end def test_quote_float_nan diff --git a/activerecord/test/cases/adapters/postgresql/range_test.rb b/activerecord/test/cases/adapters/postgresql/range_test.rb index 0edfa4ed9d..f411884dfd 100644 --- a/activerecord/test/cases/adapters/postgresql/range_test.rb +++ b/activerecord/test/cases/adapters/postgresql/range_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/connection_helper' +require "support/connection_helper" if ActiveRecord::Base.connection.respond_to?(:supports_ranges?) && ActiveRecord::Base.connection.supports_ranges? class PostgresqlRange < ActiveRecord::Base @@ -23,7 +23,7 @@ if ActiveRecord::Base.connection.respond_to?(:supports_ranges?) && ActiveRecord: ); _SQL - @connection.create_table('postgresql_ranges') do |t| + @connection.create_table("postgresql_ranges") do |t| t.daterange :date_range t.numrange :num_range t.tsrange :ts_range @@ -32,7 +32,7 @@ _SQL t.int8range :int8_range end - @connection.add_column 'postgresql_ranges', 'float_range', 'floatrange' + @connection.add_column "postgresql_ranges", "float_range", "floatrange" end PostgresqlRange.reset_column_information rescue ActiveRecord::StatementInvalid @@ -93,8 +93,8 @@ _SQL end teardown do - @connection.drop_table 'postgresql_ranges', if_exists: true - @connection.execute 'DROP TYPE IF EXISTS floatrange' + @connection.drop_table "postgresql_ranges", if_exists: true + @connection.execute "DROP TYPE IF EXISTS floatrange" reset_connection end @@ -132,10 +132,10 @@ _SQL end def test_numrange_values - assert_equal BigDecimal.new('0.1')..BigDecimal.new('0.2'), @first_range.num_range - assert_equal BigDecimal.new('0.1')...BigDecimal.new('0.2'), @second_range.num_range - assert_equal BigDecimal.new('0.1')...BigDecimal.new('Infinity'), @third_range.num_range - assert_equal BigDecimal.new('-Infinity')...BigDecimal.new('Infinity'), @fourth_range.num_range + assert_equal BigDecimal.new("0.1")..BigDecimal.new("0.2"), @first_range.num_range + assert_equal BigDecimal.new("0.1")...BigDecimal.new("0.2"), @second_range.num_range + assert_equal BigDecimal.new("0.1")...BigDecimal.new("Infinity"), @third_range.num_range + assert_equal BigDecimal.new("-Infinity")...BigDecimal.new("Infinity"), @fourth_range.num_range assert_nil @empty_range.num_range end @@ -148,8 +148,8 @@ _SQL end def test_tstzrange_values - assert_equal Time.parse('2010-01-01 09:30:00 UTC')..Time.parse('2011-01-01 17:30:00 UTC'), @first_range.tstz_range - assert_equal Time.parse('2010-01-01 09:30:00 UTC')...Time.parse('2011-01-01 17:30:00 UTC'), @second_range.tstz_range + assert_equal Time.parse("2010-01-01 09:30:00 UTC")..Time.parse("2011-01-01 17:30:00 UTC"), @first_range.tstz_range + assert_equal Time.parse("2010-01-01 09:30:00 UTC")...Time.parse("2011-01-01 17:30:00 UTC"), @second_range.tstz_range assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.tstz_range) assert_nil @empty_range.tstz_range end @@ -183,17 +183,17 @@ _SQL end def test_create_tstzrange - tstzrange = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2011-02-02 14:30:00 CDT') + tstzrange = Time.parse("2010-01-01 14:30:00 +0100")...Time.parse("2011-02-02 14:30:00 CDT") round_trip(@new_range, :tstz_range, tstzrange) assert_equal @new_range.tstz_range, tstzrange - assert_equal @new_range.tstz_range, Time.parse('2010-01-01 13:30:00 UTC')...Time.parse('2011-02-02 19:30:00 UTC') + assert_equal @new_range.tstz_range, Time.parse("2010-01-01 13:30:00 UTC")...Time.parse("2011-02-02 19:30:00 UTC") end def test_update_tstzrange assert_equal_round_trip(@first_range, :tstz_range, - Time.parse('2010-01-01 14:30:00 CDT')...Time.parse('2011-02-02 14:30:00 CET')) + Time.parse("2010-01-01 14:30:00 CDT")...Time.parse("2011-02-02 14:30:00 CET")) assert_nil_round_trip(@first_range, :tstz_range, - Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2010-01-01 13:30:00 +0000')) + Time.parse("2010-01-01 14:30:00 +0100")...Time.parse("2010-01-01 13:30:00 +0000")) end def test_create_tsrange @@ -232,14 +232,14 @@ _SQL def test_create_numrange assert_equal_round_trip(@new_range, :num_range, - BigDecimal.new('0.5')...BigDecimal.new('1')) + BigDecimal.new("0.5")...BigDecimal.new("1")) end def test_update_numrange assert_equal_round_trip(@first_range, :num_range, - BigDecimal.new('0.5')...BigDecimal.new('1')) + BigDecimal.new("0.5")...BigDecimal.new("1")) assert_nil_round_trip(@first_range, :num_range, - BigDecimal.new('0.5')...BigDecimal.new('0.5')) + BigDecimal.new("0.5")...BigDecimal.new("0.5")) end def test_create_daterange @@ -282,6 +282,12 @@ _SQL assert_raises(ArgumentError) { PostgresqlRange.create!(tstz_range: "(''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'']") } end + def test_where_by_attribute_with_range + range = 1..100 + record = PostgresqlRange.create!(int4_range: range) + assert_equal record, PostgresqlRange.where(int4_range: range).take + end + def test_update_all_with_ranges PostgresqlRange.create! diff --git a/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb b/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb index c895ab9db5..0ff04bfa27 100644 --- a/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb +++ b/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb @@ -1,5 +1,5 @@ -require 'cases/helper' -require 'support/connection_helper' +require "cases/helper" +require "support/connection_helper" class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase self.use_transactional_tests = false @@ -14,7 +14,7 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase def execute(sql) if IS_REFERENTIAL_INTEGRITY_SQL.call(sql) super "BROKEN;" rescue nil # put transaction in broken state - raise ActiveRecord::StatementInvalid, 'PG::InsufficientPrivilege' + raise ActiveRecord::StatementInvalid, "PG::InsufficientPrivilege" else super end @@ -24,7 +24,7 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase module ProgrammerMistake def execute(sql) if IS_REFERENTIAL_INTEGRITY_SQL.call(sql) - raise ArgumentError, 'something is not right.' + raise ArgumentError, "something is not right." else super end @@ -48,10 +48,10 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase warning = capture(:stderr) do e = assert_raises(ActiveRecord::InvalidForeignKey) do @connection.disable_referential_integrity do - raise ActiveRecord::InvalidForeignKey, 'Should be re-raised' + raise ActiveRecord::InvalidForeignKey, "Should be re-raised" end end - assert_equal 'Should be re-raised', e.message + assert_equal "Should be re-raised", e.message end assert_match (/WARNING: Rails was not able to disable referential integrity/), warning assert_match (/cause: PG::InsufficientPrivilege/), warning @@ -63,10 +63,10 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase warning = capture(:stderr) do e = assert_raises(ActiveRecord::StatementInvalid) do @connection.disable_referential_integrity do - raise ActiveRecord::StatementInvalid, 'Should be re-raised' + raise ActiveRecord::StatementInvalid, "Should be re-raised" end end - assert_equal 'Should be re-raised', e.message + assert_equal "Should be re-raised", e.message end assert warning.blank?, "expected no warnings but got:\n#{warning}" end @@ -105,7 +105,7 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::PostgreSQLTestCase private - def assert_transaction_is_not_broken - assert_equal 1, @connection.select_value("SELECT 1") - end + def assert_transaction_is_not_broken + assert_equal 1, @connection.select_value("SELECT 1") + end end diff --git a/activerecord/test/cases/adapters/postgresql/rename_table_test.rb b/activerecord/test/cases/adapters/postgresql/rename_table_test.rb index bd64bae308..e9e7f717ac 100644 --- a/activerecord/test/cases/adapters/postgresql/rename_table_test.rb +++ b/activerecord/test/cases/adapters/postgresql/rename_table_test.rb @@ -24,11 +24,11 @@ class PostgresqlRenameTableTest < ActiveRecord::PostgreSQLTestCase private - def num_indices_named(name) - @connection.execute(<<-SQL).values.length - SELECT 1 FROM "pg_index" - JOIN "pg_class" ON "pg_index"."indexrelid" = "pg_class"."oid" - WHERE "pg_class"."relname" = '#{name}' - SQL - end + def num_indices_named(name) + @connection.execute(<<-SQL).values.length + SELECT 1 FROM "pg_index" + JOIN "pg_class" ON "pg_index"."indexrelid" = "pg_class"."oid" + WHERE "pg_class"."relname" = '#{name}' + SQL + end end diff --git a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb index 285a92f60e..7193f23880 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb @@ -6,12 +6,12 @@ end class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase self.use_transactional_tests = false - TABLE_NAME = 'schema_things' + TABLE_NAME = "schema_things" COLUMNS = [ - 'id serial primary key', - 'name character varying(50)' + "id serial primary key", + "name character varying(50)" ] - USERS = ['rails_pg_schema_user1', 'rails_pg_schema_user2'] + USERS = ["rails_pg_schema_user1", "rails_pg_schema_user2"] def setup @connection = ActiveRecord::Base.connection @@ -45,7 +45,7 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase def test_session_auth= assert_raise(ActiveRecord::StatementInvalid) do - @connection.session_auth = 'DEFAULT' + @connection.session_auth = "DEFAULT" @connection.execute "SELECT * FROM #{TABLE_NAME}" end end @@ -68,7 +68,7 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase USERS.each do |u| @connection.clear_cache! set_session_auth u - assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [bind_param(1)]) + assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = $1", "SQL", [bind_param(1)]) set_session_auth end end @@ -90,9 +90,9 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase assert_nothing_raised do USERS.each do |u| set_session_auth u - st = SchemaThing.new :name => 'TEST1' + st = SchemaThing.new name: "TEST1" st.save! - st = SchemaThing.new :id => 5, :name => 'TEST2' + st = SchemaThing.new id: 5, name: "TEST2" st.save! set_session_auth end @@ -100,17 +100,17 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase end def test_tables_in_current_schemas - assert !@connection.tables.include?(TABLE_NAME) + assert_not_includes @connection.tables, TABLE_NAME USERS.each do |u| set_session_auth u - assert @connection.tables.include?(TABLE_NAME) + assert_includes @connection.tables, TABLE_NAME set_session_auth end end private - def set_session_auth auth = nil - @connection.session_auth = auth || 'default' + def set_session_auth(auth = nil) + @connection.session_auth = auth || "default" end def bind_param(value) diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 52ef07f654..51a2306c59 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'models/default' -require 'support/schema_dumping_helper' +require "models/default" +require "support/schema_dumping_helper" module PGSchemaHelper def with_schema_search_path(schema_search_path) @@ -17,32 +17,32 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase include PGSchemaHelper self.use_transactional_tests = false - SCHEMA_NAME = 'test_schema' - SCHEMA2_NAME = 'test_schema2' - TABLE_NAME = 'things' - CAPITALIZED_TABLE_NAME = 'Things' - INDEX_A_NAME = 'a_index_things_on_name' - INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema' - INDEX_C_NAME = 'c_index_full_text_search' - INDEX_D_NAME = 'd_index_things_on_description_desc' - INDEX_E_NAME = 'e_index_things_on_name_vector' - INDEX_A_COLUMN = 'name' - INDEX_B_COLUMN_S1 = 'email' - INDEX_B_COLUMN_S2 = 'moment' - INDEX_C_COLUMN = %q{(to_tsvector('english', coalesce(things.name, '')))} - INDEX_D_COLUMN = 'description' - INDEX_E_COLUMN = 'name_vector' + SCHEMA_NAME = "test_schema" + SCHEMA2_NAME = "test_schema2" + TABLE_NAME = "things" + CAPITALIZED_TABLE_NAME = "Things" + INDEX_A_NAME = "a_index_things_on_name" + INDEX_B_NAME = "b_index_things_on_different_columns_in_each_schema" + INDEX_C_NAME = "c_index_full_text_search" + INDEX_D_NAME = "d_index_things_on_description_desc" + INDEX_E_NAME = "e_index_things_on_name_vector" + INDEX_A_COLUMN = "name" + INDEX_B_COLUMN_S1 = "email" + INDEX_B_COLUMN_S2 = "moment" + INDEX_C_COLUMN = "(to_tsvector('english', coalesce(things.name, '')))" + INDEX_D_COLUMN = "description" + INDEX_E_COLUMN = "name_vector" COLUMNS = [ - 'id integer', - 'name character varying(50)', - 'email character varying(50)', - 'description character varying(100)', - 'name_vector tsvector', - 'moment timestamp without time zone default now()' + "id integer", + "name character varying(50)", + "email character varying(50)", + "description character varying(100)", + "name_vector tsvector", + "moment timestamp without time zone default now()" ] - PK_TABLE_NAME = 'table_with_pk' - UNMATCHED_SEQUENCE_NAME = 'unmatched_primary_key_default_value_seq' - UNMATCHED_PK_TABLE_NAME = 'table_with_unmatched_sequence_for_pk' + PK_TABLE_NAME = "table_with_pk" + UNMATCHED_SEQUENCE_NAME = "unmatched_primary_key_default_value_seq" + UNMATCHED_PK_TABLE_NAME = "table_with_unmatched_sequence_for_pk" class Thing1 < ActiveRecord::Base self.table_name = "test_schema.things" @@ -61,7 +61,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase end class Thing5 < ActiveRecord::Base - self.table_name = 'things' + self.table_name = "things" end class Song < ActiveRecord::Base @@ -130,7 +130,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase ensure @connection.drop_schema "test_schema3" end - assert !@connection.schema_names.include?("test_schema3") + assert_not_includes @connection.schema_names, "test_schema3" end def test_drop_schema_if_exists @@ -168,21 +168,21 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase def test_raise_wrapped_exception_on_bad_prepare assert_raises(ActiveRecord::StatementInvalid) do - @connection.exec_query "select * from developers where id = ?", 'sql', [bind_param(1)] + @connection.exec_query "select * from developers where id = ?", "sql", [bind_param(1)] end end if ActiveRecord::Base.connection.prepared_statements def test_schema_change_with_prepared_stmt altered = false - @connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)] - @connection.exec_query "alter table developers add column zomg int", 'sql', [] + @connection.exec_query "select * from developers where id = $1", "sql", [bind_param(1)] + @connection.exec_query "alter table developers add column zomg int", "sql", [] altered = true - @connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)] + @connection.exec_query "select * from developers where id = $1", "sql", [bind_param(1)] ensure # We are not using DROP COLUMN IF EXISTS because that syntax is only # supported by pg 9.X - @connection.exec_query("alter table developers drop column zomg", 'sql', []) if altered + @connection.exec_query("alter table developers drop column zomg", "sql", []) if altered end end @@ -200,7 +200,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase end def test_data_source_exists_when_not_on_schema_search_path - with_schema_search_path('PUBLIC') do + with_schema_search_path("PUBLIC") do assert(!@connection.data_source_exists?(TABLE_NAME), "data_source exists but should not be found") end end @@ -246,9 +246,9 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase end def test_proper_encoding_of_table_name - assert_equal '"table_name"', @connection.quote_table_name('table_name') + assert_equal '"table_name"', @connection.quote_table_name("table_name") assert_equal '"table.name"', @connection.quote_table_name('"table.name"') - assert_equal '"schema_name"."table_name"', @connection.quote_table_name('schema_name.table_name') + assert_equal '"schema_name"."table_name"', @connection.quote_table_name("schema_name.table_name") assert_equal '"schema_name"."table.name"', @connection.quote_table_name('schema_name."table.name"') assert_equal '"schema.name"."table_name"', @connection.quote_table_name('"schema.name".table_name') assert_equal '"schema.name"."table.name"', @connection.quote_table_name('"schema.name"."table.name"') @@ -260,25 +260,25 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase assert_equal 0, Thing3.count assert_equal 0, Thing4.count - Thing1.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now) + Thing1.create(id: 1, name: "thing1", email: "thing1@localhost", moment: Time.now) assert_equal 1, Thing1.count assert_equal 0, Thing2.count assert_equal 0, Thing3.count assert_equal 0, Thing4.count - Thing2.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now) + Thing2.create(id: 1, name: "thing1", email: "thing1@localhost", moment: Time.now) assert_equal 1, Thing1.count assert_equal 1, Thing2.count assert_equal 0, Thing3.count assert_equal 0, Thing4.count - Thing3.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now) + Thing3.create(id: 1, name: "thing1", email: "thing1@localhost", moment: Time.now) assert_equal 1, Thing1.count assert_equal 1, Thing2.count assert_equal 1, Thing3.count assert_equal 0, Thing4.count - Thing4.create(:id => 1, :name => "thing1", :email => "thing1@localhost", :moment => Time.now) + Thing4.create(id: 1, name: "thing1", email: "thing1@localhost", moment: Time.now) assert_equal 1, Thing1.count assert_equal 1, Thing2.count assert_equal 1, Thing3.count @@ -287,7 +287,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase def test_raise_on_unquoted_schema_name assert_raises(ActiveRecord::StatementInvalid) do - with_schema_search_path '$user,public' + with_schema_search_path "$user,public" end end @@ -307,7 +307,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase assert @connection.index_name_exists?(TABLE_NAME, INDEX_D_NAME, true) assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME, true) assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME, true) - assert_not @connection.index_name_exists?(TABLE_NAME, 'missing_index', true) + assert_not @connection.index_name_exists?(TABLE_NAME, "missing_index", true) end end @@ -332,7 +332,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase @connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)" with_schema_search_path SCHEMA_NAME do - assert_nothing_raised { @connection.remove_index "things", name: "things_Index"} + assert_nothing_raised { @connection.remove_index "things", name: "things_Index" } end end @@ -356,13 +356,13 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase %(#{SCHEMA_NAME}."#{PK_TABLE_NAME}"), %(#{SCHEMA_NAME}.#{PK_TABLE_NAME}) ].each do |given| - assert_equal 'id', @connection.primary_key(given), "primary key should be found when table referenced as #{given}" + assert_equal "id", @connection.primary_key(given), "primary key should be found when table referenced as #{given}" end end def test_primary_key_assuming_schema_search_path with_schema_search_path(SCHEMA_NAME) do - assert_equal 'id', @connection.primary_key(PK_TABLE_NAME), "primary key should be found" + assert_equal "id", @connection.primary_key(PK_TABLE_NAME), "primary key should be found" end end @@ -381,7 +381,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}") ].each do |given| pk, seq = @connection.pk_and_sequence_for(given) - assert_equal 'id', pk, "primary key should be found when table referenced as #{given}" + assert_equal "id", pk, "primary key should be found when table referenced as #{given}" assert_equal pg_name.new(SCHEMA_NAME, "#{PK_TABLE_NAME}_id_seq"), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}") assert_equal pg_name.new(SCHEMA_NAME, UNMATCHED_SEQUENCE_NAME), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}") end @@ -389,10 +389,10 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase def test_current_schema { - %('$user',public) => 'public', + %('$user',public) => "public", SCHEMA_NAME => SCHEMA_NAME, %(#{SCHEMA2_NAME},#{SCHEMA_NAME},public) => SCHEMA2_NAME, - %(public,#{SCHEMA2_NAME},#{SCHEMA_NAME}) => 'public' + %(public,#{SCHEMA2_NAME},#{SCHEMA_NAME}) => "public" }.each do |given,expect| with_schema_search_path(given) { assert_equal expect, @connection.current_schema } end @@ -401,7 +401,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase def test_prepared_statements_with_multiple_schemas [SCHEMA_NAME, SCHEMA2_NAME].each do |schema_name| with_schema_search_path schema_name do - Thing5.create(:id => 1, :name => "thing inside #{SCHEMA_NAME}", :email => "thing1@localhost", :moment => Time.now) + Thing5.create(id: 1, name: "thing inside #{SCHEMA_NAME}", email: "thing1@localhost", moment: Time.now) end end @@ -414,10 +414,10 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase def test_schema_exists? { - 'public' => true, + "public" => true, SCHEMA_NAME => true, SCHEMA2_NAME => true, - 'darkside' => false + "darkside" => false }.each do |given,expect| assert_equal expect, @connection.schema_exists?(given) end @@ -442,7 +442,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase private def columns(table_name) @connection.send(:column_definitions, table_name).map do |name, type, default| - "#{name} #{type}" + (default ? " default #{default}" : '') + "#{name} #{type}" + (default ? " default #{default}" : "") end end diff --git a/activerecord/test/cases/adapters/postgresql/serial_test.rb b/activerecord/test/cases/adapters/postgresql/serial_test.rb index 8abe064bf1..d711b3b729 100644 --- a/activerecord/test/cases/adapters/postgresql/serial_test.rb +++ b/activerecord/test/cases/adapters/postgresql/serial_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class PostgresqlSerialTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper diff --git a/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb b/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb index 5aab246c99..eb9978a898 100644 --- a/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb +++ b/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord module ConnectionAdapters @@ -17,22 +17,22 @@ module ActiveRecord if Process.respond_to?(:fork) def test_cache_is_per_pid cache = StatementPool.new nil, 10 - cache['foo'] = 'bar' - assert_equal 'bar', cache['foo'] + cache["foo"] = "bar" + assert_equal "bar", cache["foo"] pid = fork { - lookup = cache['foo']; + lookup = cache["foo"]; exit!(!lookup) } Process.waitpid pid - assert $?.success?, 'process should exit successfully' + assert $?.success?, "process should exit successfully" end end def test_dealloc_does_not_raise_on_inactive_connection cache = StatementPool.new InactivePGconn.new, 10 - cache['foo'] = 'bar' + cache["foo"] = "bar" assert_nothing_raised { cache.clear } end end diff --git a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb index 4c4866b46b..e7c1d97d16 100644 --- a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb +++ b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb @@ -1,6 +1,6 @@ -require 'cases/helper' -require 'models/developer' -require 'models/topic' +require "cases/helper" +require "models/developer" +require "models/topic" class PostgresqlTimestampTest < ActiveRecord::PostgreSQLTestCase class PostgresqlTimestampWithZone < ActiveRecord::Base; end @@ -32,7 +32,7 @@ class PostgresqlTimestampTest < ActiveRecord::PostgreSQLTestCase with_timezone_config default: :local, aware_attributes: false do @connection.reconnect! # make sure to use a non-UTC time zone - @connection.execute("SET time zone 'America/Jamaica'", 'SCHEMA') + @connection.execute("SET time zone 'America/Jamaica'", "SCHEMA") timestamp = PostgresqlTimestampWithZone.find(1) assert_equal Time.utc(2010,1,1, 11,0,0), timestamp.time @@ -54,37 +54,37 @@ class PostgresqlTimestampFixtureTest < ActiveRecord::PostgreSQLTestCase def test_load_infinity_and_beyond d = Developer.find_by_sql("select 'infinity'::timestamp as updated_at") - assert d.first.updated_at.infinite?, 'timestamp should be infinite' + assert d.first.updated_at.infinite?, "timestamp should be infinite" d = Developer.find_by_sql("select '-infinity'::timestamp as updated_at") time = d.first.updated_at - assert time.infinite?, 'timestamp should be infinite' + assert time.infinite?, "timestamp should be infinite" assert_operator time, :<, 0 end def test_save_infinity_and_beyond - d = Developer.create!(:name => 'aaron', :updated_at => 1.0 / 0.0) + d = Developer.create!(name: "aaron", updated_at: 1.0 / 0.0) assert_equal(1.0 / 0.0, d.updated_at) - d = Developer.create!(:name => 'aaron', :updated_at => -1.0 / 0.0) + d = Developer.create!(name: "aaron", updated_at: -1.0 / 0.0) assert_equal(-1.0 / 0.0, d.updated_at) end def test_bc_timestamp date = Date.new(0) - 1.week - Developer.create!(:name => "aaron", :updated_at => date) + Developer.create!(name: "aaron", updated_at: date) assert_equal date, Developer.find_by_name("aaron").updated_at end def test_bc_timestamp_leap_year date = Time.utc(-4, 2, 29) - Developer.create!(:name => "taihou", :updated_at => date) + Developer.create!(name: "taihou", updated_at: date) assert_equal date, Developer.find_by_name("taihou").updated_at end def test_bc_timestamp_year_zero date = Time.utc(0, 4, 7) - Developer.create!(:name => "yahagi", :updated_at => date) + Developer.create!(name: "yahagi", updated_at: date) assert_equal date, Developer.find_by_name("yahagi").updated_at end end diff --git a/activerecord/test/cases/adapters/postgresql/transaction_test.rb b/activerecord/test/cases/adapters/postgresql/transaction_test.rb new file mode 100644 index 0000000000..00119f13bb --- /dev/null +++ b/activerecord/test/cases/adapters/postgresql/transaction_test.rb @@ -0,0 +1,100 @@ +require "cases/helper" +require "support/connection_helper" +require "concurrent/atomic/cyclic_barrier" + +module ActiveRecord + class PostgresqlTransactionTest < ActiveRecord::PostgreSQLTestCase + self.use_transactional_tests = false + + class Sample < ActiveRecord::Base + self.table_name = "samples" + end + + setup do + @connection = ActiveRecord::Base.connection + + @connection.transaction do + @connection.drop_table "samples", if_exists: true + @connection.create_table("samples") do |t| + t.integer "value" + end + end + + Sample.reset_column_information + end + + teardown do + @connection.drop_table "samples", if_exists: true + end + + test "raises SerializationFailure when a serialization failure occurs" do + with_warning_suppression do + assert_raises(ActiveRecord::SerializationFailure) do + thread = Thread.new do + Sample.transaction isolation: :serializable do + Sample.delete_all + + 10.times do |i| + sleep 0.1 + + Sample.create value: i + end + end + end + + sleep 0.1 + + Sample.transaction isolation: :serializable do + Sample.delete_all + + 10.times do |i| + sleep 0.1 + + Sample.create value: i + end + end + + thread.join + end + end + end + + test "raises Deadlocked when a deadlock is encountered" do + with_warning_suppression do + assert_raises(ActiveRecord::Deadlocked) do + barrier = Concurrent::CyclicBarrier.new(2) + + s1 = Sample.create value: 1 + s2 = Sample.create value: 2 + + thread = Thread.new do + Sample.transaction do + s1.lock! + barrier.wait + s2.update_attributes value: 1 + end + end + + begin + Sample.transaction do + s2.lock! + barrier.wait + s1.update_attributes value: 2 + end + ensure + thread.join + end + end + end + end + + protected + + def with_warning_suppression + log_level = @connection.client_min_messages + @connection.client_min_messages = "error" + yield + @connection.client_min_messages = log_level + end + end +end diff --git a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb index 77a99ca778..bd45a9daa0 100644 --- a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb +++ b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" class PostgresqlTypeLookupTest < ActiveRecord::PostgreSQLTestCase setup do @@ -9,8 +9,8 @@ class PostgresqlTypeLookupTest < ActiveRecord::PostgreSQLTestCase box_array = @connection.type_map.lookup(1020) int_array = @connection.type_map.lookup(1007) - assert_equal ';', box_array.delimiter - assert_equal ',', int_array.delimiter + assert_equal ";", box_array.delimiter + assert_equal ",", int_array.delimiter end test "array types correctly respect registration of subtypes" do @@ -18,7 +18,7 @@ class PostgresqlTypeLookupTest < ActiveRecord::PostgreSQLTestCase bigint_array = @connection.type_map.lookup(1016, -1, "bigint[]") big_array = [123456789123456789] - assert_raises(RangeError) { int_array.serialize(big_array) } + assert_raises(ActiveModel::RangeError) { int_array.serialize(big_array) } assert_equal "{123456789123456789}", bigint_array.serialize(big_array) end @@ -27,7 +27,7 @@ class PostgresqlTypeLookupTest < ActiveRecord::PostgreSQLTestCase bigint_range = @connection.type_map.lookup(3926, -1, "int8range") big_range = 0..123456789123456789 - assert_raises(RangeError) { int_range.serialize(big_range) } + assert_raises(ActiveModel::RangeError) { int_range.serialize(big_range) } assert_equal "[0,123456789123456789]", bigint_range.serialize(big_range) end end diff --git a/activerecord/test/cases/adapters/postgresql/utils_test.rb b/activerecord/test/cases/adapters/postgresql/utils_test.rb index 095c1826e5..01c597beae 100644 --- a/activerecord/test/cases/adapters/postgresql/utils_test.rb +++ b/activerecord/test/cases/adapters/postgresql/utils_test.rb @@ -1,5 +1,5 @@ -require 'cases/helper' -require 'active_record/connection_adapters/postgresql/utils' +require "cases/helper" +require "active_record/connection_adapters/postgresql/utils" class PostgreSQLUtilsTest < ActiveRecord::PostgreSQLTestCase Name = ActiveRecord::ConnectionAdapters::PostgreSQL::Name @@ -7,14 +7,14 @@ class PostgreSQLUtilsTest < ActiveRecord::PostgreSQLTestCase def test_extract_schema_qualified_name { - %(table_name) => [nil,'table_name'], - %("table.name") => [nil,'table.name'], + %(table_name) => [nil,"table_name"], + %("table.name") => [nil,"table.name"], %(schema.table_name) => %w{schema table_name}, %("schema".table_name) => %w{schema table_name}, %(schema."table_name") => %w{schema table_name}, %("schema"."table_name") => %w{schema table_name}, - %("even spaces".table) => ['even spaces','table'], - %(schema."table.name") => ['schema', 'table.name'] + %("even spaces".table) => ["even spaces","table"], + %(schema."table.name") => ["schema", "table.name"] }.each do |given, expect| assert_equal Name.new(*expect), extract_schema_qualified_name(given) end @@ -54,7 +54,7 @@ class PostgreSQLNameTest < ActiveRecord::PostgreSQLTestCase end test "can be used as hash key" do - hash = {Name.new("schema", "article_seq") => "success"} + hash = { Name.new("schema", "article_seq") => "success" } assert_equal "success", hash[Name.new("schema", "article_seq")] assert_equal nil, hash[Name.new("schema", "articles")] assert_equal nil, hash[Name.new("public", "article_seq")] diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb index 7628075ad2..9a59691737 100644 --- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb +++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" module PostgresqlUUIDHelper def connection @@ -20,10 +20,10 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase end setup do - enable_extension!('uuid-ossp', connection) + enable_extension!("uuid-ossp", connection) connection.create_table "uuid_data_type" do |t| - t.uuid 'guid' + t.uuid "guid" end end @@ -34,13 +34,13 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase def test_change_column_default @connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v1()" UUIDType.reset_column_information - column = UUIDType.columns_hash['thingy'] + column = UUIDType.columns_hash["thingy"] assert_equal "uuid_generate_v1()", column.default_function @connection.change_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v4()" UUIDType.reset_column_information - column = UUIDType.columns_hash['thingy'] + column = UUIDType.columns_hash["thingy"] assert_equal "uuid_generate_v4()", column.default_function ensure UUIDType.reset_column_information @@ -57,46 +57,46 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase end def test_treat_blank_uuid_as_nil - UUIDType.create! guid: '' + UUIDType.create! guid: "" assert_equal(nil, UUIDType.last.guid) end def test_treat_invalid_uuid_as_nil - uuid = UUIDType.create! guid: 'foobar' + uuid = UUIDType.create! guid: "foobar" assert_equal(nil, uuid.guid) end def test_invalid_uuid_dont_modify_before_type_cast - uuid = UUIDType.new guid: 'foobar' - assert_equal 'foobar', uuid.guid_before_type_cast + uuid = UUIDType.new guid: "foobar" + assert_equal "foobar", uuid.guid_before_type_cast end def test_acceptable_uuid_regex # Valid uuids - ['A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11', - '{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}', - 'a0eebc999c0b4ef8bb6d6bb9bd380a11', - 'a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11', - '{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}', + ["A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11", + "{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}", + "a0eebc999c0b4ef8bb6d6bb9bd380a11", + "a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11", + "{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}", # The following is not a valid RFC 4122 UUID, but PG doesn't seem to care, # so we shouldn't block it either. (Pay attention to "fb6d" – the "f" here # is invalid – it must be one of 8, 9, A, B, a, b according to the spec.) - '{a0eebc99-9c0b-4ef8-fb6d-6bb9bd380a11}', + "{a0eebc99-9c0b-4ef8-fb6d-6bb9bd380a11}", ].each do |valid_uuid| uuid = UUIDType.new guid: valid_uuid assert_not_nil uuid.guid end # Invalid uuids - [['A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11'], + [["A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11"], Hash.new, 0, 0.0, true, - 'Z0000C99-9C0B-4EF8-BB6D-6BB9BD380A11', - 'a0eebc999r0b4ef8ab6d6bb9bd380a11', - 'a0ee-bc99------4ef8-bb6d-6bb9-bd38-0a11', - '{a0eebc99-bb6d6bb9-bd380a11}'].each do |invalid_uuid| + "Z0000C99-9C0B-4EF8-BB6D-6BB9BD380A11", + "a0eebc999r0b4ef8ab6d6bb9bd380a11", + "a0ee-bc99------4ef8-bb6d-6bb9-bd38-0a11", + "{a0eebc99-bb6d6bb9-bd380a11}"].each do |invalid_uuid| uuid = UUIDType.new guid: invalid_uuid assert_nil uuid.guid end @@ -142,13 +142,13 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper class UUID < ActiveRecord::Base - self.table_name = 'pg_uuids' + self.table_name = "pg_uuids" end setup do - connection.create_table('pg_uuids', id: :uuid, default: 'uuid_generate_v1()') do |t| - t.string 'name' - t.uuid 'other_uuid', default: 'uuid_generate_v4()' + connection.create_table("pg_uuids", id: :uuid, default: "uuid_generate_v1()") do |t| + t.string "name" + t.uuid "other_uuid", default: "uuid_generate_v4()" end # Create custom PostgreSQL function to generate UUIDs @@ -160,21 +160,21 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase SQL # Create such a table with custom function as default value generator - connection.create_table('pg_uuids_2', id: :uuid, default: 'my_uuid_generator()') do |t| - t.string 'name' - t.uuid 'other_uuid_2', default: 'my_uuid_generator()' + connection.create_table("pg_uuids_2", id: :uuid, default: "my_uuid_generator()") do |t| + t.string "name" + t.uuid "other_uuid_2", default: "my_uuid_generator()" end end teardown do drop_table "pg_uuids" - drop_table 'pg_uuids_2' - connection.execute 'DROP FUNCTION IF EXISTS my_uuid_generator();' + drop_table "pg_uuids_2" + connection.execute "DROP FUNCTION IF EXISTS my_uuid_generator();" end if ActiveRecord::Base.connection.supports_extensions? def test_id_is_uuid - assert_equal :uuid, UUID.columns_hash['id'].type + assert_equal :uuid, UUID.columns_hash["id"].type assert UUID.primary_key end @@ -190,21 +190,21 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase end def test_pk_and_sequence_for_uuid_primary_key - pk, seq = connection.pk_and_sequence_for('pg_uuids') - assert_equal 'id', pk + pk, seq = connection.pk_and_sequence_for("pg_uuids") + assert_equal "id", pk assert_equal nil, seq end def test_schema_dumper_for_uuid_primary_key schema = dump_table_schema "pg_uuids" assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: -> { "uuid_generate_v1\(\)" }/, schema) - assert_match(/t\.uuid "other_uuid", default: -> { "uuid_generate_v4\(\)" }/, schema) + assert_match(/t\.uuid "other_uuid", default: -> { "uuid_generate_v4\(\)" }/, schema) end def test_schema_dumper_for_uuid_primary_key_with_custom_default schema = dump_table_schema "pg_uuids_2" assert_match(/\bcreate_table "pg_uuids_2", id: :uuid, default: -> { "my_uuid_generator\(\)" }/, schema) - assert_match(/t\.uuid "other_uuid_2", default: -> { "my_uuid_generator\(\)" }/, schema) + assert_match(/t\.uuid "other_uuid_2", default: -> { "my_uuid_generator\(\)" }/, schema) end end end @@ -214,9 +214,9 @@ class PostgresqlUUIDTestNilDefault < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper setup do - connection.create_table('pg_uuids', id: false) do |t| + connection.create_table("pg_uuids", id: false) do |t| t.primary_key :id, :uuid, default: nil - t.string 'name' + t.string "name" end end @@ -244,30 +244,30 @@ class PostgresqlUUIDTestInverseOf < ActiveRecord::PostgreSQLTestCase include PostgresqlUUIDHelper class UuidPost < ActiveRecord::Base - self.table_name = 'pg_uuid_posts' + self.table_name = "pg_uuid_posts" has_many :uuid_comments, inverse_of: :uuid_post end class UuidComment < ActiveRecord::Base - self.table_name = 'pg_uuid_comments' + self.table_name = "pg_uuid_comments" belongs_to :uuid_post end setup do connection.transaction do - connection.create_table('pg_uuid_posts', id: :uuid) do |t| - t.string 'title' + connection.create_table("pg_uuid_posts", id: :uuid) do |t| + t.string "title" end - connection.create_table('pg_uuid_comments', id: :uuid) do |t| + connection.create_table("pg_uuid_comments", id: :uuid) do |t| t.references :uuid_post, type: :uuid - t.string 'content' + t.string "content" end end end teardown do - drop_table "pg_uuid_comments" - drop_table "pg_uuid_posts" + drop_table "pg_uuid_comments" + drop_table "pg_uuid_posts" end if ActiveRecord::Base.connection.supports_extensions? @@ -290,5 +290,4 @@ class PostgresqlUUIDTestInverseOf < ActiveRecord::PostgreSQLTestCase assert_nil UuidPost.find_by(id: 789) end end - end diff --git a/activerecord/test/cases/adapters/postgresql/xml_test.rb b/activerecord/test/cases/adapters/postgresql/xml_test.rb index add32699fa..826b384fb3 100644 --- a/activerecord/test/cases/adapters/postgresql/xml_test.rb +++ b/activerecord/test/cases/adapters/postgresql/xml_test.rb @@ -1,28 +1,28 @@ -require 'cases/helper' -require 'support/schema_dumping_helper' +require "cases/helper" +require "support/schema_dumping_helper" class PostgresqlXMLTest < ActiveRecord::PostgreSQLTestCase include SchemaDumpingHelper class XmlDataType < ActiveRecord::Base - self.table_name = 'xml_data_type' + self.table_name = "xml_data_type" end def setup @connection = ActiveRecord::Base.connection begin @connection.transaction do - @connection.create_table('xml_data_type') do |t| - t.xml 'payload' + @connection.create_table("xml_data_type") do |t| + t.xml "payload" end end rescue ActiveRecord::StatementInvalid skip "do not test on PG without xml" end - @column = XmlDataType.columns_hash['payload'] + @column = XmlDataType.columns_hash["payload"] end teardown do - @connection.drop_table 'xml_data_type', if_exists: true + @connection.drop_table "xml_data_type", if_exists: true end def test_column @@ -30,7 +30,7 @@ class PostgresqlXMLTest < ActiveRecord::PostgreSQLTestCase end def test_null_xml - @connection.execute %q|insert into xml_data_type (payload) VALUES(null)| + @connection.execute "insert into xml_data_type (payload) VALUES(null)" assert_nil XmlDataType.first.payload end diff --git a/activerecord/test/cases/adapters/sqlite3/collation_test.rb b/activerecord/test/cases/adapters/sqlite3/collation_test.rb index 58a9469ce5..28e8f12c18 100644 --- a/activerecord/test/cases/adapters/sqlite3/collation_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/collation_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class SQLite3CollationTest < ActiveRecord::SQLite3TestCase include SchemaDumpingHelper @@ -7,8 +7,8 @@ class SQLite3CollationTest < ActiveRecord::SQLite3TestCase def setup @connection = ActiveRecord::Base.connection @connection.create_table :collation_table_sqlite3, force: true do |t| - t.string :string_nocase, collation: 'NOCASE' - t.text :text_rtrim, collation: 'RTRIM' + t.string :string_nocase, collation: "NOCASE" + t.text :text_rtrim, collation: "RTRIM" end end @@ -17,32 +17,32 @@ class SQLite3CollationTest < ActiveRecord::SQLite3TestCase end test "string column with collation" do - column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == 'string_nocase' } + column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == "string_nocase" } assert_equal :string, column.type - assert_equal 'NOCASE', column.collation + assert_equal "NOCASE", column.collation end test "text column with collation" do - column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == 'text_rtrim' } + column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == "text_rtrim" } assert_equal :text, column.type - assert_equal 'RTRIM', column.collation + assert_equal "RTRIM", column.collation end test "add column with collation" do - @connection.add_column :collation_table_sqlite3, :title, :string, collation: 'RTRIM' + @connection.add_column :collation_table_sqlite3, :title, :string, collation: "RTRIM" - column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == 'title' } + column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == "title" } assert_equal :string, column.type - assert_equal 'RTRIM', column.collation + assert_equal "RTRIM", column.collation end test "change column with collation" do @connection.add_column :collation_table_sqlite3, :description, :string - @connection.change_column :collation_table_sqlite3, :description, :text, collation: 'RTRIM' + @connection.change_column :collation_table_sqlite3, :description, :text, collation: "RTRIM" - column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == 'description' } + column = @connection.columns(:collation_table_sqlite3).find { |c| c.name == "description" } assert_equal :text, column.type - assert_equal 'RTRIM', column.collation + assert_equal "RTRIM", column.collation end test "schema dump includes collation" do diff --git a/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb b/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb index 34e3b2e023..8342b05870 100644 --- a/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb @@ -10,8 +10,8 @@ class CopyTableTest < ActiveRecord::SQLite3TestCase end end - def test_copy_table(from = 'customers', to = 'customers2', options = {}) - assert_nothing_raised {copy_table(from, to, options)} + def test_copy_table(from = "customers", to = "customers2", options = {}) + assert_nothing_raised { copy_table(from, to, options) } assert_equal row_count(from), row_count(to) if block_given? @@ -24,39 +24,39 @@ class CopyTableTest < ActiveRecord::SQLite3TestCase end def test_copy_table_renaming_column - test_copy_table('customers', 'customers2', - :rename => {'name' => 'person_name'}) do |from, to, options| - expected = column_values(from, 'name') - assert_equal expected, column_values(to, 'person_name') + test_copy_table("customers", "customers2", + rename: { "name" => "person_name" }) do |from, to, options| + expected = column_values(from, "name") + assert_equal expected, column_values(to, "person_name") assert expected.any?, "No values in table: #{expected.inspect}" end end def test_copy_table_allows_to_pass_options_to_create_table - @connection.create_table('blocker_table') - test_copy_table('customers', 'blocker_table', force: true) + @connection.create_table("blocker_table") + test_copy_table("customers", "blocker_table", force: true) end def test_copy_table_with_index - test_copy_table('comments', 'comments_with_index') do - @connection.add_index('comments_with_index', ['post_id', 'type']) - test_copy_table('comments_with_index', 'comments_with_index2') do - assert_equal table_indexes_without_name('comments_with_index'), - table_indexes_without_name('comments_with_index2') + test_copy_table("comments", "comments_with_index") do + @connection.add_index("comments_with_index", ["post_id", "type"]) + test_copy_table("comments_with_index", "comments_with_index2") do + assert_equal table_indexes_without_name("comments_with_index"), + table_indexes_without_name("comments_with_index2") end end end def test_copy_table_without_primary_key - test_copy_table('developers_projects', 'programmers_projects') do - assert_nil @connection.primary_key('programmers_projects') + test_copy_table("developers_projects", "programmers_projects") do + assert_nil @connection.primary_key("programmers_projects") end end def test_copy_table_with_id_col_that_is_not_primary_key - test_copy_table('goofy_string_id', 'goofy_string_id2') do - original_id = @connection.columns('goofy_string_id').detect{|col| col.name == 'id' } - copied_id = @connection.columns('goofy_string_id2').detect{|col| col.name == 'id' } + test_copy_table("goofy_string_id", "goofy_string_id2") do + original_id = @connection.columns("goofy_string_id").detect { |col| col.name == "id" } + copied_id = @connection.columns("goofy_string_id2").detect { |col| col.name == "id" } assert_equal original_id.type, copied_id.type assert_equal original_id.sql_type, copied_id.sql_type assert_equal original_id.limit, copied_id.limit @@ -64,28 +64,28 @@ class CopyTableTest < ActiveRecord::SQLite3TestCase end def test_copy_table_with_unconventional_primary_key - test_copy_table('owners', 'owners_unconventional') do - original_pk = @connection.primary_key('owners') - copied_pk = @connection.primary_key('owners_unconventional') + test_copy_table("owners", "owners_unconventional") do + original_pk = @connection.primary_key("owners") + copied_pk = @connection.primary_key("owners_unconventional") assert_equal original_pk, copied_pk end end def test_copy_table_with_binary_column - test_copy_table 'binaries', 'binaries2' + test_copy_table "binaries", "binaries2" end protected def copy_table(from, to, options = {}) - @connection.copy_table(from, to, {:temporary => true}.merge(options)) + @connection.copy_table(from, to, { temporary: true }.merge(options)) end def column_names(table) - @connection.table_structure(table).map {|column| column['name']} + @connection.table_structure(table).map { |column| column["name"] } end def column_values(table, column) - @connection.select_all("SELECT #{column} FROM #{table} ORDER BY id").map {|row| row[column]} + @connection.select_all("SELECT #{column} FROM #{table} ORDER BY id").map { |row| row[column] } end def table_indexes_without_name(table) @@ -93,6 +93,6 @@ protected end def row_count(table) - @connection.select_one("SELECT COUNT(*) AS count FROM #{table}")['count'] + @connection.select_one("SELECT COUNT(*) AS count FROM #{table}")["count"] end end diff --git a/activerecord/test/cases/adapters/sqlite3/explain_test.rb b/activerecord/test/cases/adapters/sqlite3/explain_test.rb index a1a6e5f16a..128acb79cf 100644 --- a/activerecord/test/cases/adapters/sqlite3/explain_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/explain_test.rb @@ -1,19 +1,19 @@ require "cases/helper" -require 'models/developer' -require 'models/computer' +require "models/developer" +require "models/computer" class SQLite3ExplainTest < ActiveRecord::SQLite3TestCase fixtures :developers def test_explain_for_one_query explain = Developer.where(id: 1).explain - assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\?|1)), explain + assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\? \[\["id", 1\]\]|1)), explain assert_match(/(SEARCH )?TABLE developers USING (INTEGER )?PRIMARY KEY/, explain) end def test_explain_with_eager_loading explain = Developer.where(id: 1).includes(:audit_logs).explain - assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\?|1)), explain + assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\? \[\["id", 1\]\]|1)), explain assert_match(/(SEARCH )?TABLE developers USING (INTEGER )?PRIMARY KEY/, explain) assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" = 1), explain assert_match(/(SCAN )?TABLE audit_logs/, explain) diff --git a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb index f3ec2b98d3..80a37e83ff 100644 --- a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb @@ -1,100 +1,94 @@ require "cases/helper" -require 'bigdecimal' -require 'yaml' -require 'securerandom' - -module ActiveRecord - module ConnectionAdapters - class SQLite3Adapter - class QuotingTest < ActiveRecord::SQLite3TestCase - def setup - @conn = ActiveRecord::Base.connection - end - - def test_type_cast_binary_encoding_without_logger - @conn.extend(Module.new { def logger; end }) - binary = SecureRandom.hex - expected = binary.dup.encode!(Encoding::UTF_8) - assert_equal expected, @conn.type_cast(binary) - end - - def test_type_cast_symbol - assert_equal 'foo', @conn.type_cast(:foo) - end - - def test_type_cast_date - date = Date.today - expected = @conn.quoted_date(date) - assert_equal expected, @conn.type_cast(date) - end - - def test_type_cast_time - time = Time.now - expected = @conn.quoted_date(time) - assert_equal expected, @conn.type_cast(time) - end - - def test_type_cast_numeric - assert_equal 10, @conn.type_cast(10) - assert_equal 2.2, @conn.type_cast(2.2) - end - - def test_type_cast_nil - assert_equal nil, @conn.type_cast(nil) - end - - def test_type_cast_true - assert_equal 't', @conn.type_cast(true) - end - - def test_type_cast_false - assert_equal 'f', @conn.type_cast(false) - end - - def test_type_cast_bigdecimal - bd = BigDecimal.new '10.0' - assert_equal bd.to_f, @conn.type_cast(bd) - end - - def test_type_cast_unknown_should_raise_error - obj = Class.new.new - assert_raise(TypeError) { @conn.type_cast(obj) } - end - - def test_type_cast_object_which_responds_to_quoted_id - quoted_id_obj = Class.new { - def quoted_id - "'zomg'" - end - - def id - 10 - end - }.new - assert_equal 10, @conn.type_cast(quoted_id_obj) - - quoted_id_obj = Class.new { - def quoted_id - "'zomg'" - end - }.new - assert_raise(TypeError) { @conn.type_cast(quoted_id_obj) } - end - - def test_quoting_binary_strings - value = "hello".encode('ascii-8bit') - type = Type::String.new - - assert_equal "'hello'", @conn.quote(type.serialize(value)) - end - - def test_quoted_time_returns_date_qualified_time - value = ::Time.utc(2000, 1, 1, 12, 30, 0, 999999) - type = Type::Time.new - - assert_equal "'2000-01-01 12:30:00.999999'", @conn.quote(type.serialize(value)) - end +require "bigdecimal" +require "yaml" +require "securerandom" + +class SQLite3QuotingTest < ActiveRecord::SQLite3TestCase + def setup + @conn = ActiveRecord::Base.connection + end + + def test_type_cast_binary_encoding_without_logger + @conn.extend(Module.new { def logger; end }) + binary = SecureRandom.hex + expected = binary.dup.encode!(Encoding::UTF_8) + assert_equal expected, @conn.type_cast(binary) + end + + def test_type_cast_symbol + assert_equal "foo", @conn.type_cast(:foo) + end + + def test_type_cast_date + date = Date.today + expected = @conn.quoted_date(date) + assert_equal expected, @conn.type_cast(date) + end + + def test_type_cast_time + time = Time.now + expected = @conn.quoted_date(time) + assert_equal expected, @conn.type_cast(time) + end + + def test_type_cast_numeric + assert_equal 10, @conn.type_cast(10) + assert_equal 2.2, @conn.type_cast(2.2) + end + + def test_type_cast_nil + assert_equal nil, @conn.type_cast(nil) + end + + def test_type_cast_true + assert_equal "t", @conn.type_cast(true) + end + + def test_type_cast_false + assert_equal "f", @conn.type_cast(false) + end + + def test_type_cast_bigdecimal + bd = BigDecimal.new "10.0" + assert_equal bd.to_f, @conn.type_cast(bd) + end + + def test_type_cast_unknown_should_raise_error + obj = Class.new.new + assert_raise(TypeError) { @conn.type_cast(obj) } + end + + def test_type_cast_object_which_responds_to_quoted_id + quoted_id_obj = Class.new { + def quoted_id + "'zomg'" + end + + def id + 10 end - end + }.new + assert_equal 10, @conn.type_cast(quoted_id_obj) + + quoted_id_obj = Class.new { + def quoted_id + "'zomg'" + end + }.new + assert_raise(TypeError) { @conn.type_cast(quoted_id_obj) } + end + + def test_quoting_binary_strings + value = "hello".encode("ascii-8bit") + type = ActiveRecord::Type::String.new + + assert_equal "'hello'", @conn.quote(type.serialize(value)) + end + + def test_quoted_time_returns_date_qualified_time + value = ::Time.utc(2000, 1, 1, 12, 30, 0, 999999) + type = ActiveRecord::Type::Time.new + + assert_equal "'2000-01-01 12:30:00.999999'", @conn.quote(type.serialize(value)) end end diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb index bbc9f978bf..66f9349111 100644 --- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb @@ -1,7 +1,7 @@ require "cases/helper" -require 'models/owner' -require 'tempfile' -require 'support/ddl_helper' +require "models/owner" +require "tempfile" +require "support/ddl_helper" module ActiveRecord module ConnectionAdapters @@ -14,22 +14,22 @@ module ActiveRecord end def setup - @conn = Base.sqlite3_connection database: ':memory:', - adapter: 'sqlite3', + @conn = Base.sqlite3_connection database: ":memory:", + adapter: "sqlite3", timeout: 100 end def test_bad_connection assert_raise ActiveRecord::NoDatabaseError do connection = ActiveRecord::Base.sqlite3_connection(adapter: "sqlite3", database: "/tmp/should/_not/_exist/-cinco-dog.db") - connection.drop_table 'ex', if_exists: true + connection.drop_table "ex", if_exists: true end end unless in_memory_db? def test_connect_with_url original_connection = ActiveRecord::Base.remove_connection - tf = Tempfile.open 'whatever' + tf = Tempfile.open "whatever" url = "sqlite3:#{tf.path}" ActiveRecord::Base.establish_connection(url) assert ActiveRecord::Base.connection @@ -51,7 +51,7 @@ module ActiveRecord def test_valid_column with_example_table do - column = @conn.columns('ex').find { |col| col.name == 'id' } + column = @conn.columns("ex").find { |col| col.name == "id" } assert @conn.valid_type?(column.type) end end @@ -66,9 +66,9 @@ module ActiveRecord end def test_column_types - owner = Owner.create!(name: "hello".encode('ascii-8bit')) + owner = Owner.create!(name: "hello".encode("ascii-8bit")) owner.reload - select = Owner.columns.map { |c| "typeof(#{c.name})" }.join ', ' + select = Owner.columns.map { |c| "typeof(#{c.name})" }.join ", " result = Owner.connection.exec_query <<-esql SELECT #{select} FROM #{Owner.table_name} @@ -83,10 +83,10 @@ module ActiveRecord def test_exec_insert with_example_table do vals = [Relation::QueryAttribute.new("number", 10, Type::Value.new)] - @conn.exec_insert('insert into ex (number) VALUES (?)', 'SQL', vals) + @conn.exec_insert("insert into ex (number) VALUES (?)", "SQL", vals) result = @conn.exec_query( - 'select number from ex where number = ?', 'SQL', vals) + "select number from ex where number = ?", "SQL", vals) assert_equal 1, result.rows.length assert_equal 10, result.rows.first.first @@ -94,8 +94,8 @@ module ActiveRecord end def test_primary_key_returns_nil_for_no_pk - with_example_table 'id int, data string' do - assert_nil @conn.primary_key('ex') + with_example_table "id int, data string" do + assert_nil @conn.primary_key("ex") end end @@ -107,69 +107,69 @@ module ActiveRecord def test_bad_timeout assert_raises(TypeError) do - Base.sqlite3_connection database: ':memory:', - adapter: 'sqlite3', - timeout: 'usa' + Base.sqlite3_connection database: ":memory:", + adapter: "sqlite3", + timeout: "usa" end end # connection is OK with a nil timeout def test_nil_timeout - conn = Base.sqlite3_connection database: ':memory:', - adapter: 'sqlite3', + conn = Base.sqlite3_connection database: ":memory:", + adapter: "sqlite3", timeout: nil - assert conn, 'made a connection' + assert conn, "made a connection" end def test_connect - assert @conn, 'should have connection' + assert @conn, "should have connection" end # sqlite3 defaults to UTF-8 encoding def test_encoding - assert_equal 'UTF-8', @conn.encoding + assert_equal "UTF-8", @conn.encoding end def test_exec_no_binds - with_example_table 'id int, data string' do - result = @conn.exec_query('SELECT id, data FROM ex') + with_example_table "id int, data string" do + result = @conn.exec_query("SELECT id, data FROM ex") assert_equal 0, result.rows.length assert_equal 2, result.columns.length assert_equal %w{ id data }, result.columns @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') - result = @conn.exec_query('SELECT id, data FROM ex') + result = @conn.exec_query("SELECT id, data FROM ex") assert_equal 1, result.rows.length assert_equal 2, result.columns.length - assert_equal [[1, 'foo']], result.rows + assert_equal [[1, "foo"]], result.rows end end def test_exec_query_with_binds - with_example_table 'id int, data string' do + with_example_table "id int, data string" do @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') result = @conn.exec_query( - 'SELECT id, data FROM ex WHERE id = ?', nil, [Relation::QueryAttribute.new(nil, 1, Type::Value.new)]) + "SELECT id, data FROM ex WHERE id = ?", nil, [Relation::QueryAttribute.new(nil, 1, Type::Value.new)]) assert_equal 1, result.rows.length assert_equal 2, result.columns.length - assert_equal [[1, 'foo']], result.rows + assert_equal [[1, "foo"]], result.rows end end def test_exec_query_typecasts_bind_vals - with_example_table 'id int, data string' do + with_example_table "id int, data string" do @conn.exec_query('INSERT INTO ex (id, data) VALUES (1, "foo")') result = @conn.exec_query( - 'SELECT id, data FROM ex WHERE id = ?', nil, [Relation::QueryAttribute.new("id", "1-fuu", Type::Integer.new)]) + "SELECT id, data FROM ex WHERE id = ?", nil, [Relation::QueryAttribute.new("id", "1-fuu", Type::Integer.new)]) assert_equal 1, result.rows.length assert_equal 2, result.columns.length - assert_equal [[1, 'foo']], result.rows + assert_equal [[1, "foo"]], result.rows end end @@ -182,15 +182,15 @@ module ActiveRecord ) eosql str = "\x80".force_encoding("ASCII-8BIT") - binary = DualEncoding.new name: 'いただきます!', data: str + binary = DualEncoding.new name: "いただきます!", data: str binary.save! assert_equal str, binary.data ensure - DualEncoding.connection.drop_table 'dual_encodings', if_exists: true + DualEncoding.connection.drop_table "dual_encodings", if_exists: true end def test_type_cast_should_not_mutate_encoding - name = 'hello'.force_encoding(Encoding::ASCII_8BIT) + name = "hello".force_encoding(Encoding::ASCII_8BIT) Owner.create(name: name) assert_equal Encoding::ASCII_8BIT, name.encoding ensure @@ -204,8 +204,8 @@ module ActiveRecord assert_equal 1, records.length record = records.first - assert_equal 10, record['number'] - assert_equal 1, record['id'] + assert_equal 10, record["number"] + assert_equal 1, record["id"] end end @@ -226,7 +226,7 @@ module ActiveRecord def test_insert_id_value_returned with_example_table do sql = "INSERT INTO ex (number) VALUES (10)" - idval = 'vuvuzela' + idval = "vuvuzela" id = @conn.insert(sql, nil, nil, idval) assert_equal idval, id end @@ -237,7 +237,7 @@ module ActiveRecord 2.times do |i| @conn.create "INSERT INTO ex (number) VALUES (#{i})" end - rows = @conn.select_rows 'select number, id from ex' + rows = @conn.select_rows "select number, id from ex" assert_equal [[0, 1], [1, 2]], rows end end @@ -254,7 +254,7 @@ module ActiveRecord def test_transaction with_example_table do - count_sql = 'select count(*) from ex' + count_sql = "select count(*) from ex" @conn.begin_db_transaction @conn.create "INSERT INTO ex (number) VALUES (10)" @@ -268,7 +268,7 @@ module ActiveRecord def test_tables with_example_table do ActiveSupport::Deprecation.silence { assert_equal %w{ ex }, @conn.tables } - with_example_table 'id integer PRIMARY KEY AUTOINCREMENT, number integer', 'people' do + with_example_table "id integer PRIMARY KEY AUTOINCREMENT, number integer", "people" do ActiveSupport::Deprecation.silence { assert_equal %w{ ex people }.sort, @conn.tables.sort } end end @@ -279,17 +279,17 @@ module ActiveRecord SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence' SQL - assert_logged [[sql.squish, 'SCHEMA', []]] do + assert_logged [[sql.squish, "SCHEMA", []]] do ActiveSupport::Deprecation.silence do - @conn.tables('hello') + @conn.tables("hello") end end end def test_indexes_logs_name with_example_table do - assert_logged [["PRAGMA index_list(\"ex\")", 'SCHEMA', []]] do - @conn.indexes('ex', 'hello') + assert_logged [["PRAGMA index_list(\"ex\")", "SCHEMA", []]] do + @conn.indexes("ex", "hello") end end end @@ -300,9 +300,9 @@ module ActiveRecord SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence' AND name = 'ex' SQL - assert_logged [[sql.squish, 'SCHEMA', []]] do + assert_logged [[sql.squish, "SCHEMA", []]] do ActiveSupport::Deprecation.silence do - assert @conn.table_exists?('ex') + assert @conn.table_exists?("ex") end end end @@ -310,7 +310,7 @@ module ActiveRecord def test_columns with_example_table do - columns = @conn.columns('ex').sort_by(&:name) + columns = @conn.columns("ex").sort_by(&:name) assert_equal 2, columns.length assert_equal %w{ id number }.sort, columns.map(&:name) assert_equal [nil, nil], columns.map(&:default) @@ -319,17 +319,17 @@ module ActiveRecord end def test_columns_with_default - with_example_table 'id integer PRIMARY KEY AUTOINCREMENT, number integer default 10' do - column = @conn.columns('ex').find { |x| - x.name == 'number' + with_example_table "id integer PRIMARY KEY AUTOINCREMENT, number integer default 10" do + column = @conn.columns("ex").find { |x| + x.name == "number" } - assert_equal '10', column.default + assert_equal "10", column.default end end def test_columns_with_not_null - with_example_table 'id integer PRIMARY KEY AUTOINCREMENT, number integer not null' do - column = @conn.columns('ex').find { |x| x.name == 'number' } + with_example_table "id integer PRIMARY KEY AUTOINCREMENT, number integer not null" do + column = @conn.columns("ex").find { |x| x.name == "number" } assert_not column.null, "column should not be null" end end @@ -337,59 +337,59 @@ module ActiveRecord def test_indexes_logs with_example_table do assert_logged [["PRAGMA index_list(\"ex\")", "SCHEMA", []]] do - @conn.indexes('ex') + @conn.indexes("ex") end end end def test_no_indexes - assert_equal [], @conn.indexes('items') + assert_equal [], @conn.indexes("items") end def test_index with_example_table do - @conn.add_index 'ex', 'id', unique: true, name: 'fun' - index = @conn.indexes('ex').find { |idx| idx.name == 'fun' } + @conn.add_index "ex", "id", unique: true, name: "fun" + index = @conn.indexes("ex").find { |idx| idx.name == "fun" } - assert_equal 'ex', index.table - assert index.unique, 'index is unique' - assert_equal ['id'], index.columns + assert_equal "ex", index.table + assert index.unique, "index is unique" + assert_equal ["id"], index.columns end end def test_non_unique_index with_example_table do - @conn.add_index 'ex', 'id', name: 'fun' - index = @conn.indexes('ex').find { |idx| idx.name == 'fun' } - assert_not index.unique, 'index is not unique' + @conn.add_index "ex", "id", name: "fun" + index = @conn.indexes("ex").find { |idx| idx.name == "fun" } + assert_not index.unique, "index is not unique" end end def test_compound_index with_example_table do - @conn.add_index 'ex', %w{ id number }, name: 'fun' - index = @conn.indexes('ex').find { |idx| idx.name == 'fun' } + @conn.add_index "ex", %w{ id number }, name: "fun" + index = @conn.indexes("ex").find { |idx| idx.name == "fun" } assert_equal %w{ id number }.sort, index.columns.sort end end def test_primary_key with_example_table do - assert_equal 'id', @conn.primary_key('ex') - with_example_table 'internet integer PRIMARY KEY AUTOINCREMENT, number integer not null', 'foos' do - assert_equal 'internet', @conn.primary_key('foos') + assert_equal "id", @conn.primary_key("ex") + with_example_table "internet integer PRIMARY KEY AUTOINCREMENT, number integer not null", "foos" do + assert_equal "internet", @conn.primary_key("foos") end end end def test_no_primary_key - with_example_table 'number integer not null' do - assert_nil @conn.primary_key('ex') + with_example_table "number integer not null" do + assert_nil @conn.primary_key("ex") end end def test_supports_extensions - assert_not @conn.supports_extensions?, 'does not support extensions' + assert_not @conn.supports_extensions?, "does not support extensions" end def test_respond_to_enable_extension @@ -402,15 +402,15 @@ module ActiveRecord def test_statement_closed db = ::SQLite3::Database.new(ActiveRecord::Base. - configurations['arunit']['database']) + configurations["arunit"]["database"]) statement = ::SQLite3::Statement.new(db, - 'CREATE TABLE statement_test (number integer not null)') - statement.stub(:step, ->{ raise ::SQLite3::BusyException.new('busy') }) do + "CREATE TABLE statement_test (number integer not null)") + statement.stub(:step, -> { raise ::SQLite3::BusyException.new("busy") }) do assert_called(statement, :columns, returns: []) do assert_called(statement, :close) do ::SQLite3::Statement.stub(:new, statement) do assert_raises ActiveRecord::StatementInvalid do - @conn.exec_query 'select * from statement_test' + @conn.exec_query "select * from statement_test" end end end @@ -420,22 +420,22 @@ module ActiveRecord private - def assert_logged logs - subscriber = SQLSubscriber.new - subscription = ActiveSupport::Notifications.subscribe('sql.active_record', subscriber) - yield - assert_equal logs, subscriber.logged - ensure - ActiveSupport::Notifications.unsubscribe(subscription) - end + def assert_logged(logs) + subscriber = SQLSubscriber.new + subscription = ActiveSupport::Notifications.subscribe("sql.active_record", subscriber) + yield + assert_equal logs, subscriber.logged + ensure + ActiveSupport::Notifications.unsubscribe(subscription) + end - def with_example_table(definition = nil, table_name = 'ex', &block) - definition ||= <<-SQL - id integer PRIMARY KEY AUTOINCREMENT, - number integer - SQL - super(@conn, table_name, definition, &block) - end + def with_example_table(definition = nil, table_name = "ex", &block) + definition ||= <<-SQL + id integer PRIMARY KEY AUTOINCREMENT, + number integer + SQL + super(@conn, table_name, definition, &block) + end end end end diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb index 9b675b804b..b1b4463bf1 100644 --- a/activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'models/owner' +require "models/owner" module ActiveRecord module ConnectionAdapters @@ -8,12 +8,12 @@ module ActiveRecord Dir.mktmpdir do |dir| begin dir = Pathname.new(dir) - @conn = Base.sqlite3_connection :database => dir.join("db/foo.sqlite3"), - :adapter => 'sqlite3', - :timeout => 100 + @conn = Base.sqlite3_connection database: dir.join("db/foo.sqlite3"), + adapter: "sqlite3", + timeout: 100 - assert Dir.exist? dir.join('db') - assert File.exist? dir.join('db/foo.sqlite3') + assert Dir.exist? dir.join("db") + assert File.exist? dir.join("db/foo.sqlite3") ensure @conn.disconnect! if @conn end diff --git a/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb b/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb index 559b951109..aebcce3691 100644 --- a/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb @@ -1,24 +1,20 @@ -require 'cases/helper' +require "cases/helper" -module ActiveRecord::ConnectionAdapters - class SQLite3Adapter - class StatementPoolTest < ActiveRecord::SQLite3TestCase - if Process.respond_to?(:fork) - def test_cache_is_per_pid +class SQLite3StatementPoolTest < ActiveRecord::SQLite3TestCase + if Process.respond_to?(:fork) + def test_cache_is_per_pid - cache = StatementPool.new(10) - cache['foo'] = 'bar' - assert_equal 'bar', cache['foo'] + cache = ActiveRecord::ConnectionAdapters::SQLite3Adapter::StatementPool.new(10) + cache["foo"] = "bar" + assert_equal "bar", cache["foo"] - pid = fork { - lookup = cache['foo']; - exit!(!lookup) - } + pid = fork { + lookup = cache["foo"]; + exit!(!lookup) + } - Process.waitpid pid - assert $?.success?, 'process should exit successfully' - end - end + Process.waitpid pid + assert $?.success?, "process should exit successfully" end end end diff --git a/activerecord/test/cases/aggregations_test.rb b/activerecord/test/cases/aggregations_test.rb index 5536702f58..f8136fde72 100644 --- a/activerecord/test/cases/aggregations_test.rb +++ b/activerecord/test/cases/aggregations_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'models/customer' +require "models/customer" class AggregationsTest < ActiveRecord::TestCase fixtures :customers @@ -51,17 +51,17 @@ class AggregationsTest < ActiveRecord::TestCase Customer.update_all("gps_location = '24x113'") customers(:david).reload - assert_equal '24x113', customers(:david)['gps_location'] + assert_equal "24x113", customers(:david)["gps_location"] - assert_equal GpsLocation.new('24x113'), customers(:david).gps_location + assert_equal GpsLocation.new("24x113"), customers(:david).gps_location end def test_gps_equality - assert_equal GpsLocation.new('39x110'), GpsLocation.new('39x110') + assert_equal GpsLocation.new("39x110"), GpsLocation.new("39x110") end def test_gps_inequality - assert_not_equal GpsLocation.new('39x110'), GpsLocation.new('39x111') + assert_not_equal GpsLocation.new("39x110"), GpsLocation.new("39x111") end def test_allow_nil_gps_is_nil @@ -102,7 +102,7 @@ class AggregationsTest < ActiveRecord::TestCase end def test_nil_assignment_results_in_nil - customers(:david).gps_location = GpsLocation.new('39x111') + customers(:david).gps_location = GpsLocation.new("39x111") assert_not_nil customers(:david).gps_location customers(:david).gps_location = nil assert_nil customers(:david).gps_location @@ -129,26 +129,36 @@ class AggregationsTest < ActiveRecord::TestCase end def test_custom_constructor - assert_equal 'Barney GUMBLE', customers(:barney).fullname.to_s + assert_equal "Barney GUMBLE", customers(:barney).fullname.to_s assert_kind_of Fullname, customers(:barney).fullname end def test_custom_converter - customers(:barney).fullname = 'Barnoit Gumbleau' - assert_equal 'Barnoit GUMBLEAU', customers(:barney).fullname.to_s + customers(:barney).fullname = "Barnoit Gumbleau" + assert_equal "Barnoit GUMBLEAU", customers(:barney).fullname.to_s assert_kind_of Fullname, customers(:barney).fullname end + + def test_assigning_hash_to_custom_converter + customers(:barney).fullname = { first: "Barney", last: "Stinson" } + assert_equal "Barney STINSON", customers(:barney).name + end + + def test_assigning_hash_without_custom_converter + customers(:barney).fullname_no_converter = { first: "Barney", last: "Stinson" } + assert_equal({ first: "Barney", last: "Stinson" }.to_s, customers(:barney).name) + end end class OverridingAggregationsTest < ActiveRecord::TestCase class DifferentName; end class Person < ActiveRecord::Base - composed_of :composed_of, :mapping => %w(person_first_name first_name) + composed_of :composed_of, mapping: %w(person_first_name first_name) end class DifferentPerson < Person - composed_of :composed_of, :class_name => 'DifferentName', :mapping => %w(different_person_first_name first_name) + composed_of :composed_of, class_name: "DifferentName", mapping: %w(different_person_first_name first_name) end def test_composed_of_aggregation_redefinition_reflections_should_differ_and_not_inherited diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb index 9c99689c1e..e3eccad71f 100644 --- a/activerecord/test/cases/ar_schema_test.rb +++ b/activerecord/test/cases/ar_schema_test.rb @@ -17,6 +17,7 @@ if ActiveRecord::Base.connection.supports_migrations? @connection.drop_table :nep_fruits rescue nil @connection.drop_table :nep_schema_migrations rescue nil @connection.drop_table :has_timestamps rescue nil + @connection.drop_table :multiple_indexes rescue nil ActiveRecord::SchemaMigration.delete_all rescue nil ActiveRecord::Migration.verbose = @original_verbose end @@ -36,7 +37,7 @@ if ActiveRecord::Base.connection.supports_migrations? end def test_schema_define - ActiveRecord::Schema.define(:version => 7) do + ActiveRecord::Schema.define(version: 7) do create_table :fruits do |t| t.column :color, :string t.column :fruit_size, :string # NOTE: "size" is reserved in Oracle @@ -55,7 +56,7 @@ if ActiveRecord::Base.connection.supports_migrations? old_table_name_prefix = ActiveRecord::Base.table_name_prefix ActiveRecord::Base.table_name_prefix = "nep_" ActiveRecord::SchemaMigration.table_name = "nep_#{table_name}" - ActiveRecord::Schema.define(:version => 7) do + ActiveRecord::Schema.define(version: 7) do create_table :fruits do |t| t.column :color, :string t.column :fruit_size, :string # NOTE: "size" is reserved in Oracle @@ -71,7 +72,7 @@ if ActiveRecord::Base.connection.supports_migrations? def test_schema_raises_an_error_for_invalid_column_type assert_raise NoMethodError do - ActiveRecord::Schema.define(:version => 8) do + ActiveRecord::Schema.define(version: 8) do create_table :vegetables do |t| t.unknown :color end @@ -80,7 +81,7 @@ if ActiveRecord::Base.connection.supports_migrations? end def test_schema_subclass - Class.new(ActiveRecord::Schema).define(:version => 9) do + Class.new(ActiveRecord::Schema).define(version: 9) do create_table :fruits end assert_nothing_raised { @connection.select_all "SELECT * FROM fruits" } @@ -93,6 +94,21 @@ if ActiveRecord::Base.connection.supports_migrations? assert_equal "20131219224947", ActiveRecord::SchemaMigration.normalize_migration_number("20131219224947") end + def test_schema_load_with_multiple_indexes_for_column_of_different_names + ActiveRecord::Schema.define do + create_table :multiple_indexes do |t| + t.string "foo" + t.index ["foo"], name: "multiple_indexes_foo_1" + t.index ["foo"], name: "multiple_indexes_foo_2" + end + end + + indexes = @connection.indexes("multiple_indexes") + + assert_equal 2, indexes.length + assert_equal ["multiple_indexes_foo_1", "multiple_indexes_foo_2"], indexes.collect(&:name).sort + end + def test_timestamps_without_null_set_null_to_false_on_create_table ActiveRecord::Schema.define do create_table :has_timestamps do |t| @@ -100,8 +116,8 @@ if ActiveRecord::Base.connection.supports_migrations? end end - assert !@connection.columns(:has_timestamps).find { |c| c.name == 'created_at' }.null - assert !@connection.columns(:has_timestamps).find { |c| c.name == 'updated_at' }.null + assert !@connection.columns(:has_timestamps).find { |c| c.name == "created_at" }.null + assert !@connection.columns(:has_timestamps).find { |c| c.name == "updated_at" }.null end def test_timestamps_without_null_set_null_to_false_on_change_table @@ -113,8 +129,8 @@ if ActiveRecord::Base.connection.supports_migrations? end end - assert !@connection.columns(:has_timestamps).find { |c| c.name == 'created_at' }.null - assert !@connection.columns(:has_timestamps).find { |c| c.name == 'updated_at' }.null + assert !@connection.columns(:has_timestamps).find { |c| c.name == "created_at" }.null + assert !@connection.columns(:has_timestamps).find { |c| c.name == "updated_at" }.null end def test_timestamps_without_null_set_null_to_false_on_add_timestamps @@ -123,8 +139,8 @@ if ActiveRecord::Base.connection.supports_migrations? add_timestamps :has_timestamps, default: Time.now end - assert !@connection.columns(:has_timestamps).find { |c| c.name == 'created_at' }.null - assert !@connection.columns(:has_timestamps).find { |c| c.name == 'updated_at' }.null + assert !@connection.columns(:has_timestamps).find { |c| c.name == "created_at" }.null + assert !@connection.columns(:has_timestamps).find { |c| c.name == "updated_at" }.null end end end diff --git a/activerecord/test/cases/associations/association_scope_test.rb b/activerecord/test/cases/associations/association_scope_test.rb index 472e270f8c..c322333f6d 100644 --- a/activerecord/test/cases/associations/association_scope_test.rb +++ b/activerecord/test/cases/associations/association_scope_test.rb @@ -1,11 +1,11 @@ -require 'cases/helper' -require 'models/post' -require 'models/author' +require "cases/helper" +require "models/post" +require "models/author" module ActiveRecord module Associations class AssociationScopeTest < ActiveRecord::TestCase - test 'does not duplicate conditions' do + test "does not duplicate conditions" do scope = AssociationScope.scope(Author.new.association(:welcome_posts), Author.connection) binds = scope.where_clause.binds.map(&:value) diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index a3046d526e..2418346d1b 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -1,28 +1,28 @@ -require 'cases/helper' -require 'models/developer' -require 'models/project' -require 'models/company' -require 'models/topic' -require 'models/reply' -require 'models/computer' -require 'models/post' -require 'models/author' -require 'models/tag' -require 'models/tagging' -require 'models/comment' -require 'models/sponsor' -require 'models/member' -require 'models/essay' -require 'models/toy' -require 'models/invoice' -require 'models/line_item' -require 'models/column' -require 'models/record' -require 'models/admin' -require 'models/admin/user' -require 'models/ship' -require 'models/treasure' -require 'models/parrot' +require "cases/helper" +require "models/developer" +require "models/project" +require "models/company" +require "models/topic" +require "models/reply" +require "models/computer" +require "models/post" +require "models/author" +require "models/tag" +require "models/tagging" +require "models/comment" +require "models/sponsor" +require "models/member" +require "models/essay" +require "models/toy" +require "models/invoice" +require "models/line_item" +require "models/column" +require "models/record" +require "models/admin" +require "models/admin/user" +require "models/ship" +require "models/treasure" +require "models/parrot" class BelongsToAssociationsTest < ActiveRecord::TestCase fixtures :accounts, :companies, :developers, :projects, :topics, @@ -43,11 +43,11 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase ActiveRecord::SQLCounter.clear_log Client.find(3).firm ensure - assert ActiveRecord::SQLCounter.log_all.all? { |sql| /order by/i !~ sql }, 'ORDER BY was used in the query' + assert ActiveRecord::SQLCounter.log_all.all? { |sql| /order by/i !~ sql }, "ORDER BY was used in the query" end def test_belongs_to_with_primary_key - client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name) + client = Client.create(name: "Primary key client", firm_name: companies(:first_firm).name) assert_equal companies(:first_firm).name, client.firm_with_primary_key.name end @@ -94,7 +94,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase account = model.new assert_not account.valid? - assert_equal [{error: :blank}], account.errors.details[:company] + assert_equal [{ error: :blank }], account.errors.details[:company] ensure ActiveRecord::Base.belongs_to_required_by_default = original_value end @@ -111,7 +111,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase account = model.new assert_not account.valid? - assert_equal [{error: :blank}], account.errors.details[:company] + assert_equal [{ error: :blank }], account.errors.details[:company] ensure ActiveRecord::Base.belongs_to_required_by_default = original_value end @@ -120,21 +120,21 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase counter = 0 comments = Class.new(ActiveRecord::Base) { - self.table_name = 'comments' - self.inheritance_column = 'not_there' + self.table_name = "comments" + self.inheritance_column = "not_there" posts = Class.new(ActiveRecord::Base) { - self.table_name = 'posts' - self.inheritance_column = 'not_there' + self.table_name = "posts" + self.inheritance_column = "not_there" default_scope -> { counter += 1 - where("id = :inc", :inc => counter) + where("id = :inc", inc: counter) } - has_many :comments, :anonymous_class => comments + has_many :comments, anonymous_class: comments } - belongs_to :post, :anonymous_class => posts, :inverse_of => false + belongs_to :post, anonymous_class: posts, inverse_of: false } assert_equal 0, counter @@ -166,9 +166,9 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase Admin.const_set "Region", Class.new(ActiveRecord::Base) e = assert_raise(ActiveRecord::AssociationTypeMismatch) { - Admin::RegionalUser.new(region: 'wrong value') + Admin::RegionalUser.new(region: "wrong value") } - assert_match(/^Region\([^)]+\) expected, got String\([^)]+\)$/, e.message) + assert_match(/^Region\([^)]+\) expected, got "wrong value" which is an instance of String\([^)]+\)$/, e.message) ensure Admin.send :remove_const, "Region" if Admin.const_defined?("Region") Admin.send :remove_const, "RegionalUser" if Admin.const_defined?("RegionalUser") @@ -203,14 +203,14 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_eager_loading_with_primary_key Firm.create("name" => "Apple") Client.create("name" => "Citibank", :firm_name => "Apple") - citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key).first + citibank_result = Client.all.merge!(where: { name: "Citibank" }, includes: :firm_with_primary_key).first assert citibank_result.association(:firm_with_primary_key).loaded? end def test_eager_loading_with_primary_key_as_symbol Firm.create("name" => "Apple") Client.create("name" => "Citibank", :firm_name => "Apple") - citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key_symbols).first + citibank_result = Client.all.merge!(where: { name: "Citibank" }, includes: :firm_with_primary_key_symbols).first assert citibank_result.association(:firm_with_primary_key_symbols).loaded? end @@ -224,7 +224,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_creating_the_belonging_object_with_primary_key - client = Client.create(:name => "Primary key client") + client = Client.create(name: "Primary key client") apple = client.create_firm_with_primary_key("name" => "Apple") assert_equal apple, client.firm_with_primary_key client.save @@ -247,36 +247,36 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_building_the_belonging_object_with_explicit_sti_base_class account = Account.new - company = account.build_firm(:type => "Company") + company = account.build_firm(type: "Company") assert_kind_of Company, company, "Expected #{company.class} to be a Company" end def test_building_the_belonging_object_with_sti_subclass account = Account.new - company = account.build_firm(:type => "Firm") + company = account.build_firm(type: "Firm") assert_kind_of Firm, company, "Expected #{company.class} to be a Firm" end def test_building_the_belonging_object_with_an_invalid_type account = Account.new - assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(:type => "InvalidType") } + assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(type: "InvalidType") } end def test_building_the_belonging_object_with_an_unrelated_type account = Account.new - assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(:type => "Account") } + assert_raise(ActiveRecord::SubclassNotFound) { account.build_firm(type: "Account") } end def test_building_the_belonging_object_with_primary_key - client = Client.create(:name => "Primary key client") + client = Client.create(name: "Primary key client") apple = client.build_firm_with_primary_key("name" => "Apple") client.save assert_equal apple.name, client.firm_name end def test_create! - client = Client.create!(:name => "Jimmy") - account = client.create_account!(:credit_limit => 10) + client = Client.create!(name: "Jimmy") + account = client.create_account!(credit_limit: 10) assert_equal account, client.account assert account.persisted? client.save @@ -285,7 +285,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_failing_create! - client = Client.create!(:name => "Jimmy") + client = Client.create!(name: "Jimmy") assert_raise(ActiveRecord::RecordInvalid) { client.create_account! } assert_not_nil client.account assert client.account.new_record? @@ -301,7 +301,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_natural_assignment_to_nil_with_primary_key - client = Client.create(:name => "Primary key client", :firm_name => companies(:first_firm).name) + client = Client.create(name: "Primary key client", firm_name: companies(:first_firm).name) client.firm_with_primary_key = nil client.save client.association(:firm_with_primary_key).reload @@ -325,19 +325,19 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase sponsor.association(:sponsorable).reload assert_nil sponsor.sponsorable - sponsor.sponsorable_type = '' # the column doesn't have to be declared NOT NULL + sponsor.sponsorable_type = "" # the column doesn't have to be declared NOT NULL assert_nil sponsor.association(:sponsorable).send(:klass) sponsor.association(:sponsorable).reload assert_nil sponsor.sponsorable - sponsor.sponsorable = Member.new :name => "Bert" + sponsor.sponsorable = Member.new name: "Bert" assert_equal Member, sponsor.association(:sponsorable).send(:klass) assert_equal "members", sponsor.association(:sponsorable).aliased_table_name end def test_with_polymorphic_and_condition sponsor = Sponsor.create - member = Member.create :name => "Bert" + member = Member.create name: "Bert" sponsor.sponsorable = member assert_equal member, sponsor.sponsorable @@ -346,16 +346,16 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_with_select assert_equal 1, Company.find(2).firm_with_select.attributes.size - assert_equal 1, Company.all.merge!(:includes => :firm_with_select ).find(2).firm_with_select.attributes.size + assert_equal 1, Company.all.merge!(includes: :firm_with_select ).find(2).firm_with_select.attributes.size end def test_belongs_to_without_counter_cache_option # Ship has a conventionally named `treasures_count` column, but the counter_cache # option is not given on the association. - ship = Ship.create(name: 'Countless') + ship = Ship.create(name: "Countless") assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed unless counter_cache is given on the relation" do - treasure = Treasure.new(name: 'Gold', ship: ship) + treasure = Treasure.new(name: "Gold", ship: ship) treasure.save end @@ -461,8 +461,8 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_belongs_to_counter_after_save - topic = Topic.create!(:title => "monday night") - topic.replies.create!(:title => "re: monday night", :content => "football") + topic = Topic.create!(title: "monday night") + topic.replies.create!(title: "re: monday night", content: "football") assert_equal 1, Topic.find(topic.id)[:replies_count] topic.save! @@ -564,8 +564,8 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_belongs_to_counter_when_update_columns - topic = Topic.create!(:title => "37s") - topic.replies.create!(:title => "re: 37s", :content => "rails") + topic = Topic.create!(title: "37s") + topic.replies.create!(title: "re: 37s", content: "rails") assert_equal 1, Topic.find(topic.id)[:replies_count] topic.update_columns(content: "rails is wonderful") @@ -601,7 +601,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_new_record_with_foreign_key_but_no_object client = Client.new("firm_id" => 1) # sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first - assert_equal Firm.all.merge!(:order => "id").first, client.firm_with_basic_id + assert_equal Firm.all.merge!(order: "id").first, client.firm_with_basic_id end def test_setting_foreign_key_after_nil_target_loaded @@ -626,16 +626,22 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_queries(0) { tagging.super_tag } end + def test_dont_find_target_when_saving_foreign_key_after_stale_association_loaded + client = Client.create!(name: "Test client", firm_with_basic_id: Firm.find(1)) + client.firm_id = Firm.create!(name: "Test firm").id + assert_queries(1) { client.save! } + end + def test_field_name_same_as_foreign_key computer = Computer.find(1) assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # ' end def test_counter_cache - topic = Topic.create :title => "Zoom-zoom-zoom" + topic = Topic.create title: "Zoom-zoom-zoom" assert_equal 0, topic[:replies_count] - reply = Reply.create(:title => "re: zoom", :content => "speedy quick!") + reply = Reply.create(title: "re: zoom", content: "speedy quick!") reply.topic = topic assert_equal 1, topic.reload[:replies_count] @@ -646,10 +652,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_counter_cache_double_destroy - topic = Topic.create :title => "Zoom-zoom-zoom" + topic = Topic.create title: "Zoom-zoom-zoom" 5.times do - topic.replies.create(:title => "re: zoom", :content => "speedy quick!") + topic.replies.create(title: "re: zoom", content: "speedy quick!") end assert_equal 5, topic.reload[:replies_count] @@ -666,10 +672,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_concurrent_counter_cache_double_destroy - topic = Topic.create :title => "Zoom-zoom-zoom" + topic = Topic.create title: "Zoom-zoom-zoom" 5.times do - topic.replies.create(:title => "re: zoom", :content => "speedy quick!") + topic.replies.create(title: "re: zoom", content: "speedy quick!") end assert_equal 5, topic.reload[:replies_count] @@ -687,10 +693,10 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_custom_counter_cache - reply = Reply.create(:title => "re: zoom", :content => "speedy quick!") + reply = Reply.create(title: "re: zoom", content: "speedy quick!") assert_equal 0, reply[:replies_count] - silly = SillyReply.create(:title => "gaga", :content => "boo-boo") + silly = SillyReply.create(title: "gaga", content: "boo-boo") silly.reply = reply assert_equal 1, reply.reload[:replies_count] @@ -700,10 +706,21 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal 17, reply.replies.size end + def test_replace_counter_cache + topic = Topic.create(title: "Zoom-zoom-zoom") + reply = Reply.create(title: "re: zoom", content: "speedy quick!") + + reply.topic = topic + reply.save + topic.reload + + assert_equal 1, topic.replies_count + end + def test_association_assignment_sticks post = Post.first - author1, author2 = Author.all.merge!(:limit => 2).to_a + author1, author2 = Author.all.merge!(limit: 2).to_a assert_not_nil author1 assert_not_nil author2 @@ -756,7 +773,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_polymorphic_assignment_with_primary_key_foreign_type_field_updating # should update when assigning a saved record essay = Essay.new - writer = Author.create(:name => "David") + writer = Author.create(name: "David") essay.writer = writer assert_equal "Author", essay.writer_type @@ -781,7 +798,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_assignment_updates_foreign_id_field_for_new_and_saved_records client = Client.new - saved_firm = Firm.create :name => "Saved" + saved_firm = Firm.create name: "Saved" new_firm = Firm.new client.firm = saved_firm @@ -793,7 +810,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_polymorphic_assignment_with_primary_key_updates_foreign_id_field_for_new_and_saved_records essay = Essay.new - saved_writer = Author.create(:name => "David") + saved_writer = Author.create(name: "David") new_writer = Author.new essay.writer = saved_writer @@ -809,7 +826,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_nil essay.writer_type essay.writer_id = 1 - essay.writer_type = 'Author' + essay.writer_type = "Author" essay.writer = nil assert_nil essay.writer_id @@ -831,14 +848,14 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_nothing_raised do Account.find(@account.id).save! - Account.all.merge!(:includes => :firm).find(@account.id).save! + Account.all.merge!(includes: :firm).find(@account.id).save! end @account.firm.delete assert_nothing_raised do Account.find(@account.id).save! - Account.all.merge!(:includes => :firm).find(@account.id).save! + Account.all.merge!(includes: :firm).find(@account.id).save! end end @@ -859,18 +876,18 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_belongs_to_invalid_dependent_option_raises_exception error = assert_raise ArgumentError do - Class.new(Author).belongs_to :special_author_address, :dependent => :nullify + Class.new(Author).belongs_to :special_author_address, dependent: :nullify end - assert_equal error.message, 'The :dependent option must be one of [:destroy, :delete], but is :nullify' + assert_equal error.message, "The :dependent option must be one of [:destroy, :delete], but is :nullify" end def test_attributes_are_being_set_when_initialized_from_belongs_to_association_with_where_clause - new_firm = accounts(:signals37).build_firm(:name => 'Apple') + new_firm = accounts(:signals37).build_firm(name: "Apple") assert_equal new_firm.name, "Apple" end def test_attributes_are_set_without_error_when_initialized_from_belongs_to_association_with_array_in_where_clause - new_account = Account.where(:credit_limit => [ 50, 60 ]).new + new_account = Account.where(credit_limit: [ 50, 60 ]).new assert_nil new_account.credit_limit end @@ -919,7 +936,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert !proxy.stale_target? assert_equal members(:groucho), sponsor.sponsorable - sponsor.sponsorable_type = 'Firm' + sponsor.sponsorable_type = "Firm" assert proxy.stale_target? assert_equal companies(:first_firm), sponsor.sponsorable @@ -944,7 +961,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase comment = comments(:greetings) assert_difference lambda { post.reload.tags_count }, -1 do - assert_difference 'comment.reload.tags_count', +1 do + assert_difference "comment.reload.tags_count", +1 do tagging.taggable = comment end end @@ -991,42 +1008,42 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_build_with_block - client = Client.create(:name => 'Client Company') + client = Client.create(name: "Client Company") - firm = client.build_firm{ |f| f.name = 'Agency Company' } - assert_equal 'Agency Company', firm.name + firm = client.build_firm { |f| f.name = "Agency Company" } + assert_equal "Agency Company", firm.name end def test_create_with_block - client = Client.create(:name => 'Client Company') + client = Client.create(name: "Client Company") - firm = client.create_firm{ |f| f.name = 'Agency Company' } - assert_equal 'Agency Company', firm.name + firm = client.create_firm { |f| f.name = "Agency Company" } + assert_equal "Agency Company", firm.name end def test_create_bang_with_block - client = Client.create(:name => 'Client Company') + client = Client.create(name: "Client Company") - firm = client.create_firm!{ |f| f.name = 'Agency Company' } - assert_equal 'Agency Company', firm.name + firm = client.create_firm! { |f| f.name = "Agency Company" } + assert_equal "Agency Company", firm.name end def test_should_set_foreign_key_on_create_association - client = Client.create! :name => "fuu" + client = Client.create! name: "fuu" - firm = client.create_firm :name => "baa" + firm = client.create_firm name: "baa" assert_equal firm.id, client.client_of end def test_should_set_foreign_key_on_create_association! - client = Client.create! :name => "fuu" + client = Client.create! name: "fuu" - firm = client.create_firm! :name => "baa" + firm = client.create_firm! name: "baa" assert_equal firm.id, client.client_of end def test_self_referential_belongs_to_with_counter_cache_assigning_nil - comment = Comment.create! :post => posts(:thinking), :body => "fuu" + comment = Comment.create! post: posts(:thinking), body: "fuu" comment.parent = nil comment.save! @@ -1047,7 +1064,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_polymorphic_with_custom_primary_key toy = Toy.create! - sponsor = Sponsor.create!(:sponsorable => toy) + sponsor = Sponsor.create!(sponsorable: toy) assert_equal toy, sponsor.reload.sponsorable end @@ -1066,7 +1083,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase def test_reflect_the_most_recent_change author1, author2 = Author.limit(2) - post = Post.new(:title => "foo", :body=> "bar") + post = Post.new(title: "foo", body: "bar") post.author = author1 post.author_id = author2.id @@ -1075,8 +1092,8 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal post.author_id, author2.id end - test 'dangerous association name raises ArgumentError' do - [:errors, 'errors', :save, 'save'].each do |name| + test "dangerous association name raises ArgumentError" do + [:errors, "errors", :save, "save"].each do |name| assert_raises(ArgumentError, "Association #{name} should not be allowed") do Class.new(ActiveRecord::Base) do belongs_to name @@ -1085,7 +1102,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end end - test 'belongs_to works with model called Record' do + test "belongs_to works with model called Record" do record = Record.create! Column.create! record: record assert_equal 1, Column.count diff --git a/activerecord/test/cases/associations/bidirectional_destroy_dependencies_test.rb b/activerecord/test/cases/associations/bidirectional_destroy_dependencies_test.rb index 2b867965ba..8a0e041864 100644 --- a/activerecord/test/cases/associations/bidirectional_destroy_dependencies_test.rb +++ b/activerecord/test/cases/associations/bidirectional_destroy_dependencies_test.rb @@ -1,5 +1,5 @@ -require 'cases/helper' -require 'models/content' +require "cases/helper" +require "models/content" class BidirectionalDestroyDependenciesTest < ActiveRecord::TestCase fixtures :content, :content_positions diff --git a/activerecord/test/cases/associations/callbacks_test.rb b/activerecord/test/cases/associations/callbacks_test.rb index a4298a25a6..2f62d0367e 100644 --- a/activerecord/test/cases/associations/callbacks_test.rb +++ b/activerecord/test/cases/associations/callbacks_test.rb @@ -1,10 +1,10 @@ require "cases/helper" -require 'models/post' -require 'models/author' -require 'models/project' -require 'models/developer' -require 'models/computer' -require 'models/company' +require "models/post" +require "models/author" +require "models/project" +require "models/developer" +require "models/computer" +require "models/company" class AssociationCallbacksTest < ActiveRecord::TestCase fixtures :posts, :authors, :projects, :developers @@ -61,20 +61,20 @@ class AssociationCallbacksTest < ActiveRecord::TestCase end def test_has_many_callbacks_with_create - morten = Author.create :name => "Morten" - post = morten.posts_with_proc_callbacks.create! :title => "Hello", :body => "How are you doing?" + morten = Author.create name: "Morten" + post = morten.posts_with_proc_callbacks.create! title: "Hello", body: "How are you doing?" assert_equal ["before_adding<new>", "after_adding#{post.id}"], morten.post_log end def test_has_many_callbacks_with_create! - morten = Author.create! :name => "Morten" - post = morten.posts_with_proc_callbacks.create :title => "Hello", :body => "How are you doing?" + morten = Author.create! name: "Morten" + post = morten.posts_with_proc_callbacks.create title: "Hello", body: "How are you doing?" assert_equal ["before_adding<new>", "after_adding#{post.id}"], morten.post_log end def test_has_many_callbacks_for_save_on_parent - jack = Author.new :name => "Jack" - jack.posts_with_callbacks.build :title => "Call me back!", :body => "Before you wake up and after you sleep" + jack = Author.new name: "Jack" + jack.posts_with_callbacks.build title: "Call me back!", body: "Before you wake up and after you sleep" callback_log = ["before_adding<new>", "after_adding#{jack.posts_with_callbacks.first.id}"] assert_equal callback_log, jack.post_log @@ -84,8 +84,8 @@ class AssociationCallbacksTest < ActiveRecord::TestCase end def test_has_many_callbacks_for_destroy_on_parent - firm = Firm.create! :name => "Firm" - client = firm.clients.create! :name => "Client" + firm = Firm.create! name: "Firm" + client = firm.clients.create! name: "Client" firm.destroy assert_equal ["before_remove#{client.id}", "after_remove#{client.id}"], firm.log @@ -108,14 +108,14 @@ class AssociationCallbacksTest < ActiveRecord::TestCase klass = Class.new(Project) do def self.name; Project.name; end has_and_belongs_to_many :developers_with_callbacks, - :class_name => "Developer", - :before_add => lambda { |o,r| + class_name: "Developer", + before_add: lambda { |o,r| dev = r new_dev = r.new_record? } end rec = klass.create! - alice = Developer.new(:name => 'alice') + alice = Developer.new(name: "alice") rec.developers_with_callbacks << alice assert_equal alice, dev assert_not_nil new_dev @@ -126,18 +126,17 @@ class AssociationCallbacksTest < ActiveRecord::TestCase def test_has_and_belongs_to_many_after_add_called_after_save ar = projects(:active_record) assert ar.developers_log.empty? - alice = Developer.new(:name => 'alice') + alice = Developer.new(name: "alice") ar.developers_with_callbacks << alice assert_equal"after_adding#{alice.id}", ar.developers_log.last - bob = ar.developers_with_callbacks.create(:name => 'bob') + bob = ar.developers_with_callbacks.create(name: "bob") assert_equal "after_adding#{bob.id}", ar.developers_log.last - ar.developers_with_callbacks.build(:name => 'charlie') + ar.developers_with_callbacks.build(name: "charlie") assert_equal "after_adding<new>", ar.developers_log.last end - def test_has_and_belongs_to_many_remove_callback david = developers(:david) jamis = developers(:jamis) @@ -160,14 +159,14 @@ class AssociationCallbacksTest < ActiveRecord::TestCase activerecord.reload assert activerecord.developers_with_callbacks.size == 2 end - activerecord.developers_with_callbacks.flat_map {|d| ["before_removing#{d.id}","after_removing#{d.id}"]}.sort + activerecord.developers_with_callbacks.flat_map { |d| ["before_removing#{d.id}","after_removing#{d.id}"] }.sort assert activerecord.developers_with_callbacks.clear assert_predicate activerecord.developers_log, :empty? end def test_has_many_and_belongs_to_many_callbacks_for_save_on_parent - project = Project.new :name => "Callbacks" - project.developers_with_callbacks.build :name => "Jack", :salary => 95000 + project = Project.new name: "Callbacks" + project.developers_with_callbacks.build name: "Jack", salary: 95000 callback_log = ["before_adding<new>", "after_adding<new>"] assert_equal callback_log, project.developers_log @@ -177,14 +176,14 @@ class AssociationCallbacksTest < ActiveRecord::TestCase end def test_dont_add_if_before_callback_raises_exception - assert !@david.unchangeable_posts.include?(@authorless) + assert_not_includes @david.unchangeable_posts, @authorless begin @david.unchangeable_posts << @authorless rescue Exception end assert @david.post_log.empty? - assert !@david.unchangeable_posts.include?(@authorless) + assert_not_includes @david.unchangeable_posts, @authorless @david.reload - assert !@david.unchangeable_posts.include?(@authorless) + assert_not_includes @david.unchangeable_posts, @authorless end end diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb index 51d8e0523e..e87431bf32 100644 --- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb +++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb @@ -1,56 +1,56 @@ require "cases/helper" -require 'models/post' -require 'models/comment' -require 'models/author' -require 'models/categorization' -require 'models/category' -require 'models/company' -require 'models/topic' -require 'models/reply' -require 'models/person' -require 'models/vertex' -require 'models/edge' +require "models/post" +require "models/comment" +require "models/author" +require "models/categorization" +require "models/category" +require "models/company" +require "models/topic" +require "models/reply" +require "models/person" +require "models/vertex" +require "models/edge" class CascadedEagerLoadingTest < ActiveRecord::TestCase fixtures :authors, :mixins, :companies, :posts, :topics, :accounts, :comments, :categorizations, :people, :categories, :edges, :vertices def test_eager_association_loading_with_cascaded_two_levels - authors = Author.all.merge!(:includes=>{:posts=>:comments}, :order=>"authors.id").to_a + authors = Author.all.merge!(includes: { posts: :comments }, order: "authors.id").to_a assert_equal 3, authors.size assert_equal 5, authors[0].posts.size assert_equal 3, authors[1].posts.size - assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i} + assert_equal 10, authors[0].posts.collect { |post| post.comments.size }.inject(0) { |sum,i| sum+i } end def test_eager_association_loading_with_cascaded_two_levels_and_one_level - authors = Author.all.merge!(:includes=>[{:posts=>:comments}, :categorizations], :order=>"authors.id").to_a + authors = Author.all.merge!(includes: [{ posts: :comments }, :categorizations], order: "authors.id").to_a assert_equal 3, authors.size assert_equal 5, authors[0].posts.size assert_equal 3, authors[1].posts.size - assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i} + assert_equal 10, authors[0].posts.collect { |post| post.comments.size }.inject(0) { |sum,i| sum+i } assert_equal 1, authors[0].categorizations.size assert_equal 2, authors[1].categorizations.size end def test_eager_association_loading_with_hmt_does_not_table_name_collide_when_joining_associations assert_nothing_raised do - Author.joins(:posts).eager_load(:comments).where(:posts => {:tags_count => 1}).to_a + Author.joins(:posts).eager_load(:comments).where(posts: { tags_count: 1 }).to_a end - authors = Author.joins(:posts).eager_load(:comments).where(:posts => {:tags_count => 1}).to_a + authors = Author.joins(:posts).eager_load(:comments).where(posts: { tags_count: 1 }).to_a assert_equal 1, assert_no_queries { authors.size } assert_equal 10, assert_no_queries { authors[0].comments.size } end def test_eager_association_loading_grafts_stashed_associations_to_correct_parent assert_nothing_raised do - Person.eager_load(:primary_contact => :primary_contact).where('primary_contacts_people_2.first_name = ?', 'Susan').order('people.id').to_a + Person.eager_load(primary_contact: :primary_contact).where("primary_contacts_people_2.first_name = ?", "Susan").order("people.id").to_a end - assert_equal people(:michael), Person.eager_load(:primary_contact => :primary_contact).where('primary_contacts_people_2.first_name = ?', 'Susan').order('people.id').first + assert_equal people(:michael), Person.eager_load(primary_contact: :primary_contact).where("primary_contacts_people_2.first_name = ?", "Susan").order("people.id").first end def test_cascaded_eager_association_loading_with_join_for_count - categories = Category.joins(:categorizations).includes([{:posts=>:comments}, :authors]) + categories = Category.joins(:categorizations).includes([{ posts: :comments }, :authors]) assert_equal 4, categories.count assert_equal 4, categories.to_a.count @@ -59,7 +59,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_cascaded_eager_association_loading_with_duplicated_includes - categories = Category.includes(:categorizations).includes(:categorizations => :author).where("categorizations.id is not null").references(:categorizations) + categories = Category.includes(:categorizations).includes(categorizations: :author).where("categorizations.id is not null").references(:categorizations) assert_nothing_raised do assert_equal 3, categories.count assert_equal 3, categories.to_a.size @@ -67,7 +67,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_cascaded_eager_association_loading_with_twice_includes_edge_cases - categories = Category.includes(:categorizations => :author).includes(:categorizations => :post).where("posts.id is not null").references(:posts) + categories = Category.includes(categorizations: :author).includes(categorizations: :post).where("posts.id is not null").references(:posts) assert_nothing_raised do assert_equal 3, categories.count assert_equal 3, categories.to_a.size @@ -82,29 +82,29 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_eager_association_loading_with_cascaded_two_levels_with_two_has_many_associations - authors = Author.all.merge!(:includes=>{:posts=>[:comments, :categorizations]}, :order=>"authors.id").to_a + authors = Author.all.merge!(includes: { posts: [:comments, :categorizations] }, order: "authors.id").to_a assert_equal 3, authors.size assert_equal 5, authors[0].posts.size assert_equal 3, authors[1].posts.size - assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i} + assert_equal 10, authors[0].posts.collect { |post| post.comments.size }.inject(0) { |sum,i| sum+i } end def test_eager_association_loading_with_cascaded_two_levels_and_self_table_reference - authors = Author.all.merge!(:includes=>{:posts=>[:comments, :author]}, :order=>"authors.id").to_a + authors = Author.all.merge!(includes: { posts: [:comments, :author] }, order: "authors.id").to_a assert_equal 3, authors.size assert_equal 5, authors[0].posts.size assert_equal authors(:david).name, authors[0].name - assert_equal [authors(:david).name], authors[0].posts.collect{|post| post.author.name}.uniq + assert_equal [authors(:david).name], authors[0].posts.collect { |post| post.author.name }.uniq end def test_eager_association_loading_with_cascaded_two_levels_with_condition - authors = Author.all.merge!(:includes=>{:posts=>:comments}, :where=>"authors.id=1", :order=>"authors.id").to_a + authors = Author.all.merge!(includes: { posts: :comments }, where: "authors.id=1", order: "authors.id").to_a assert_equal 1, authors.size assert_equal 5, authors[0].posts.size end def test_eager_association_loading_with_cascaded_three_levels_by_ping_pong - firms = Firm.all.merge!(:includes=>{:account=>{:firm=>:account}}, :order=>"companies.id").to_a + firms = Firm.all.merge!(includes: { account: { firm: :account } }, order: "companies.id").to_a assert_equal 2, firms.size assert_equal firms.first.account, firms.first.account.firm.account assert_equal companies(:first_firm).account, assert_no_queries { firms.first.account.firm.account } @@ -112,7 +112,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_eager_association_loading_with_has_many_sti - topics = Topic.all.merge!(:includes => :replies, :order => 'topics.id').to_a + topics = Topic.all.merge!(includes: :replies, order: "topics.id").to_a first, second, = topics(:first).replies.size, topics(:second).replies.size assert_no_queries do assert_equal first, topics[0].replies.size @@ -121,11 +121,11 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_eager_association_loading_with_has_many_sti_and_subclasses - silly = SillyReply.new(:title => "gaga", :content => "boo-boo", :parent_id => 1) + silly = SillyReply.new(title: "gaga", content: "boo-boo", parent_id: 1) silly.parent_id = 1 assert silly.save - topics = Topic.all.merge!(:includes => :replies, :order => ['topics.id', 'replies_topics.id']).to_a + topics = Topic.all.merge!(includes: :replies, order: ["topics.id", "replies_topics.id"]).to_a assert_no_queries do assert_equal 2, topics[0].replies.size assert_equal 0, topics[1].replies.size @@ -133,14 +133,14 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_eager_association_loading_with_belongs_to_sti - replies = Reply.all.merge!(:includes => :topic, :order => 'topics.id').to_a - assert replies.include?(topics(:second)) - assert !replies.include?(topics(:first)) + replies = Reply.all.merge!(includes: :topic, order: "topics.id").to_a + assert_includes replies, topics(:second) + assert_not_includes replies, topics(:first) assert_equal topics(:first), assert_no_queries { replies.first.topic } end def test_eager_association_loading_with_multiple_stis_and_order - author = Author.all.merge!(:includes => { :posts => [ :special_comments , :very_special_comment ] }, :order => ['authors.name', 'comments.body', 'very_special_comments_posts.body'], :where => 'posts.id = 4').first + author = Author.all.merge!(includes: { posts: [ :special_comments , :very_special_comment ] }, order: ["authors.name", "comments.body", "very_special_comments_posts.body"], where: "posts.id = 4").first assert_equal authors(:david), author assert_no_queries do author.posts.first.special_comments @@ -149,7 +149,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_eager_association_loading_of_stis_with_multiple_references - authors = Author.all.merge!(:includes => { :posts => { :special_comments => { :post => [ :special_comments, :very_special_comment ] } } }, :order => 'comments.body, very_special_comments_posts.body', :where => 'posts.id = 4').to_a + authors = Author.all.merge!(includes: { posts: { special_comments: { post: [ :special_comments, :very_special_comment ] } } }, order: "comments.body, very_special_comments_posts.body", where: "posts.id = 4").to_a assert_equal [authors(:david)], authors assert_no_queries do authors.first.posts.first.special_comments.first.post.special_comments @@ -158,7 +158,7 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_eager_association_loading_where_first_level_returns_nil - authors = Author.all.merge!(:includes => {:post_about_thinking => :comments}, :order => 'authors.id DESC').to_a + authors = Author.all.merge!(includes: { post_about_thinking: :comments }, order: "authors.id DESC").to_a assert_equal [authors(:bob), authors(:mary), authors(:david)], authors assert_no_queries do authors[2].post_about_thinking.comments.first @@ -166,12 +166,12 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase end def test_eager_association_loading_with_recursive_cascading_four_levels_has_many_through - source = Vertex.all.merge!(:includes=>{:sinks=>{:sinks=>{:sinks=>:sinks}}}, :order => 'vertices.id').first + source = Vertex.all.merge!(includes: { sinks: { sinks: { sinks: :sinks } } }, order: "vertices.id").first assert_equal vertices(:vertex_4), assert_no_queries { source.sinks.first.sinks.first.sinks.first } end def test_eager_association_loading_with_recursive_cascading_four_levels_has_and_belongs_to_many - sink = Vertex.all.merge!(:includes=>{:sources=>{:sources=>{:sources=>:sources}}}, :order => 'vertices.id DESC').first + sink = Vertex.all.merge!(includes: { sources: { sources: { sources: :sources } } }, order: "vertices.id DESC").first assert_equal vertices(:vertex_1), assert_no_queries { sink.sources.first.sources.first.sources.first.sources.first } end diff --git a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb index 75a6295350..aa82b9dd2a 100644 --- a/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb +++ b/activerecord/test/cases/associations/eager_load_includes_full_sti_class_test.rb @@ -1,34 +1,33 @@ -require 'cases/helper' -require 'models/post' -require 'models/tagging' +require "cases/helper" +require "models/post" +require "models/tagging" module Namespaced class Post < ActiveRecord::Base - self.table_name = 'posts' - has_one :tagging, :as => :taggable, :class_name => 'Tagging' + self.table_name = "posts" + has_one :tagging, as: :taggable, class_name: "Tagging" end end class EagerLoadIncludeFullStiClassNamesTest < ActiveRecord::TestCase - def setup generate_test_objects end def generate_test_objects - post = Namespaced::Post.create( :title => 'Great stuff', :body => 'This is not', :author_id => 1 ) - Tagging.create( :taggable => post ) + post = Namespaced::Post.create( title: "Great stuff", body: "This is not", author_id: 1 ) + Tagging.create( taggable: post ) end def test_class_names old = ActiveRecord::Base.store_full_sti_class ActiveRecord::Base.store_full_sti_class = false - post = Namespaced::Post.includes(:tagging).find_by_title('Great stuff') + post = Namespaced::Post.includes(:tagging).find_by_title("Great stuff") assert_nil post.tagging ActiveRecord::Base.store_full_sti_class = true - post = Namespaced::Post.includes(:tagging).find_by_title('Great stuff') + post = Namespaced::Post.includes(:tagging).find_by_title("Great stuff") assert_instance_of Tagging, post.tagging ensure ActiveRecord::Base.store_full_sti_class = old diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb index f571198079..a7a8c6a783 100644 --- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb +++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb @@ -1,11 +1,11 @@ -require 'cases/helper' -require 'models/post' -require 'models/tag' -require 'models/author' -require 'models/comment' -require 'models/category' -require 'models/categorization' -require 'models/tagging' +require "cases/helper" +require "models/post" +require "models/tag" +require "models/author" +require "models/comment" +require "models/category" +require "models/categorization" +require "models/tagging" module Remembered extend ActiveSupport::Concern @@ -23,30 +23,30 @@ module Remembered end class ShapeExpression < ActiveRecord::Base - belongs_to :shape, :polymorphic => true - belongs_to :paint, :polymorphic => true + belongs_to :shape, polymorphic: true + belongs_to :paint, polymorphic: true end class Circle < ActiveRecord::Base - has_many :shape_expressions, :as => :shape + has_many :shape_expressions, as: :shape include Remembered end class Square < ActiveRecord::Base - has_many :shape_expressions, :as => :shape + has_many :shape_expressions, as: :shape include Remembered end class Triangle < ActiveRecord::Base - has_many :shape_expressions, :as => :shape + has_many :shape_expressions, as: :shape include Remembered end class PaintColor < ActiveRecord::Base - has_many :shape_expressions, :as => :paint - belongs_to :non_poly, :foreign_key => "non_poly_one_id", :class_name => "NonPolyOne" + has_many :shape_expressions, as: :paint + belongs_to :non_poly, foreign_key: "non_poly_one_id", class_name: "NonPolyOne" include Remembered end class PaintTexture < ActiveRecord::Base - has_many :shape_expressions, :as => :paint - belongs_to :non_poly, :foreign_key => "non_poly_two_id", :class_name => "NonPolyTwo" + has_many :shape_expressions, as: :paint + belongs_to :non_poly, foreign_key: "non_poly_two_id", class_name: "NonPolyTwo" include Remembered end class NonPolyOne < ActiveRecord::Base @@ -58,8 +58,6 @@ class NonPolyTwo < ActiveRecord::Base include Remembered end - - class EagerLoadPolyAssocsTest < ActiveRecord::TestCase NUM_SIMPLE_OBJS = 50 NUM_SHAPE_EXPRESSIONS = 100 @@ -78,19 +76,19 @@ class EagerLoadPolyAssocsTest < ActiveRecord::TestCase [Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&:create!) end 1.upto(NUM_SIMPLE_OBJS) do - PaintColor.create!(:non_poly_one_id => NonPolyOne.sample.id) - PaintTexture.create!(:non_poly_two_id => NonPolyTwo.sample.id) + PaintColor.create!(non_poly_one_id: NonPolyOne.sample.id) + PaintTexture.create!(non_poly_two_id: NonPolyTwo.sample.id) end 1.upto(NUM_SHAPE_EXPRESSIONS) do shape_type = [Circle, Square, Triangle].sample paint_type = [PaintColor, PaintTexture].sample - ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.sample.id, - :paint_type => paint_type.to_s, :paint_id => paint_type.sample.id) + ShapeExpression.create!(shape_type: shape_type.to_s, shape_id: shape_type.sample.id, + paint_type: paint_type.to_s, paint_id: paint_type.sample.id) end end def test_include_query - res = ShapeExpression.all.merge!(:includes => [ :shape, { :paint => :non_poly } ]).to_a + res = ShapeExpression.all.merge!(includes: [ :shape, { paint: :non_poly } ]).to_a assert_equal NUM_SHAPE_EXPRESSIONS, res.size assert_queries(0) do res.each do |se| @@ -103,10 +101,10 @@ end class EagerLoadNestedIncludeWithMissingDataTest < ActiveRecord::TestCase def setup - @davey_mcdave = Author.create(:name => 'Davey McDave') - @first_post = @davey_mcdave.posts.create(:title => 'Davey Speaks', :body => 'Expressive wordage') - @first_comment = @first_post.comments.create(:body => 'Inflamatory doublespeak') - @first_categorization = @davey_mcdave.categorizations.create(:category => Category.first, :post => @first_post) + @davey_mcdave = Author.create(name: "Davey McDave") + @first_post = @davey_mcdave.posts.create(title: "Davey Speaks", body: "Expressive wordage") + @first_comment = @first_post.comments.create(body: "Inflamatory doublespeak") + @first_categorization = @davey_mcdave.categorizations.create(category: Category.first, post: @first_post) end teardown do @@ -119,8 +117,8 @@ class EagerLoadNestedIncludeWithMissingDataTest < ActiveRecord::TestCase def test_missing_data_in_a_nested_include_should_not_cause_errors_when_constructing_objects assert_nothing_raised do # @davey_mcdave doesn't have any author_favorites - includes = {:posts => :comments, :categorizations => :category, :author_favorites => :favorite_author } - Author.all.merge!(:includes => includes, :where => {:authors => {:name => @davey_mcdave.name}}, :order => 'categories.name').to_a + includes = { posts: :comments, categorizations: :category, author_favorites: :favorite_author } + Author.all.merge!(includes: includes, where: { authors: { name: @davey_mcdave.name } }, order: "categories.name").to_a end end end diff --git a/activerecord/test/cases/associations/eager_singularization_test.rb b/activerecord/test/cases/associations/eager_singularization_test.rb index a61a070331..5d1c1c4b9b 100644 --- a/activerecord/test/cases/associations/eager_singularization_test.rb +++ b/activerecord/test/cases/associations/eager_singularization_test.rb @@ -1,148 +1,147 @@ require "cases/helper" - if ActiveRecord::Base.connection.supports_migrations? -class EagerSingularizationTest < ActiveRecord::TestCase - class Virus < ActiveRecord::Base - belongs_to :octopus - end - - class Octopus < ActiveRecord::Base - has_one :virus - end - - class Pass < ActiveRecord::Base - belongs_to :bus - end - - class Bus < ActiveRecord::Base - has_many :passes - end - - class Mess < ActiveRecord::Base - has_and_belongs_to_many :crises - end - - class Crisis < ActiveRecord::Base - has_and_belongs_to_many :messes - has_many :analyses, :dependent => :destroy - has_many :successes, :through => :analyses - has_many :dresses, :dependent => :destroy - has_many :compresses, :through => :dresses - end - - class Analysis < ActiveRecord::Base - belongs_to :crisis - belongs_to :success - end - - class Success < ActiveRecord::Base - has_many :analyses, :dependent => :destroy - has_many :crises, :through => :analyses - end + class EagerSingularizationTest < ActiveRecord::TestCase + class Virus < ActiveRecord::Base + belongs_to :octopus + end + + class Octopus < ActiveRecord::Base + has_one :virus + end + + class Pass < ActiveRecord::Base + belongs_to :bus + end - class Dress < ActiveRecord::Base - belongs_to :crisis - has_many :compresses - end + class Bus < ActiveRecord::Base + has_many :passes + end - class Compress < ActiveRecord::Base - belongs_to :dress - end - - def setup - connection.create_table :viri do |t| - t.column :octopus_id, :integer - t.column :species, :string - end - connection.create_table :octopi do |t| - t.column :species, :string + class Mess < ActiveRecord::Base + has_and_belongs_to_many :crises end - connection.create_table :passes do |t| - t.column :bus_id, :integer - t.column :rides, :integer - end - connection.create_table :buses do |t| - t.column :name, :string - end - connection.create_table :crises_messes, :id => false do |t| - t.column :crisis_id, :integer - t.column :mess_id, :integer - end - connection.create_table :messes do |t| - t.column :name, :string - end - connection.create_table :crises do |t| - t.column :name, :string - end - connection.create_table :successes do |t| - t.column :name, :string - end - connection.create_table :analyses do |t| - t.column :crisis_id, :integer - t.column :success_id, :integer - end - connection.create_table :dresses do |t| - t.column :crisis_id, :integer + + class Crisis < ActiveRecord::Base + has_and_belongs_to_many :messes + has_many :analyses, dependent: :destroy + has_many :successes, through: :analyses + has_many :dresses, dependent: :destroy + has_many :compresses, through: :dresses end - connection.create_table :compresses do |t| - t.column :dress_id, :integer + + class Analysis < ActiveRecord::Base + belongs_to :crisis + belongs_to :success end - end - teardown do - connection.drop_table :viri - connection.drop_table :octopi - connection.drop_table :passes - connection.drop_table :buses - connection.drop_table :crises_messes - connection.drop_table :messes - connection.drop_table :crises - connection.drop_table :successes - connection.drop_table :analyses - connection.drop_table :dresses - connection.drop_table :compresses - end + class Success < ActiveRecord::Base + has_many :analyses, dependent: :destroy + has_many :crises, through: :analyses + end - def connection - ActiveRecord::Base.connection - end + class Dress < ActiveRecord::Base + belongs_to :crisis + has_many :compresses + end - def test_eager_no_extra_singularization_belongs_to - assert_nothing_raised do - Virus.all.merge!(:includes => :octopus).to_a + class Compress < ActiveRecord::Base + belongs_to :dress end - end - def test_eager_no_extra_singularization_has_one - assert_nothing_raised do - Octopus.all.merge!(:includes => :virus).to_a + def setup + connection.create_table :viri do |t| + t.column :octopus_id, :integer + t.column :species, :string + end + connection.create_table :octopi do |t| + t.column :species, :string + end + connection.create_table :passes do |t| + t.column :bus_id, :integer + t.column :rides, :integer + end + connection.create_table :buses do |t| + t.column :name, :string + end + connection.create_table :crises_messes, id: false do |t| + t.column :crisis_id, :integer + t.column :mess_id, :integer + end + connection.create_table :messes do |t| + t.column :name, :string + end + connection.create_table :crises do |t| + t.column :name, :string + end + connection.create_table :successes do |t| + t.column :name, :string + end + connection.create_table :analyses do |t| + t.column :crisis_id, :integer + t.column :success_id, :integer + end + connection.create_table :dresses do |t| + t.column :crisis_id, :integer + end + connection.create_table :compresses do |t| + t.column :dress_id, :integer + end end - end - def test_eager_no_extra_singularization_has_many - assert_nothing_raised do - Bus.all.merge!(:includes => :passes).to_a + teardown do + connection.drop_table :viri + connection.drop_table :octopi + connection.drop_table :passes + connection.drop_table :buses + connection.drop_table :crises_messes + connection.drop_table :messes + connection.drop_table :crises + connection.drop_table :successes + connection.drop_table :analyses + connection.drop_table :dresses + connection.drop_table :compresses end - end - def test_eager_no_extra_singularization_has_and_belongs_to_many - assert_nothing_raised do - Crisis.all.merge!(:includes => :messes).to_a - Mess.all.merge!(:includes => :crises).to_a + def connection + ActiveRecord::Base.connection end - end - def test_eager_no_extra_singularization_has_many_through_belongs_to - assert_nothing_raised do - Crisis.all.merge!(:includes => :successes).to_a + def test_eager_no_extra_singularization_belongs_to + assert_nothing_raised do + Virus.all.merge!(includes: :octopus).to_a + end end - end - def test_eager_no_extra_singularization_has_many_through_has_many - assert_nothing_raised do - Crisis.all.merge!(:includes => :compresses).to_a + def test_eager_no_extra_singularization_has_one + assert_nothing_raised do + Octopus.all.merge!(includes: :virus).to_a + end + end + + def test_eager_no_extra_singularization_has_many + assert_nothing_raised do + Bus.all.merge!(includes: :passes).to_a + end + end + + def test_eager_no_extra_singularization_has_and_belongs_to_many + assert_nothing_raised do + Crisis.all.merge!(includes: :messes).to_a + Mess.all.merge!(includes: :crises).to_a + end + end + + def test_eager_no_extra_singularization_has_many_through_belongs_to + assert_nothing_raised do + Crisis.all.merge!(includes: :successes).to_a + end + end + + def test_eager_no_extra_singularization_has_many_through_has_many + assert_nothing_raised do + Crisis.all.merge!(includes: :compresses).to_a + end end end end -end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 7f2a2229ee..d1c4c1cef8 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1,31 +1,31 @@ require "cases/helper" -require 'models/post' -require 'models/tagging' -require 'models/tag' -require 'models/comment' -require 'models/author' -require 'models/essay' -require 'models/category' -require 'models/company' -require 'models/person' -require 'models/reader' -require 'models/owner' -require 'models/pet' -require 'models/reference' -require 'models/job' -require 'models/subscriber' -require 'models/subscription' -require 'models/book' -require 'models/developer' -require 'models/computer' -require 'models/project' -require 'models/member' -require 'models/membership' -require 'models/club' -require 'models/categorization' -require 'models/sponsor' -require 'models/mentor' -require 'models/contract' +require "models/post" +require "models/tagging" +require "models/tag" +require "models/comment" +require "models/author" +require "models/essay" +require "models/category" +require "models/company" +require "models/person" +require "models/reader" +require "models/owner" +require "models/pet" +require "models/reference" +require "models/job" +require "models/subscriber" +require "models/subscription" +require "models/book" +require "models/developer" +require "models/computer" +require "models/project" +require "models/member" +require "models/membership" +require "models/club" +require "models/categorization" +require "models/sponsor" +require "models/mentor" +require "models/contract" class EagerAssociationTest < ActiveRecord::TestCase fixtures :posts, :comments, :authors, :essays, :author_addresses, :categories, :categories_posts, @@ -34,42 +34,42 @@ class EagerAssociationTest < ActiveRecord::TestCase :developers, :projects, :developers_projects, :members, :memberships, :clubs, :sponsors def test_eager_with_has_one_through_join_model_with_conditions_on_the_through - member = Member.all.merge!(:includes => :favourite_club).find(members(:some_other_guy).id) + member = Member.all.merge!(includes: :favourite_club).find(members(:some_other_guy).id) assert_nil member.favourite_club end def test_loading_with_one_association - posts = Post.all.merge!(:includes => :comments).to_a + posts = Post.all.merge!(includes: :comments).to_a post = posts.find { |p| p.id == 1 } assert_equal 2, post.comments.size - assert post.comments.include?(comments(:greetings)) + assert_includes post.comments, comments(:greetings) - post = Post.all.merge!(:includes => :comments, :where => "posts.title = 'Welcome to the weblog'").first + post = Post.all.merge!(includes: :comments, where: "posts.title = 'Welcome to the weblog'").first assert_equal 2, post.comments.size - assert post.comments.include?(comments(:greetings)) + assert_includes post.comments, comments(:greetings) - posts = Post.all.merge!(:includes => :last_comment).to_a + posts = Post.all.merge!(includes: :last_comment).to_a post = posts.find { |p| p.id == 1 } assert_equal Post.find(1).last_comment, post.last_comment end def test_loading_with_one_association_with_non_preload - posts = Post.all.merge!(:includes => :last_comment, :order => 'comments.id DESC').to_a + posts = Post.all.merge!(includes: :last_comment, order: "comments.id DESC").to_a post = posts.find { |p| p.id == 1 } assert_equal Post.find(1).last_comment, post.last_comment end def test_loading_conditions_with_or posts = authors(:david).posts.references(:comments).merge( - :includes => :comments, - :where => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'" + includes: :comments, + where: "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'" ).to_a assert_nil posts.detect { |p| p.author_id != authors(:david).id }, "expected to find only david's posts" end def test_with_ordering - list = Post.all.merge!(:includes => :comments, :order => "posts.id DESC").to_a + list = Post.all.merge!(includes: :comments, order: "posts.id DESC").to_a [:other_by_mary, :other_by_bob, :misc_by_mary, :misc_by_bob, :eager_other, :sti_habtm, :sti_post_and_comments, :sti_comments, :authorless, :thinking, :welcome ].each_with_index do |post, index| @@ -90,49 +90,53 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_no_queries { authors.map(&:post) } end + def test_calculate_with_string_in_from_and_eager_loading + assert_equal 10, Post.from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").count + end + def test_with_two_tables_in_from_without_getting_double_quoted posts = Post.select("posts.*").from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").order("posts.id").to_a assert_equal 2, posts.first.comments.size end def test_loading_with_multiple_associations - posts = Post.all.merge!(:includes => [ :comments, :author, :categories ], :order => "posts.id").to_a + posts = Post.all.merge!(includes: [ :comments, :author, :categories ], order: "posts.id").to_a assert_equal 2, posts.first.comments.size assert_equal 2, posts.first.categories.size - assert posts.first.comments.include?(comments(:greetings)) + assert_includes posts.first.comments, comments(:greetings) end def test_duplicate_middle_objects - comments = Comment.all.merge!(:where => 'post_id = 1', :includes => [:post => :author]).to_a + comments = Comment.all.merge!(where: "post_id = 1", includes: [post: :author]).to_a assert_no_queries do - comments.each {|comment| comment.post.author.name} + comments.each { |comment| comment.post.author.name } end end def test_preloading_has_many_in_multiple_queries_with_more_ids_than_database_can_handle assert_called(Comment.connection, :in_clause_length, returns: 5) do - posts = Post.all.merge!(:includes=>:comments).to_a + posts = Post.all.merge!(includes: :comments).to_a assert_equal 11, posts.size end end def test_preloading_has_many_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle assert_called(Comment.connection, :in_clause_length, returns: nil) do - posts = Post.all.merge!(:includes=>:comments).to_a + posts = Post.all.merge!(includes: :comments).to_a assert_equal 11, posts.size end end def test_preloading_habtm_in_multiple_queries_with_more_ids_than_database_can_handle assert_called(Comment.connection, :in_clause_length, times: 2, returns: 5) do - posts = Post.all.merge!(:includes=>:categories).to_a + posts = Post.all.merge!(includes: :categories).to_a assert_equal 11, posts.size end end def test_preloading_habtm_in_one_queries_when_database_has_no_limit_on_ids_it_can_handle assert_called(Comment.connection, :in_clause_length, times: 2, returns: nil) do - posts = Post.all.merge!(:includes=>:categories).to_a + posts = Post.all.merge!(includes: :categories).to_a assert_equal 11, posts.size end end @@ -141,7 +145,7 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_called(Comment.connection, :in_clause_length, returns: nil) do post = posts(:welcome) assert_queries(2) do - Post.includes(:comments).where(:id => post.id).to_a + Post.includes(:comments).where(id: post.id).to_a end end end @@ -150,7 +154,7 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_called(Comment.connection, :in_clause_length, returns: 1) do post1, post2 = posts(:welcome), posts(:thinking) assert_queries(3) do - Post.includes(:comments).where(:id => [post1.id, post2.id]).to_a + Post.includes(:comments).where(id: [post1.id, post2.id]).to_a end end end @@ -159,50 +163,50 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_called(Comment.connection, :in_clause_length, returns: 3) do post = posts(:welcome) assert_queries(2) do - Post.includes(:comments).where(:id => post.id).to_a + Post.includes(:comments).where(id: post.id).to_a end end end def test_including_duplicate_objects_from_belongs_to - popular_post = Post.create!(:title => 'foo', :body => "I like cars!") - comment = popular_post.comments.create!(:body => "lol") - popular_post.readers.create!(:person => people(:michael)) - popular_post.readers.create!(:person => people(:david)) + popular_post = Post.create!(title: "foo", body: "I like cars!") + comment = popular_post.comments.create!(body: "lol") + popular_post.readers.create!(person: people(:michael)) + popular_post.readers.create!(person: people(:david)) - readers = Reader.all.merge!(:where => ["post_id = ?", popular_post.id], - :includes => {:post => :comments}).to_a + readers = Reader.all.merge!(where: ["post_id = ?", popular_post.id], + includes: { post: :comments }).to_a readers.each do |reader| assert_equal [comment], reader.post.comments end end def test_including_duplicate_objects_from_has_many - car_post = Post.create!(:title => 'foo', :body => "I like cars!") + car_post = Post.create!(title: "foo", body: "I like cars!") car_post.categories << categories(:general) car_post.categories << categories(:technology) - comment = car_post.comments.create!(:body => "hmm") - categories = Category.all.merge!(:where => { 'posts.id' => car_post.id }, - :includes => {:posts => :comments}).to_a + comment = car_post.comments.create!(body: "hmm") + categories = Category.all.merge!(where: { "posts.id" => car_post.id }, + includes: { posts: :comments }).to_a categories.each do |category| assert_equal [comment], category.posts[0].comments end end def test_associations_loaded_for_all_records - post = Post.create!(:title => 'foo', :body => "I like cars!") - SpecialComment.create!(:body => 'Come on!', :post => post) - first_category = Category.create! :name => 'First!', :posts => [post] - second_category = Category.create! :name => 'Second!', :posts => [post] + post = Post.create!(title: "foo", body: "I like cars!") + SpecialComment.create!(body: "Come on!", post: post) + first_category = Category.create! name: "First!", posts: [post] + second_category = Category.create! name: "Second!", posts: [post] - categories = Category.where(:id => [first_category.id, second_category.id]).includes(:posts => :special_comments) + categories = Category.where(id: [first_category.id, second_category.id]).includes(posts: :special_comments) assert_equal categories.map { |category| category.posts.first.special_comments.loaded? }, [true, true] end def test_finding_with_includes_on_has_many_association_with_same_include_includes_only_once author_id = authors(:david).id - author = assert_queries(3) { Author.all.merge!(:includes => {:posts_with_comments => :comments}).find(author_id) } # find the author, then find the posts, then find the comments + author = assert_queries(3) { Author.all.merge!(includes: { posts_with_comments: :comments }).find(author_id) } # find the author, then find the posts, then find the comments author.posts_with_comments.each do |post_with_comments| assert_equal post_with_comments.comments.length, post_with_comments.comments.count assert_nil post_with_comments.comments.to_a.uniq! @@ -213,7 +217,7 @@ class EagerAssociationTest < ActiveRecord::TestCase author = authors(:david) post = author.post_about_thinking_with_last_comment last_comment = post.last_comment - author = assert_queries(3) { Author.all.merge!(:includes => {:post_about_thinking_with_last_comment => :last_comment}).find(author.id)} # find the author, then find the posts, then find the comments + author = assert_queries(3) { Author.all.merge!(includes: { post_about_thinking_with_last_comment: :last_comment }).find(author.id) } # find the author, then find the posts, then find the comments assert_no_queries do assert_equal post, author.post_about_thinking_with_last_comment assert_equal last_comment, author.post_about_thinking_with_last_comment.last_comment @@ -224,7 +228,7 @@ class EagerAssociationTest < ActiveRecord::TestCase post = posts(:welcome) author = post.author author_address = author.author_address - post = assert_queries(3) { Post.all.merge!(:includes => {:author_with_address => :author_address}).find(post.id) } # find the post, then find the author, then find the address + post = assert_queries(3) { Post.all.merge!(includes: { author_with_address: :author_address }).find(post.id) } # find the post, then find the author, then find the address assert_no_queries do assert_equal author, post.author_with_address assert_equal author_address, post.author_with_address.author_address @@ -234,7 +238,7 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_finding_with_includes_on_null_belongs_to_association_with_same_include_includes_only_once post = posts(:welcome) post.update!(author: nil) - post = assert_queries(1) { Post.all.merge!(includes: {author_with_address: :author_address}).find(post.id) } + post = assert_queries(1) { Post.all.merge!(includes: { author_with_address: :author_address }).find(post.id) } # find the post, then find the author which is null so no query for the author or address assert_no_queries do assert_equal nil, post.author_with_address @@ -244,7 +248,7 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_finding_with_includes_on_null_belongs_to_polymorphic_association sponsor = sponsors(:moustache_club_sponsor_for_groucho) sponsor.update!(sponsorable: nil) - sponsor = assert_queries(1) { Sponsor.all.merge!(:includes => :sponsorable).find(sponsor.id) } + sponsor = assert_queries(1) { Sponsor.all.merge!(includes: :sponsorable).find(sponsor.id) } assert_no_queries do assert_equal nil, sponsor.sponsorable end @@ -252,9 +256,9 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_finding_with_includes_on_empty_polymorphic_type_column sponsor = sponsors(:moustache_club_sponsor_for_groucho) - sponsor.update!(sponsorable_type: '', sponsorable_id: nil) # sponsorable_type column might be declared NOT NULL + sponsor.update!(sponsorable_type: "", sponsorable_id: nil) # sponsorable_type column might be declared NOT NULL sponsor = assert_queries(1) do - assert_nothing_raised { Sponsor.all.merge!(:includes => :sponsorable).find(sponsor.id) } + assert_nothing_raised { Sponsor.all.merge!(includes: :sponsorable).find(sponsor.id) } end assert_no_queries do assert_equal nil, sponsor.sponsorable @@ -262,25 +266,25 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_loading_from_an_association - posts = authors(:david).posts.merge(:includes => :comments, :order => "posts.id").to_a + posts = authors(:david).posts.merge(includes: :comments, order: "posts.id").to_a assert_equal 2, posts.first.comments.size end def test_loading_from_an_association_that_has_a_hash_of_conditions assert_nothing_raised do - Author.all.merge!(:includes => :hello_posts_with_hash_conditions).to_a + Author.all.merge!(includes: :hello_posts_with_hash_conditions).to_a end - assert !Author.all.merge!(:includes => :hello_posts_with_hash_conditions).find(authors(:david).id).hello_posts.empty? + assert !Author.all.merge!(includes: :hello_posts_with_hash_conditions).find(authors(:david).id).hello_posts.empty? end def test_loading_with_no_associations - assert_nil Post.all.merge!(:includes => :author).find(posts(:authorless).id).author + assert_nil Post.all.merge!(includes: :author).find(posts(:authorless).id).author end # Regression test for 21c75e5 def test_nested_loading_does_not_raise_exception_when_association_does_not_exist assert_nothing_raised do - Post.all.merge!(:includes => {:author => :author_addresss}).find(posts(:authorless).id) + Post.all.merge!(includes: { author: :author_addresss }).find(posts(:authorless).id) end end @@ -288,107 +292,107 @@ class EagerAssociationTest < ActiveRecord::TestCase post_id = Comment.where(author_id: nil).where.not(post_id: nil).first.post_id assert_nothing_raised do - Post.preload(:comments => [{:author => :essays}]).find(post_id) + Post.preload(comments: [{ author: :essays }]).find(post_id) end end def test_nested_loading_through_has_one_association - aa = AuthorAddress.all.merge!(:includes => {:author => :posts}).find(author_addresses(:david_address).id) + aa = AuthorAddress.all.merge!(includes: { author: :posts }).find(author_addresses(:david_address).id) assert_equal aa.author.posts.count, aa.author.posts.length end def test_nested_loading_through_has_one_association_with_order - aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'author_addresses.id').find(author_addresses(:david_address).id) + aa = AuthorAddress.all.merge!(includes: { author: :posts }, order: "author_addresses.id").find(author_addresses(:david_address).id) assert_equal aa.author.posts.count, aa.author.posts.length end def test_nested_loading_through_has_one_association_with_order_on_association - aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'authors.id').find(author_addresses(:david_address).id) + aa = AuthorAddress.all.merge!(includes: { author: :posts }, order: "authors.id").find(author_addresses(:david_address).id) assert_equal aa.author.posts.count, aa.author.posts.length end def test_nested_loading_through_has_one_association_with_order_on_nested_association - aa = AuthorAddress.all.merge!(:includes => {:author => :posts}, :order => 'posts.id').find(author_addresses(:david_address).id) + aa = AuthorAddress.all.merge!(includes: { author: :posts }, order: "posts.id").find(author_addresses(:david_address).id) assert_equal aa.author.posts.count, aa.author.posts.length end def test_nested_loading_through_has_one_association_with_conditions aa = AuthorAddress.references(:author_addresses).merge( - :includes => {:author => :posts}, - :where => "author_addresses.id > 0" + includes: { author: :posts }, + where: "author_addresses.id > 0" ).find author_addresses(:david_address).id assert_equal aa.author.posts.count, aa.author.posts.length end def test_nested_loading_through_has_one_association_with_conditions_on_association aa = AuthorAddress.references(:authors).merge( - :includes => {:author => :posts}, - :where => "authors.id > 0" + includes: { author: :posts }, + where: "authors.id > 0" ).find author_addresses(:david_address).id assert_equal aa.author.posts.count, aa.author.posts.length end def test_nested_loading_through_has_one_association_with_conditions_on_nested_association aa = AuthorAddress.references(:posts).merge( - :includes => {:author => :posts}, - :where => "posts.id > 0" + includes: { author: :posts }, + where: "posts.id > 0" ).find author_addresses(:david_address).id assert_equal aa.author.posts.count, aa.author.posts.length end def test_eager_association_loading_with_belongs_to_and_foreign_keys - pets = Pet.all.merge!(:includes => :owner).to_a + pets = Pet.all.merge!(includes: :owner).to_a assert_equal 4, pets.length end def test_eager_association_loading_with_belongs_to - comments = Comment.all.merge!(:includes => :post).to_a + comments = Comment.all.merge!(includes: :post).to_a assert_equal 11, comments.length titles = comments.map { |c| c.post.title } - assert titles.include?(posts(:welcome).title) - assert titles.include?(posts(:sti_post_and_comments).title) + assert_includes titles, posts(:welcome).title + assert_includes titles, posts(:sti_post_and_comments).title end def test_eager_association_loading_with_belongs_to_and_limit - comments = Comment.all.merge!(:includes => :post, :limit => 5, :order => 'comments.id').to_a + comments = Comment.all.merge!(includes: :post, limit: 5, order: "comments.id").to_a assert_equal 5, comments.length assert_equal [1,2,3,5,6], comments.collect(&:id) end def test_eager_association_loading_with_belongs_to_and_limit_and_conditions - comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 4', :limit => 3, :order => 'comments.id').to_a + comments = Comment.all.merge!(includes: :post, where: "post_id = 4", limit: 3, order: "comments.id").to_a assert_equal 3, comments.length assert_equal [5,6,7], comments.collect(&:id) end def test_eager_association_loading_with_belongs_to_and_limit_and_offset - comments = Comment.all.merge!(:includes => :post, :limit => 3, :offset => 2, :order => 'comments.id').to_a + comments = Comment.all.merge!(includes: :post, limit: 3, offset: 2, order: "comments.id").to_a assert_equal 3, comments.length assert_equal [3,5,6], comments.collect(&:id) end def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions - comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 4', :limit => 3, :offset => 1, :order => 'comments.id').to_a + comments = Comment.all.merge!(includes: :post, where: "post_id = 4", limit: 3, offset: 1, order: "comments.id").to_a assert_equal 3, comments.length assert_equal [6,7,8], comments.collect(&:id) end def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_conditions_array - comments = Comment.all.merge!(:includes => :post, :where => ['post_id = ?',4], :limit => 3, :offset => 1, :order => 'comments.id').to_a + comments = Comment.all.merge!(includes: :post, where: ["post_id = ?",4], limit: 3, offset: 1, order: "comments.id").to_a assert_equal 3, comments.length assert_equal [6,7,8], comments.collect(&:id) end def test_eager_association_loading_with_belongs_to_and_conditions_string_with_unquoted_table_name assert_nothing_raised do - Comment.includes(:post).references(:posts).where('posts.id = ?', 4) + Comment.includes(:post).references(:posts).where("posts.id = ?", 4) end end def test_eager_association_loading_with_belongs_to_and_conditions_hash comments = [] assert_nothing_raised do - comments = Comment.all.merge!(:includes => :post, :where => {:posts => {:id => 4}}, :limit => 3, :order => 'comments.id').to_a + comments = Comment.all.merge!(includes: :post, where: { posts: { id: 4 } }, limit: 3, order: "comments.id").to_a end assert_equal 3, comments.length assert_equal [5,6,7], comments.collect(&:id) @@ -398,7 +402,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_association_loading_with_belongs_to_and_conditions_string_with_quoted_table_name - quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id') + quoted_posts_id= Comment.connection.quote_table_name("posts") + "." + Comment.connection.quote_column_name("id") assert_nothing_raised do Comment.includes(:post).references(:posts).where("#{quoted_posts_id} = ?", 4) end @@ -406,61 +410,61 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_association_loading_with_belongs_to_and_order_string_with_unquoted_table_name assert_nothing_raised do - Comment.all.merge!(:includes => :post, :order => 'posts.id').to_a + Comment.all.merge!(includes: :post, order: "posts.id").to_a end end def test_eager_association_loading_with_belongs_to_and_order_string_with_quoted_table_name - quoted_posts_id= Comment.connection.quote_table_name('posts') + '.' + Comment.connection.quote_column_name('id') + quoted_posts_id= Comment.connection.quote_table_name("posts") + "." + Comment.connection.quote_column_name("id") assert_nothing_raised do Comment.includes(:post).references(:posts).order(quoted_posts_id) end end def test_eager_association_loading_with_belongs_to_and_limit_and_multiple_associations - posts = Post.all.merge!(:includes => [:author, :very_special_comment], :limit => 1, :order => 'posts.id').to_a + posts = Post.all.merge!(includes: [:author, :very_special_comment], limit: 1, order: "posts.id").to_a assert_equal 1, posts.length assert_equal [1], posts.collect(&:id) end def test_eager_association_loading_with_belongs_to_and_limit_and_offset_and_multiple_associations - posts = Post.all.merge!(:includes => [:author, :very_special_comment], :limit => 1, :offset => 1, :order => 'posts.id').to_a + posts = Post.all.merge!(includes: [:author, :very_special_comment], limit: 1, offset: 1, order: "posts.id").to_a assert_equal 1, posts.length assert_equal [2], posts.collect(&:id) end def test_eager_association_loading_with_belongs_to_inferred_foreign_key_from_association_name - author_favorite = AuthorFavorite.all.merge!(:includes => :favorite_author).first + author_favorite = AuthorFavorite.all.merge!(includes: :favorite_author).first assert_equal authors(:mary), assert_no_queries { author_favorite.favorite_author } end def test_eager_load_belongs_to_quotes_table_and_column_names job = Job.includes(:ideal_reference).find jobs(:unicyclist).id references(:michael_unicyclist) - assert_no_queries{ assert_equal references(:michael_unicyclist), job.ideal_reference} + assert_no_queries { assert_equal references(:michael_unicyclist), job.ideal_reference } end def test_eager_load_has_one_quotes_table_and_column_names - michael = Person.all.merge!(:includes => :favourite_reference).find(people(:michael).id) + michael = Person.all.merge!(includes: :favourite_reference).find(people(:michael).id) references(:michael_unicyclist) - assert_no_queries{ assert_equal references(:michael_unicyclist), michael.favourite_reference} + assert_no_queries { assert_equal references(:michael_unicyclist), michael.favourite_reference } end def test_eager_load_has_many_quotes_table_and_column_names - michael = Person.all.merge!(:includes => :references).find(people(:michael).id) + michael = Person.all.merge!(includes: :references).find(people(:michael).id) references(:michael_magician,:michael_unicyclist) - assert_no_queries{ assert_equal references(:michael_magician,:michael_unicyclist), michael.references.sort_by(&:id) } + assert_no_queries { assert_equal references(:michael_magician,:michael_unicyclist), michael.references.sort_by(&:id) } end def test_eager_load_has_many_through_quotes_table_and_column_names - michael = Person.all.merge!(:includes => :jobs).find(people(:michael).id) + michael = Person.all.merge!(includes: :jobs).find(people(:michael).id) jobs(:magician, :unicyclist) - assert_no_queries{ assert_equal jobs(:unicyclist, :magician), michael.jobs.sort_by(&:id) } + assert_no_queries { assert_equal jobs(:unicyclist, :magician), michael.jobs.sort_by(&:id) } end def test_eager_load_has_many_with_string_keys subscriptions = subscriptions(:webster_awdr, :webster_rfr) - subscriber =Subscriber.all.merge!(:includes => :subscriptions).find(subscribers(:second).id) + subscriber =Subscriber.all.merge!(includes: :subscriptions).find(subscribers(:second).id) assert_equal subscriptions, subscriber.subscriptions.sort_by(&:id) end @@ -471,32 +475,32 @@ class EagerAssociationTest < ActiveRecord::TestCase b = Book.create! - Subscription.create!(:subscriber_id => "PL", :book_id => b.id) + Subscription.create!(subscriber_id: "PL", book_id: b.id) s.reload s.book_ids = s.book_ids end def test_eager_load_has_many_through_with_string_keys books = books(:awdr, :rfr) - subscriber = Subscriber.all.merge!(:includes => :books).find(subscribers(:second).id) + subscriber = Subscriber.all.merge!(includes: :books).find(subscribers(:second).id) assert_equal books, subscriber.books.sort_by(&:id) end def test_eager_load_belongs_to_with_string_keys subscriber = subscribers(:second) - subscription = Subscription.all.merge!(:includes => :subscriber).find(subscriptions(:webster_awdr).id) + subscription = Subscription.all.merge!(includes: :subscriber).find(subscriptions(:webster_awdr).id) assert_equal subscriber, subscription.subscriber end def test_eager_association_loading_with_explicit_join - posts = Post.all.merge!(:includes => :comments, :joins => "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", :limit => 1, :order => 'author_id').to_a + posts = Post.all.merge!(includes: :comments, joins: "INNER JOIN authors ON posts.author_id = authors.id AND authors.name = 'Mary'", limit: 1, order: "author_id").to_a assert_equal 1, posts.length end def test_eager_with_has_many_through - posts_with_comments = people(:michael).posts.merge(:includes => :comments, :order => 'posts.id').to_a - posts_with_author = people(:michael).posts.merge(:includes => :author, :order => 'posts.id').to_a - posts_with_comments_and_author = people(:michael).posts.merge(:includes => [ :comments, :author ], :order => 'posts.id').to_a + posts_with_comments = people(:michael).posts.merge(includes: :comments, order: "posts.id").to_a + posts_with_author = people(:michael).posts.merge(includes: :author, order: "posts.id").to_a + posts_with_comments_and_author = people(:michael).posts.merge(includes: [ :comments, :author ], order: "posts.id").to_a assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum + post.comments.size } assert_equal authors(:david), assert_no_queries { posts_with_author.first.author } assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author } @@ -504,35 +508,35 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_with_has_many_through_a_belongs_to_association author = authors(:mary) - Post.create!(:author => author, :title => "TITLE", :body => "BODY") - author.author_favorites.create(:favorite_author_id => 1) - author.author_favorites.create(:favorite_author_id => 2) - posts_with_author_favorites = author.posts.merge(:includes => :author_favorites).to_a + Post.create!(author: author, title: "TITLE", body: "BODY") + author.author_favorites.create(favorite_author_id: 1) + author.author_favorites.create(favorite_author_id: 2) + posts_with_author_favorites = author.posts.merge(includes: :author_favorites).to_a assert_no_queries { posts_with_author_favorites.first.author_favorites.first.author_id } end def test_eager_with_has_many_through_an_sti_join_model - author = Author.all.merge!(:includes => :special_post_comments, :order => 'authors.id').first + author = Author.all.merge!(includes: :special_post_comments, order: "authors.id").first assert_equal [comments(:does_it_hurt)], assert_no_queries { author.special_post_comments } end def test_eager_with_has_many_through_an_sti_join_model_with_conditions_on_both - author = Author.all.merge!(:includes => :special_nonexistent_post_comments, :order => 'authors.id').first + author = Author.all.merge!(includes: :special_nonexistent_post_comments, order: "authors.id").first assert_equal [], author.special_nonexistent_post_comments end def test_eager_with_has_many_through_join_model_with_conditions - assert_equal Author.all.merge!(:includes => :hello_post_comments, - :order => 'authors.id').first.hello_post_comments.sort_by(&:id), - Author.all.merge!(:order => 'authors.id').first.hello_post_comments.sort_by(&:id) + assert_equal Author.all.merge!(includes: :hello_post_comments, + order: "authors.id").first.hello_post_comments.sort_by(&:id), + Author.all.merge!(order: "authors.id").first.hello_post_comments.sort_by(&:id) end def test_eager_with_has_many_through_join_model_with_conditions_on_top_level - assert_equal comments(:more_greetings), Author.all.merge!(:includes => :comments_with_order_and_conditions).find(authors(:david).id).comments_with_order_and_conditions.first + assert_equal comments(:more_greetings), Author.all.merge!(includes: :comments_with_order_and_conditions).find(authors(:david).id).comments_with_order_and_conditions.first end def test_eager_with_has_many_through_join_model_with_include - author_comments = Author.all.merge!(:includes => :comments_with_include).find(authors(:david).id).comments_with_include.to_a + author_comments = Author.all.merge!(includes: :comments_with_include).find(authors(:david).id).comments_with_include.to_a assert_no_queries do author_comments.first.post.title end @@ -540,7 +544,7 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_with_has_many_through_with_conditions_join_model_with_include post_tags = Post.find(posts(:welcome).id).misc_tags - eager_post_tags = Post.all.merge!(:includes => :misc_tags).find(1).misc_tags + eager_post_tags = Post.all.merge!(includes: :misc_tags).find(1).misc_tags assert_equal post_tags, eager_post_tags end @@ -551,67 +555,67 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_has_many_and_limit - posts = Post.all.merge!(:order => 'posts.id asc', :includes => [ :author, :comments ], :limit => 2).to_a + posts = Post.all.merge!(order: "posts.id asc", includes: [ :author, :comments ], limit: 2).to_a assert_equal 2, posts.size assert_equal 3, posts.inject(0) { |sum, post| sum + post.comments.size } end def test_eager_with_has_many_and_limit_and_conditions - posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => "posts.body = 'hello'", :order => "posts.id").to_a + posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, where: "posts.body = 'hello'", order: "posts.id").to_a assert_equal 2, posts.size assert_equal [4,5], posts.collect(&:id) end def test_eager_with_has_many_and_limit_and_conditions_array - posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => [ "posts.body = ?", 'hello' ], :order => "posts.id").to_a + posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, where: [ "posts.body = ?", "hello" ], order: "posts.id").to_a assert_equal 2, posts.size assert_equal [4,5], posts.collect(&:id) end def test_eager_with_has_many_and_limit_and_conditions_array_on_the_eagers - posts = Post.includes(:author, :comments).limit(2).references(:author).where("authors.name = ?", 'David') + posts = Post.includes(:author, :comments).limit(2).references(:author).where("authors.name = ?", "David") assert_equal 2, posts.size - count = Post.includes(:author, :comments).limit(2).references(:author).where("authors.name = ?", 'David').count + count = Post.includes(:author, :comments).limit(2).references(:author).where("authors.name = ?", "David").count assert_equal posts.size, count end def test_eager_with_has_many_and_limit_and_high_offset - posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10, :where => { 'authors.name' => 'David' }).to_a + posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, offset: 10, where: { "authors.name" => "David" }).to_a assert_equal 0, posts.size end def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_array_conditions assert_queries(1) do posts = Post.references(:authors, :comments). - merge(:includes => [ :author, :comments ], :limit => 2, :offset => 10, - :where => [ "authors.name = ? and comments.body = ?", 'David', 'go crazy' ]).to_a + merge(includes: [ :author, :comments ], limit: 2, offset: 10, + where: [ "authors.name = ? and comments.body = ?", "David", "go crazy" ]).to_a assert_equal 0, posts.size end end def test_eager_with_has_many_and_limit_and_high_offset_and_multiple_hash_conditions assert_queries(1) do - posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10, - :where => { 'authors.name' => 'David', 'comments.body' => 'go crazy' }).to_a + posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, offset: 10, + where: { "authors.name" => "David", "comments.body" => "go crazy" }).to_a assert_equal 0, posts.size end end def test_count_eager_with_has_many_and_limit_and_high_offset - posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :offset => 10, :where => { 'authors.name' => 'David' }).count(:all) + posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, offset: 10, where: { "authors.name" => "David" }).count(:all) assert_equal 0, posts end def test_eager_with_has_many_and_limit_with_no_results - posts = Post.all.merge!(:includes => [ :author, :comments ], :limit => 2, :where => "posts.title = 'magic forest'").to_a + posts = Post.all.merge!(includes: [ :author, :comments ], limit: 2, where: "posts.title = 'magic forest'").to_a assert_equal 0, posts.size end def test_eager_count_performed_on_a_has_many_association_with_multi_table_conditional author = authors(:david) author_posts_without_comments = author.posts.select { |post| post.comments.blank? } - assert_equal author_posts_without_comments.size, author.posts.includes(:comments).where('comments.id is null').references(:comments).count + assert_equal author_posts_without_comments.size, author.posts.includes(:comments).where("comments.id is null").references(:comments).count end def test_eager_count_performed_on_a_has_many_through_association_with_multi_table_conditional @@ -621,13 +625,13 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_has_and_belongs_to_many_and_limit - posts = Post.all.merge!(:includes => :categories, :order => "posts.id", :limit => 3).to_a + posts = Post.all.merge!(includes: :categories, order: "posts.id", limit: 3).to_a assert_equal 3, posts.size assert_equal 2, posts[0].categories.size assert_equal 1, posts[1].categories.size assert_equal 0, posts[2].categories.size - assert posts[0].categories.include?(categories(:technology)) - assert posts[1].categories.include?(categories(:general)) + assert_includes posts[0].categories, categories(:technology) + assert_includes posts[1].categories, categories(:general) end # Since the preloader for habtm gets raw row hashes from the database and then @@ -687,32 +691,32 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_association_loading_with_habtm - posts = Post.all.merge!(:includes => :categories, :order => "posts.id").to_a + posts = Post.all.merge!(includes: :categories, order: "posts.id").to_a assert_equal 2, posts[0].categories.size assert_equal 1, posts[1].categories.size assert_equal 0, posts[2].categories.size - assert posts[0].categories.include?(categories(:technology)) - assert posts[1].categories.include?(categories(:general)) + assert_includes posts[0].categories, categories(:technology) + assert_includes posts[1].categories, categories(:general) end def test_eager_with_inheritance - SpecialPost.all.merge!(:includes => [ :comments ]).to_a + SpecialPost.all.merge!(includes: [ :comments ]).to_a end def test_eager_has_one_with_association_inheritance - post = Post.all.merge!(:includes => [ :very_special_comment ]).find(4) + post = Post.all.merge!(includes: [ :very_special_comment ]).find(4) assert_equal "VerySpecialComment", post.very_special_comment.class.to_s end def test_eager_has_many_with_association_inheritance - post = Post.all.merge!(:includes => [ :special_comments ]).find(4) + post = Post.all.merge!(includes: [ :special_comments ]).find(4) post.special_comments.each do |special_comment| assert special_comment.is_a?(SpecialComment) end end def test_eager_habtm_with_association_inheritance - post = Post.all.merge!(:includes => [ :special_categories ]).find(6) + post = Post.all.merge!(includes: [ :special_categories ]).find(6) assert_equal 1, post.special_categories.size post.special_categories.each do |special_category| assert_equal "SpecialCategory", special_category.class.to_s @@ -721,8 +725,8 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_with_has_one_dependent_does_not_destroy_dependent assert_not_nil companies(:first_firm).account - f = Firm.all.merge!(:includes => :account, - :where => ["companies.name = ?", "37signals"]).first + f = Firm.all.merge!(includes: :account, + where: ["companies.name = ?", "37signals"]).first assert_not_nil f.account assert_equal companies(:first_firm, :reload).account, f.account end @@ -736,37 +740,37 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_with_invalid_association_reference assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") { - Post.all.merge!(:includes=> :monkeys ).find(6) + Post.all.merge!(includes: :monkeys ).find(6) } assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") { - Post.all.merge!(:includes=>[ :monkeys ]).find(6) + Post.all.merge!(includes: [ :monkeys ]).find(6) } assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") { - Post.all.merge!(:includes=>[ 'monkeys' ]).find(6) + Post.all.merge!(includes: [ "monkeys" ]).find(6) } assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") { - Post.all.merge!(:includes=>[ :monkeys, :elephants ]).find(6) + Post.all.merge!(includes: [ :monkeys, :elephants ]).find(6) } end def test_eager_has_many_through_with_order - tag = OrderedTag.create(name: 'Foo') - post1 = Post.create!(title: 'Beaches', body: "I like beaches!") - post2 = Post.create!(title: 'Pools', body: "I like pools!") + tag = OrderedTag.create(name: "Foo") + post1 = Post.create!(title: "Beaches", body: "I like beaches!") + post2 = Post.create!(title: "Pools", body: "I like pools!") - Tagging.create!(taggable_type: 'Post', taggable_id: post1.id, tag: tag) - Tagging.create!(taggable_type: 'Post', taggable_id: post2.id, tag: tag) + Tagging.create!(taggable_type: "Post", taggable_id: post1.id, tag: tag) + Tagging.create!(taggable_type: "Post", taggable_id: post2.id, tag: tag) tag_with_includes = OrderedTag.includes(:tagged_posts).find(tag.id) assert_equal(tag_with_includes.taggings.map(&:taggable).map(&:title), tag_with_includes.tagged_posts.map(&:title)) end def test_eager_has_many_through_multiple_with_order - tag1 = OrderedTag.create!(name: 'Bar') - tag2 = OrderedTag.create!(name: 'Foo') + tag1 = OrderedTag.create!(name: "Bar") + tag2 = OrderedTag.create!(name: "Foo") - post1 = Post.create!(title: 'Beaches', body: "I like beaches!") - post2 = Post.create!(title: 'Pools', body: "I like pools!") + post1 = Post.create!(title: "Beaches", body: "I like beaches!") + post2 = Post.create!(title: "Pools", body: "I like pools!") Tagging.create!(taggable: post1, tag: tag1) Tagging.create!(taggable: post2, tag: tag1) @@ -782,7 +786,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_default_scope - developer = EagerDeveloperWithDefaultScope.where(:name => 'David').first + developer = EagerDeveloperWithDefaultScope.where(name: "David").first projects = Project.order(:id).to_a assert_no_queries do assert_equal(projects, developer.projects) @@ -790,7 +794,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_default_scope_as_class_method - developer = EagerDeveloperWithClassMethodDefaultScope.where(:name => 'David').first + developer = EagerDeveloperWithClassMethodDefaultScope.where(name: "David").first projects = Project.order(:id).to_a assert_no_queries do assert_equal(projects, developer.projects) @@ -807,7 +811,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_default_scope_as_class_method_using_find_by_method - developer = EagerDeveloperWithClassMethodDefaultScope.find_by(name: 'David') + developer = EagerDeveloperWithClassMethodDefaultScope.find_by(name: "David") projects = Project.order(:id).to_a assert_no_queries do assert_equal(projects, developer.projects) @@ -815,7 +819,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_default_scope_as_lambda - developer = EagerDeveloperWithLambdaDefaultScope.where(:name => 'David').first + developer = EagerDeveloperWithLambdaDefaultScope.where(name: "David").first projects = Project.order(:id).to_a assert_no_queries do assert_equal(projects, developer.projects) @@ -824,8 +828,8 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_with_default_scope_as_block # warm up the habtm cache - EagerDeveloperWithBlockDefaultScope.where(:name => 'David').first.projects - developer = EagerDeveloperWithBlockDefaultScope.where(:name => 'David').first + EagerDeveloperWithBlockDefaultScope.where(name: "David").first.projects + developer = EagerDeveloperWithBlockDefaultScope.where(name: "David").first projects = Project.order(:id).to_a assert_no_queries do assert_equal(projects, developer.projects) @@ -833,7 +837,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_eager_with_default_scope_as_callable - developer = EagerDeveloperWithCallableDefaultScope.where(:name => 'David').first + developer = EagerDeveloperWithCallableDefaultScope.where(name: "David").first projects = Project.order(:id).to_a assert_no_queries do assert_equal(projects, developer.projects) @@ -841,22 +845,22 @@ class EagerAssociationTest < ActiveRecord::TestCase end def find_all_ordered(className, include=nil) - className.all.merge!(:order=>"#{className.table_name}.#{className.primary_key}", :includes=>include).to_a + className.all.merge!(order: "#{className.table_name}.#{className.primary_key}", includes: include).to_a end def test_limited_eager_with_order assert_equal( posts(:thinking, :sti_comments), Post.all.merge!( - :includes => [:author, :comments], :where => { 'authors.name' => 'David' }, - :order => 'UPPER(posts.title)', :limit => 2, :offset => 1 + includes: [:author, :comments], where: { "authors.name" => "David" }, + order: "UPPER(posts.title)", limit: 2, offset: 1 ).to_a ) assert_equal( posts(:sti_post_and_comments, :sti_comments), Post.all.merge!( - :includes => [:author, :comments], :where => { 'authors.name' => 'David' }, - :order => 'UPPER(posts.title) DESC', :limit => 2, :offset => 1 + includes: [:author, :comments], where: { "authors.name" => "David" }, + order: "UPPER(posts.title) DESC", limit: 2, offset: 1 ).to_a ) end @@ -865,15 +869,15 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal( posts(:thinking, :sti_comments), Post.all.merge!( - :includes => [:author, :comments], :where => { 'authors.name' => 'David' }, - :order => ['UPPER(posts.title)', 'posts.id'], :limit => 2, :offset => 1 + includes: [:author, :comments], where: { "authors.name" => "David" }, + order: ["UPPER(posts.title)", "posts.id"], limit: 2, offset: 1 ).to_a ) assert_equal( posts(:sti_post_and_comments, :sti_comments), Post.all.merge!( - :includes => [:author, :comments], :where => { 'authors.name' => 'David' }, - :order => ['UPPER(posts.title) DESC', 'posts.id'], :limit => 2, :offset => 1 + includes: [:author, :comments], where: { "authors.name" => "David" }, + order: ["UPPER(posts.title) DESC", "posts.id"], limit: 2, offset: 1 ).to_a ) end @@ -882,25 +886,25 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal( people(:david, :susan), Person.references(:number1_fans_people).merge( - :includes => [:readers, :primary_contact, :number1_fan], - :where => "number1_fans_people.first_name like 'M%'", - :order => 'people.id', :limit => 2, :offset => 0 + includes: [:readers, :primary_contact, :number1_fan], + where: "number1_fans_people.first_name like 'M%'", + order: "people.id", limit: 2, offset: 0 ).to_a ) end def test_polymorphic_type_condition - post = Post.all.merge!(:includes => :taggings).find(posts(:thinking).id) - assert post.taggings.include?(taggings(:thinking_general)) - post = SpecialPost.all.merge!(:includes => :taggings).find(posts(:thinking).id) - assert post.taggings.include?(taggings(:thinking_general)) + post = Post.all.merge!(includes: :taggings).find(posts(:thinking).id) + assert_includes post.taggings, taggings(:thinking_general) + post = SpecialPost.all.merge!(includes: :taggings).find(posts(:thinking).id) + assert_includes post.taggings, taggings(:thinking_general) end def test_eager_with_multiple_associations_with_same_table_has_many_and_habtm # Eager includes of has many and habtm associations aren't necessarily sorted in the same way def assert_equal_after_sort(item1, item2, item3 = nil) - assert_equal(item1.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) - assert_equal(item3.sort{|a,b| a.id <=> b.id}, item2.sort{|a,b| a.id <=> b.id}) if item3 + assert_equal(item1.sort { |a,b| a.id <=> b.id }, item2.sort { |a,b| a.id <=> b.id }) + assert_equal(item3.sort { |a,b| a.id <=> b.id }, item2.sort { |a,b| a.id <=> b.id }) if item3 end # Test regular association, association with conditions, association with # STI, and association with conditions assured not to be true @@ -943,24 +947,24 @@ class EagerAssociationTest < ActiveRecord::TestCase end end def test_eager_with_valid_association_as_string_not_symbol - assert_nothing_raised { Post.all.merge!(:includes => 'comments').to_a } + assert_nothing_raised { Post.all.merge!(includes: "comments").to_a } end def test_eager_with_floating_point_numbers assert_queries(2) do # Before changes, the floating point numbers will be interpreted as table names and will cause this to run in one query - Comment.all.merge!(:where => "123.456 = 123.456", :includes => :post).to_a + Comment.all.merge!(where: "123.456 = 123.456", includes: :post).to_a end end def test_preconfigured_includes_with_belongs_to author = posts(:welcome).author_with_posts - assert_no_queries {assert_equal 5, author.posts.size} + assert_no_queries { assert_equal 5, author.posts.size } end def test_preconfigured_includes_with_has_one comment = posts(:sti_comments).very_special_comment_with_post - assert_no_queries {assert_equal posts(:sti_comments), comment.post} + assert_no_queries { assert_equal posts(:sti_comments), comment.post } end def test_eager_association_with_scope_with_joins @@ -1002,13 +1006,13 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_association_loading_notification - notifications = messages_for('instantiation.active_record') do - Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size + notifications = messages_for("instantiation.active_record") do + Developer.all.merge!(includes: "projects", where: { "developers_projects.access_level" => 1 }, limit: 5).to_a.size end message = notifications.first payload = message.last - count = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size + count = Developer.all.merge!(includes: "projects", where: { "developers_projects.access_level" => 1 }, limit: 5).to_a.size # eagerloaded row count should be greater than just developer count assert_operator payload[:record_count], :>, count @@ -1016,7 +1020,7 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_base_messages - notifications = messages_for('instantiation.active_record') do + notifications = messages_for("instantiation.active_record") do Developer.all.to_a end message = notifications.first @@ -1044,55 +1048,55 @@ class EagerAssociationTest < ActiveRecord::TestCase end def test_conditions_on_join_table_with_include_and_limit - assert_equal 3, Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a.size + assert_equal 3, Developer.all.merge!(includes: "projects", where: { "developers_projects.access_level" => 1 }, limit: 5).to_a.size end def test_dont_create_temporary_active_record_instances Developer.instance_count = 0 - developers = Developer.all.merge!(:includes => 'projects', :where => { 'developers_projects.access_level' => 1 }, :limit => 5).to_a + developers = Developer.all.merge!(includes: "projects", where: { "developers_projects.access_level" => 1 }, limit: 5).to_a assert_equal developers.count, Developer.instance_count end def test_order_on_join_table_with_include_and_limit - assert_equal 5, Developer.all.merge!(:includes => 'projects', :order => 'developers_projects.joined_on DESC', :limit => 5).to_a.size + assert_equal 5, Developer.all.merge!(includes: "projects", order: "developers_projects.joined_on DESC", limit: 5).to_a.size end def test_eager_loading_with_order_on_joined_table_preloads posts = assert_queries(2) do - Post.all.merge!(:joins => :comments, :includes => :author, :order => 'comments.id DESC').to_a + Post.all.merge!(joins: :comments, includes: :author, order: "comments.id DESC").to_a end assert_equal posts(:eager_other), posts[1] - assert_equal authors(:mary), assert_no_queries { posts[1].author} + assert_equal authors(:mary), assert_no_queries { posts[1].author } end def test_eager_loading_with_conditions_on_joined_table_preloads posts = assert_queries(2) do - Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => [:comments], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a + Post.all.merge!(select: "distinct posts.*", includes: :author, joins: [:comments], where: "comments.body like 'Thank you%'", order: "posts.id").to_a end assert_equal [posts(:welcome)], posts - assert_equal authors(:david), assert_no_queries { posts[0].author} + assert_equal authors(:david), assert_no_queries { posts[0].author } posts = assert_queries(2) do - Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => [:comments], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a + Post.all.merge!(select: "distinct posts.*", includes: :author, joins: [:comments], where: "comments.body like 'Thank you%'", order: "posts.id").to_a end assert_equal [posts(:welcome)], posts - assert_equal authors(:david), assert_no_queries { posts[0].author} + assert_equal authors(:david), assert_no_queries { posts[0].author } posts = assert_queries(2) do - Post.all.merge!(:includes => :author, :joins => {:taggings => :tag}, :where => "tags.name = 'General'", :order => 'posts.id').to_a + Post.all.merge!(includes: :author, joins: { taggings: :tag }, where: "tags.name = 'General'", order: "posts.id").to_a end assert_equal posts(:welcome, :thinking), posts posts = assert_queries(2) do - Post.all.merge!(:includes => :author, :joins => {:taggings => {:tag => :taggings}}, :where => "taggings_tags.super_tag_id=2", :order => 'posts.id').to_a + Post.all.merge!(includes: :author, joins: { taggings: { tag: :taggings } }, where: "taggings_tags.super_tag_id=2", order: "posts.id").to_a end assert_equal posts(:welcome, :thinking), posts end def test_preload_has_many_with_association_condition_and_default_scope - post = Post.create!(:title => 'Beaches', :body => "I like beaches!") - Reader.create! :person => people(:david), :post => post - LazyReader.create! :person => people(:susan), :post => post + post = Post.create!(title: "Beaches", body: "I like beaches!") + Reader.create! person: people(:david), post: post + LazyReader.create! person: people(:susan), post: post assert_equal 1, post.lazy_readers.to_a.size assert_equal 2, post.lazy_readers_skimmers_or_not.to_a.size @@ -1103,39 +1107,39 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_eager_loading_with_conditions_on_string_joined_table_preloads posts = assert_queries(2) do - Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => "INNER JOIN comments on comments.post_id = posts.id", :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a + Post.all.merge!(select: "distinct posts.*", includes: :author, joins: "INNER JOIN comments on comments.post_id = posts.id", where: "comments.body like 'Thank you%'", order: "posts.id").to_a end assert_equal [posts(:welcome)], posts - assert_equal authors(:david), assert_no_queries { posts[0].author} + assert_equal authors(:david), assert_no_queries { posts[0].author } posts = assert_queries(2) do - Post.all.merge!(:select => 'distinct posts.*', :includes => :author, :joins => ["INNER JOIN comments on comments.post_id = posts.id"], :where => "comments.body like 'Thank you%'", :order => 'posts.id').to_a + Post.all.merge!(select: "distinct posts.*", includes: :author, joins: ["INNER JOIN comments on comments.post_id = posts.id"], where: "comments.body like 'Thank you%'", order: "posts.id").to_a end assert_equal [posts(:welcome)], posts - assert_equal authors(:david), assert_no_queries { posts[0].author} + assert_equal authors(:david), assert_no_queries { posts[0].author } end def test_eager_loading_with_select_on_joined_table_preloads posts = assert_queries(2) do - Post.all.merge!(:select => 'posts.*, authors.name as author_name', :includes => :comments, :joins => :author, :order => 'posts.id').to_a + Post.all.merge!(select: "posts.*, authors.name as author_name", includes: :comments, joins: :author, order: "posts.id").to_a end - assert_equal 'David', posts[0].author_name - assert_equal posts(:welcome).comments, assert_no_queries { posts[0].comments} + assert_equal "David", posts[0].author_name + assert_equal posts(:welcome).comments, assert_no_queries { posts[0].comments } end def test_eager_loading_with_conditions_on_join_model_preloads authors = assert_queries(2) do - Author.all.merge!(:includes => :author_address, :joins => :comments, :where => "posts.title like 'Welcome%'").to_a + Author.all.merge!(includes: :author_address, joins: :comments, where: "posts.title like 'Welcome%'").to_a end assert_equal authors(:david), authors[0] assert_equal author_addresses(:david_address), authors[0].author_address end def test_preload_belongs_to_uses_exclusive_scope - people = Person.males.merge(:includes => :primary_contact).to_a + people = Person.males.merge(includes: :primary_contact).to_a assert_not_equal people.length, 0 people.each do |person| - assert_no_queries {assert_not_nil person.primary_contact} + assert_no_queries { assert_not_nil person.primary_contact } assert_equal Person.find(person.id).primary_contact, person.primary_contact end end @@ -1159,9 +1163,9 @@ class EagerAssociationTest < ActiveRecord::TestCase expected = Firm.find(1).clients_using_primary_key.sort_by(&:name) # Oracle adapter truncates alias to 30 characters if current_adapter?(:OracleAdapter) - firm = Firm.all.merge!(:includes => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies'[0,30]+'.name').find(1) + firm = Firm.all.merge!(includes: :clients_using_primary_key, order: "clients_using_primary_keys_companies"[0,30]+".name").find(1) else - firm = Firm.all.merge!(:includes => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies.name').find(1) + firm = Firm.all.merge!(includes: :clients_using_primary_key, order: "clients_using_primary_keys_companies.name").find(1) end assert_no_queries do assert_equal expected, firm.clients_using_primary_key @@ -1170,7 +1174,7 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_preload_has_one_using_primary_key expected = accounts(:signals37) - firm = Firm.all.merge!(:includes => :account_using_primary_key, :order => 'companies.id').first + firm = Firm.all.merge!(includes: :account_using_primary_key, order: "companies.id").first assert_no_queries do assert_equal expected, firm.account_using_primary_key end @@ -1178,35 +1182,35 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_include_has_one_using_primary_key expected = accounts(:signals37) - firm = Firm.all.merge!(:includes => :account_using_primary_key, :order => 'accounts.id').to_a.detect {|f| f.id == 1} + firm = Firm.all.merge!(includes: :account_using_primary_key, order: "accounts.id").to_a.detect { |f| f.id == 1 } assert_no_queries do assert_equal expected, firm.account_using_primary_key end end def test_preloading_empty_belongs_to - c = Client.create!(:name => 'Foo', :client_of => Company.maximum(:id) + 1) + c = Client.create!(name: "Foo", client_of: Company.maximum(:id) + 1) client = assert_queries(2) { Client.preload(:firm).find(c.id) } assert_no_queries { assert_nil client.firm } end def test_preloading_empty_belongs_to_polymorphic - t = Tagging.create!(:taggable_type => 'Post', :taggable_id => Post.maximum(:id) + 1, :tag => tags(:general)) + t = Tagging.create!(taggable_type: "Post", taggable_id: Post.maximum(:id) + 1, tag: tags(:general)) tagging = assert_queries(2) { Tagging.preload(:taggable).find(t.id) } assert_no_queries { assert_nil tagging.taggable } end def test_preloading_through_empty_belongs_to - c = Client.create!(:name => 'Foo', :client_of => Company.maximum(:id) + 1) + c = Client.create!(name: "Foo", client_of: Company.maximum(:id) + 1) client = assert_queries(2) { Client.preload(:accounts).find(c.id) } assert_no_queries { assert client.accounts.empty? } end def test_preloading_has_many_through_with_distinct - mary = Author.includes(:unique_categorized_posts).where(:id => authors(:mary).id).first + mary = Author.includes(:unique_categorized_posts).where(id: authors(:mary).id).first assert_equal 1, mary.unique_categorized_posts.length assert_equal 1, mary.unique_categorized_post_ids.length end @@ -1234,13 +1238,13 @@ class EagerAssociationTest < ActiveRecord::TestCase groucho = members(:groucho) sponsor = assert_queries(2) { - Sponsor.includes(:thing).where(:id => sponsor.id).first + Sponsor.includes(:thing).where(id: sponsor.id).first } assert_no_queries { assert_equal groucho, sponsor.thing } end def test_joins_with_includes_should_preload_via_joins - post = assert_queries(1) { Post.includes(:comments).joins(:comments).order('posts.id desc').to_a.first } + post = assert_queries(1) { Post.includes(:comments).joins(:comments).order("posts.id desc").to_a.first } assert_queries(0) do assert_not_equal 0, post.comments.to_a.count @@ -1249,16 +1253,16 @@ class EagerAssociationTest < ActiveRecord::TestCase def test_join_eager_with_empty_order_should_generate_valid_sql assert_nothing_raised do - Post.includes(:comments).order("").where(:comments => {:body => "Thank you for the welcome"}).first + Post.includes(:comments).order("").where(comments: { body: "Thank you for the welcome" }).first end end def test_deep_including_through_habtm # warm up habtm cache - posts = Post.all.merge!(:includes => {:categories => :categorizations}, :order => "posts.id").to_a + posts = Post.all.merge!(includes: { categories: :categorizations }, order: "posts.id").to_a posts[0].categories[0].categorizations.length - posts = Post.all.merge!(:includes => {:categories => :categorizations}, :order => "posts.id").to_a + posts = Post.all.merge!(includes: { categories: :categorizations }, order: "posts.id").to_a assert_no_queries { assert_equal 2, posts[0].categories[0].categorizations.length } assert_no_queries { assert_equal 1, posts[0].categories[1].categorizations.length } assert_no_queries { assert_equal 2, posts[1].categories[0].categorizations.length } @@ -1275,19 +1279,19 @@ class EagerAssociationTest < ActiveRecord::TestCase end test "scoping with a circular preload" do - assert_equal Comment.find(1), Comment.preload(:post => :comments).scoping { Comment.find(1) } + assert_equal Comment.find(1), Comment.preload(post: :comments).scoping { Comment.find(1) } end test "circular preload does not modify unscoped" do expected = FirstPost.unscoped.find(2) - FirstPost.preload(:comments => :first_post).find(1) + FirstPost.preload(comments: :first_post).find(1) assert_equal expected, FirstPost.unscoped.find(2) end test "preload ignores the scoping" do assert_equal( Comment.find(1).post, - Post.where('1 = 0').scoping { Comment.preload(:post).find(1).post } + Post.where("1 = 0").scoping { Comment.preload(:post).find(1).post } ) end @@ -1312,10 +1316,10 @@ class EagerAssociationTest < ActiveRecord::TestCase end test "works in combination with order(:symbol) and reorder(:symbol)" do - author = Author.includes(:posts).references(:posts).order(:name).find_by('posts.title IS NOT NULL') + author = Author.includes(:posts).references(:posts).order(:name).find_by("posts.title IS NOT NULL") assert_equal authors(:bob), author - author = Author.includes(:posts).references(:posts).reorder(:name).find_by('posts.title IS NOT NULL') + author = Author.includes(:posts).references(:posts).reorder(:name).find_by("posts.title IS NOT NULL") assert_equal authors(:bob), author end @@ -1341,6 +1345,7 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_nothing_raised do authors(:david).essays.includes(:writer).any? + authors(:david).essays.includes(:writer).exists? end end @@ -1355,7 +1360,7 @@ class EagerAssociationTest < ActiveRecord::TestCase test "including associations with where.not adds implicit references" do author = assert_queries(2) { - Author.includes(:posts).where.not(posts: { title: 'Welcome to the weblog'} ).last + Author.includes(:posts).where.not(posts: { title: "Welcome to the weblog" } ).last } assert_no_queries { @@ -1389,7 +1394,7 @@ class EagerAssociationTest < ActiveRecord::TestCase exception = assert_raises(ArgumentError) do Author.preload(10).to_a end - assert_equal('10 was not recognized for preload', exception.message) + assert_equal("10 was not recognized for preload", exception.message) end test "associations with extensions are not instance dependent" do @@ -1419,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! @@ -1433,17 +1456,17 @@ 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 - post = Post.includes(:tags).references(:tags).where('tags.name = ?', 'General').first + post = Post.includes(:tags).references(:tags).where("tags.name = ?", "General").first assert_equal posts(:welcome), post end test "eager-loading a polymorphic association with references to the associated table" do - post = Post.eager_load(:tags).where('tags.name = ?', 'General').first + post = Post.eager_load(:tags).where("tags.name = ?", "General").first assert_equal posts(:welcome), post end diff --git a/activerecord/test/cases/associations/extension_test.rb b/activerecord/test/cases/associations/extension_test.rb index b161cde335..cc86e1a16d 100644 --- a/activerecord/test/cases/associations/extension_test.rb +++ b/activerecord/test/cases/associations/extension_test.rb @@ -1,10 +1,10 @@ require "cases/helper" -require 'models/post' -require 'models/comment' -require 'models/project' -require 'models/developer' -require 'models/computer' -require 'models/company_in_module' +require "models/post" +require "models/comment" +require "models/project" +require "models/developer" +require "models/computer" +require "models/company_in_module" class AssociationsExtensionsTest < ActiveRecord::TestCase fixtures :projects, :developers, :developers_projects, :comments, :posts @@ -63,19 +63,19 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase extend!(Developer) extend!(MyApplication::Business::Developer) - assert Object.const_get 'DeveloperAssociationNameAssociationExtension' - assert MyApplication::Business.const_get 'DeveloperAssociationNameAssociationExtension' + assert Object.const_get "DeveloperAssociationNameAssociationExtension" + assert MyApplication::Business.const_get "DeveloperAssociationNameAssociationExtension" end def test_proxy_association_after_scoped post = posts(:welcome) assert_equal post.association(:comments), post.comments.the_association - assert_equal post.association(:comments), post.comments.where('1=1').the_association + assert_equal post.association(:comments), post.comments.where("1=1").the_association end private def extend!(model) - ActiveRecord::Associations::Builder::HasMany.define_extensions(model, :association_name) { } + ActiveRecord::Associations::Builder::HasMany.define_extensions(model, :association_name) {} end end diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 1bbca84bb2..06fc7a4388 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -1,84 +1,85 @@ require "cases/helper" -require 'models/developer' -require 'models/computer' -require 'models/project' -require 'models/company' -require 'models/course' -require 'models/customer' -require 'models/order' -require 'models/categorization' -require 'models/category' -require 'models/post' -require 'models/author' -require 'models/tag' -require 'models/tagging' -require 'models/parrot' -require 'models/person' -require 'models/pirate' -require 'models/professor' -require 'models/treasure' -require 'models/price_estimate' -require 'models/club' -require 'models/member' -require 'models/membership' -require 'models/sponsor' -require 'models/country' -require 'models/treaty' -require 'models/vertex' -require 'models/publisher' -require 'models/publisher/article' -require 'models/publisher/magazine' -require 'active_support/core_ext/string/conversions' +require "models/developer" +require "models/computer" +require "models/project" +require "models/company" +require "models/course" +require "models/customer" +require "models/order" +require "models/categorization" +require "models/category" +require "models/post" +require "models/author" +require "models/tag" +require "models/tagging" +require "models/parrot" +require "models/person" +require "models/pirate" +require "models/professor" +require "models/treasure" +require "models/price_estimate" +require "models/club" +require "models/user" +require "models/member" +require "models/membership" +require "models/sponsor" +require "models/country" +require "models/treaty" +require "models/vertex" +require "models/publisher" +require "models/publisher/article" +require "models/publisher/magazine" +require "active_support/core_ext/string/conversions" class ProjectWithAfterCreateHook < ActiveRecord::Base - self.table_name = 'projects' + self.table_name = "projects" has_and_belongs_to_many :developers, - :class_name => "DeveloperForProjectWithAfterCreateHook", - :join_table => "developers_projects", - :foreign_key => "project_id", - :association_foreign_key => "developer_id" + class_name: "DeveloperForProjectWithAfterCreateHook", + join_table: "developers_projects", + foreign_key: "project_id", + association_foreign_key: "developer_id" after_create :add_david def add_david - david = DeveloperForProjectWithAfterCreateHook.find_by_name('David') + david = DeveloperForProjectWithAfterCreateHook.find_by_name("David") david.projects << self end end class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" has_and_belongs_to_many :projects, - :class_name => "ProjectWithAfterCreateHook", - :join_table => "developers_projects", - :association_foreign_key => "project_id", - :foreign_key => "developer_id" + class_name: "ProjectWithAfterCreateHook", + join_table: "developers_projects", + association_foreign_key: "project_id", + foreign_key: "developer_id" end class ProjectWithSymbolsForKeys < ActiveRecord::Base - self.table_name = 'projects' + self.table_name = "projects" has_and_belongs_to_many :developers, - :class_name => "DeveloperWithSymbolsForKeys", - :join_table => :developers_projects, - :foreign_key => :project_id, - :association_foreign_key => "developer_id" + class_name: "DeveloperWithSymbolsForKeys", + join_table: :developers_projects, + foreign_key: :project_id, + association_foreign_key: "developer_id" end class DeveloperWithSymbolsForKeys < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" has_and_belongs_to_many :projects, - :class_name => "ProjectWithSymbolsForKeys", - :join_table => :developers_projects, - :association_foreign_key => :project_id, - :foreign_key => "developer_id" + class_name: "ProjectWithSymbolsForKeys", + join_table: :developers_projects, + association_foreign_key: :project_id, + foreign_key: "developer_id" end class SubDeveloper < Developer - self.table_name = 'developers' + self.table_name = "developers" has_and_belongs_to_many :special_projects, - :join_table => 'developers_projects', - :foreign_key => "project_id", - :association_foreign_key => "developer_id" + join_table: "developers_projects", + foreign_key: "project_id", + association_foreign_key: "developer_id" end class DeveloperWithSymbolClassName < Developer @@ -88,7 +89,7 @@ end class DeveloperWithExtendOption < Developer module NamedExtension def category - 'sns' + "sns" end end @@ -96,8 +97,8 @@ class DeveloperWithExtendOption < Developer end class ProjectUnscopingDavidDefaultScope < ActiveRecord::Base - self.table_name = 'projects' - has_and_belongs_to_many :developers, -> { unscope(where: 'name') }, + self.table_name = "projects" + has_and_belongs_to_many :developers, -> { unscope(where: "name") }, class_name: "LazyBlockDeveloperCalledDavid", join_table: "developers_projects", foreign_key: "project_id", @@ -109,14 +110,14 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase :parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings, :computers def setup_data_for_habtm_case - ActiveRecord::Base.connection.execute('delete from countries_treaties') + ActiveRecord::Base.connection.execute("delete from countries_treaties") - country = Country.new(:name => 'India') - country.country_id = 'c1' + country = Country.new(name: "India") + country.country_id = "c1" country.save! - treaty = Treaty.new(:name => 'peace') - treaty.treaty_id = 't1' + treaty = Treaty.new(name: "peace") + treaty.treaty_id = "t1" country.treaties << treaty end @@ -130,33 +131,33 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase setup_data_for_habtm_case con = ActiveRecord::Base.connection - sql = 'select * from countries_treaties' + sql = "select * from countries_treaties" record = con.select_rows(sql).last - assert_equal 'c1', record[0] - assert_equal 't1', record[1] + assert_equal "c1", record[0] + assert_equal "t1", record[1] end def test_proper_usage_of_primary_keys_and_join_table setup_data_for_habtm_case - assert_equal 'country_id', Country.primary_key - assert_equal 'treaty_id', Treaty.primary_key + assert_equal "country_id", Country.primary_key + assert_equal "treaty_id", Treaty.primary_key country = Country.first assert_equal 1, country.treaties.count end def test_join_table_composite_primary_key_should_not_warn - country = Country.new(:name => 'India') - country.country_id = 'c1' + country = Country.new(name: "India") + country.country_id = "c1" country.save! - treaty = Treaty.new(:name => 'peace') - treaty.treaty_id = 't1' + treaty = Treaty.new(name: "peace") + treaty.treaty_id = "t1" warning = capture(:stderr) do country.treaties << treaty end - assert_no_match(/WARNING: Rails does not support composite primary key\./, warning) + assert_no_match(/WARNING: Active Record does not support composite primary key\./, warning) end def test_has_and_belongs_to_many @@ -168,7 +169,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase active_record = Project.find(1) assert !active_record.developers.empty? assert_equal 3, active_record.developers.size - assert active_record.developers.include?(david) + assert_includes active_record.developers, david end def test_adding_single @@ -257,7 +258,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_habtm_saving_multiple_relationships new_project = Project.new("name" => "Grimetime") amount_of_developers = 4 - developers = (0...amount_of_developers).collect {|i| Developer.create(:name => "JME #{i}") }.reverse + developers = (0...amount_of_developers).collect { |i| Developer.create(name: "JME #{i}") }.reverse new_project.developer_ids = [developers[0].id, developers[1].id] new_project.developers_with_callback_ids = [developers[2].id, developers[3].id] @@ -282,11 +283,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end def test_habtm_collection_size_from_params - devel = Developer.new({ + devel = Developer.new( projects_attributes: { - '0' => {} - } - }) + "0" => {} + }) assert_equal 1, devel.projects.size end @@ -322,9 +322,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end def test_build_by_new_record - devel = Developer.new(:name => "Marcel", :salary => 75000) - devel.projects.build(:name => "Make bed") - proj2 = devel.projects.build(:name => "Lie in it") + devel = Developer.new(name: "Marcel", salary: 75000) + devel.projects.build(name: "Make bed") + proj2 = devel.projects.build(name: "Lie in it") assert_equal devel.projects.last, proj2 assert !proj2.persisted? devel.save @@ -347,9 +347,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end def test_create_by_new_record - devel = Developer.new(:name => "Marcel", :salary => 75000) - devel.projects.build(:name => "Make bed") - proj2 = devel.projects.build(:name => "Lie in it") + devel = Developer.new(name: "Marcel", salary: 75000) + devel.projects.build(name: "Make bed") + proj2 = devel.projects.build(name: "Lie in it") assert_equal devel.projects.last, proj2 assert !proj2.persisted? devel.save @@ -361,16 +361,16 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_creation_respects_hash_condition # in Oracle '' is saved as null therefore need to save ' ' in not null column - post = categories(:general).post_with_conditions.build(:body => ' ') + post = categories(:general).post_with_conditions.build(body: " ") assert post.save - assert_equal 'Yet Another Testing Title', post.title + assert_equal "Yet Another Testing Title", post.title # in Oracle '' is saved as null therefore need to save ' ' in not null column - another_post = categories(:general).post_with_conditions.create(:body => ' ') + another_post = categories(:general).post_with_conditions.create(body: " ") assert another_post.persisted? - assert_equal 'Yet Another Testing Title', another_post.title + assert_equal "Yet Another Testing Title", another_post.title end def test_distinct_after_the_fact @@ -544,7 +544,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_no_queries(ignore_none: false) do assert project.developers.loaded? - assert project.developers.include?(developer) + assert_includes project.developers, developer end end @@ -555,14 +555,14 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase project.reload assert ! project.developers.loaded? assert_queries(1) do - assert project.developers.include?(developer) + assert_includes project.developers, developer end assert ! project.developers.loaded? end def test_include_returns_false_for_non_matching_record_to_verify_scoping project = projects(:active_record) - developer = Developer.create :name => "Bryan", :salary => 50_000 + developer = Developer.create name: "Bryan", salary: 50_000 assert ! project.developers.loaded? assert ! project.developers.include?(developer) @@ -576,32 +576,32 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_dynamic_find_should_respect_association_order # Developers are ordered 'name DESC, id DESC' - high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis') + high_id_jamis = projects(:active_record).developers.create(name: "Jamis") - assert_equal high_id_jamis, projects(:active_record).developers.merge(:where => "name = 'Jamis'").first - assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis') + assert_equal high_id_jamis, projects(:active_record).developers.merge(where: "name = 'Jamis'").first + assert_equal high_id_jamis, projects(:active_record).developers.find_by_name("Jamis") end def test_find_should_append_to_association_order - ordered_developers = projects(:active_record).developers.order('projects.id') - assert_equal ['developers.name desc, developers.id desc', 'projects.id'], ordered_developers.order_values + ordered_developers = projects(:active_record).developers.order("projects.id") + assert_equal ["developers.name desc, developers.id desc", "projects.id"], ordered_developers.order_values end def test_dynamic_find_all_should_respect_readonly_access - projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save! } if d.valid?} + projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save! } if d.valid? } projects(:active_record).readonly_developers.each(&:readonly?) end def test_new_with_values_in_collection - jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis') - david = DeveloperForProjectWithAfterCreateHook.find_by_name('David') - project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie") + jamis = DeveloperForProjectWithAfterCreateHook.find_by_name("Jamis") + david = DeveloperForProjectWithAfterCreateHook.find_by_name("David") + project = ProjectWithAfterCreateHook.new(name: "Cooking with Bertie") project.developers << jamis project.save! project.reload - assert project.developers.include?(jamis) - assert project.developers.include?(david) + assert_includes project.developers, jamis + assert_includes project.developers, david end def test_find_in_association_with_options @@ -612,8 +612,8 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end def test_association_with_extend_option - eponine = DeveloperWithExtendOption.create(name: 'Eponine') - assert_equal 'sns', eponine.projects.category + eponine = DeveloperWithExtendOption.create(name: "Eponine") + assert_equal "sns", eponine.projects.category end def test_replace_with_less @@ -628,7 +628,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")] david.save assert_equal 2, david.projects.length - assert !david.projects.include?(projects(:active_record)) + assert_not_includes david.projects, projects(:active_record) end def test_replace_on_new_object @@ -646,9 +646,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase developer.special_projects << special_project developer.reload - assert developer.projects.include?(special_project) - assert developer.special_projects.include?(special_project) - assert !developer.special_projects.include?(other_project) + assert_includes developer.projects, special_project + assert_includes developer.special_projects, special_project + assert_not_includes developer.special_projects, other_project end def test_symbol_join_table @@ -689,7 +689,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end def test_habtm_respects_select_query_method - assert_equal ['id'], developers(:david).projects.select(:id).first.attributes.keys + assert_equal ["id"], developers(:david).projects.select(:id).first.attributes.keys end def test_join_table_alias @@ -700,8 +700,8 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal( 3, Developer.references(:developers_projects_join).merge( - :includes => {:projects => :developers}, - :where => 'projects_developers_projects_join.joined_on IS NOT NULL' + includes: { projects: :developers }, + where: "projects_developers_projects_join.joined_on IS NOT NULL" ).to_a.size ) end @@ -720,15 +720,15 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal( 3, Developer.references(:developers_projects_join).merge( - :includes => {:projects => :developers}, :where => 'projects_developers_projects_join.joined_on IS NOT NULL', - :group => group.join(",") + includes: { projects: :developers }, where: "projects_developers_projects_join.joined_on IS NOT NULL", + group: group.join(",") ).to_a.size ) end def test_find_grouped - all_posts_from_category1 = Post.all.merge!(:where => "category_id = 1", :joins => :categories).to_a - grouped_posts_of_category1 = Post.all.merge!(:where => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories).to_a + all_posts_from_category1 = Post.all.merge!(where: "category_id = 1", joins: :categories).to_a + grouped_posts_of_category1 = Post.all.merge!(where: "category_id = 1", group: "author_id", select: "count(posts.id) as posts_count", joins: :categories).to_a assert_equal 5, all_posts_from_category1.size assert_equal 2, grouped_posts_of_category1.size end @@ -775,7 +775,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_assign_ids_ignoring_blanks developer = Developer.new("name" => "Joe") - developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, ''] + developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, ""] developer.save developer.reload assert_equal 2, developer.projects.length @@ -795,8 +795,8 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end def test_symbols_as_keys - developer = DeveloperWithSymbolsForKeys.new(:name => 'David') - project = ProjectWithSymbolsForKeys.new(:name => 'Rails Testing') + developer = DeveloperWithSymbolsForKeys.new(name: "David") + project = ProjectWithSymbolsForKeys.new(name: "Rails Testing") project.developers << developer project.save! @@ -809,7 +809,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_dynamic_find_should_respect_association_include # SQL error in sort clause if :include is not included # due to Unknown column 'authors.id' - assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog') + assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title("Welcome to the weblog") end def test_count @@ -841,12 +841,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end def test_attributes_are_being_set_when_initialized_from_habtm_association_with_where_clause - new_developer = projects(:action_controller).developers.where(:name => "Marcelo").build + new_developer = projects(:action_controller).developers.where(name: "Marcelo").build assert_equal new_developer.name, "Marcelo" end def test_attributes_are_being_set_when_initialized_from_habtm_association_with_multiple_where_clauses - new_developer = projects(:action_controller).developers.where(:name => "Marcelo").where(:salary => 90_000).build + new_developer = projects(:action_controller).developers.where(name: "Marcelo").where(salary: 90_000).build assert_equal new_developer.name, "Marcelo" assert_equal new_developer.salary, 90_000 end @@ -854,7 +854,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_include_method_in_has_and_belongs_to_many_association_should_return_true_for_instance_added_with_build project = Project.new developer = project.developers.build - assert project.developers.include?(developer) + assert_includes project.developers, developer end def test_destruction_does_not_error_without_primary_key @@ -871,7 +871,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase projects = Developer.new.projects assert_no_queries(ignore_none: false) do assert_equal [], projects - assert_equal [], projects.where(title: 'omg') + assert_equal [], projects.where(title: "omg") assert_equal [], projects.pluck(:title) assert_equal 0, projects.count end @@ -885,7 +885,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase treasure.valid? assert_equal 1, treasure.rich_people.size - assert_nil rich_person.first_name, 'should not run associated person validation on create when validate: false' + assert_nil rich_person.first_name, "should not run associated person validation on create when validate: false" end def test_association_with_validate_false_does_not_run_associated_validation_callbacks_on_update @@ -898,11 +898,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase treasure.valid? assert_equal 1, treasure.rich_people.size - assert_equal person_first_name, rich_person.first_name, 'should not run associated person validation on update when validate: false' + assert_equal person_first_name, rich_person.first_name, "should not run associated person validation on update when validate: false" end def test_custom_join_table - assert_equal 'edges', Vertex.reflect_on_association(:sources).join_table + assert_equal "edges", Vertex.reflect_on_association(:sources).join_table end def test_has_and_belongs_to_many_in_a_namespaced_model_pointing_to_a_namespaced_model @@ -926,11 +926,11 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_redefine_habtm child = SubDeveloper.new("name" => "Aredridel") child.special_projects << SpecialProject.new("name" => "Special Project") - assert child.save, 'child object should be saved' + assert child.save, "child object should be saved" end def test_habtm_with_reflection_using_class_name_and_fixtures - assert_not_nil Developer._reflections['shared_computers'] + assert_not_nil Developer._reflections["shared_computers"] # Checking the fixture for named association is important here, because it's the only way # we've been able to reproduce this bug assert_not_nil File.read(File.expand_path("../../../fixtures/developers.yml", __FILE__)).index("shared_computers") @@ -995,4 +995,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase Project.first.developers_required_by_default.create!(name: "Sean", salary: 50000) end end + + def test_association_name_is_the_same_as_join_table_name + user = User.create! + assert_nothing_raised { user.jobs_pool.clear } + end end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index e975f4fbdd..0ce67f971b 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -1,43 +1,43 @@ require "cases/helper" -require 'models/developer' -require 'models/computer' -require 'models/project' -require 'models/company' -require 'models/contract' -require 'models/topic' -require 'models/reply' -require 'models/category' -require 'models/image' -require 'models/post' -require 'models/author' -require 'models/essay' -require 'models/comment' -require 'models/person' -require 'models/reader' -require 'models/tagging' -require 'models/tag' -require 'models/invoice' -require 'models/line_item' -require 'models/car' -require 'models/bulb' -require 'models/engine' -require 'models/categorization' -require 'models/minivan' -require 'models/speedometer' -require 'models/reference' -require 'models/job' -require 'models/college' -require 'models/student' -require 'models/pirate' -require 'models/ship' -require 'models/ship_part' -require 'models/treasure' -require 'models/parrot' -require 'models/tyre' -require 'models/subscriber' -require 'models/subscription' -require 'models/zine' -require 'models/interest' +require "models/developer" +require "models/computer" +require "models/project" +require "models/company" +require "models/contract" +require "models/topic" +require "models/reply" +require "models/category" +require "models/image" +require "models/post" +require "models/author" +require "models/essay" +require "models/comment" +require "models/person" +require "models/reader" +require "models/tagging" +require "models/tag" +require "models/invoice" +require "models/line_item" +require "models/car" +require "models/bulb" +require "models/engine" +require "models/categorization" +require "models/minivan" +require "models/speedometer" +require "models/reference" +require "models/job" +require "models/college" +require "models/student" +require "models/pirate" +require "models/ship" +require "models/ship_part" +require "models/treasure" +require "models/parrot" +require "models/tyre" +require "models/subscriber" +require "models/subscription" +require "models/zine" +require "models/interest" class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCase fixtures :authors, :posts, :comments @@ -46,7 +46,7 @@ class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCa author = authors(:david) # this can fail on adapters which require ORDER BY expressions to be included in the SELECT expression # if the reorder clauses are not correctly handled - assert author.posts_with_comments_sorted_by_comment_id.where('comments.id > 0').reorder('posts.comments_count DESC', 'posts.tags_count DESC').last + assert author.posts_with_comments_sorted_by_comment_id.where("comments.id > 0").reorder("posts.comments_count DESC", "posts.tags_count DESC").last end end @@ -54,18 +54,18 @@ class HasManyAssociationsTestPrimaryKeys < ActiveRecord::TestCase fixtures :authors, :essays, :subscribers, :subscriptions, :people def test_custom_primary_key_on_new_record_should_fetch_with_query - subscriber = Subscriber.new(nick: 'webster132') + subscriber = Subscriber.new(nick: "webster132") assert !subscriber.subscriptions.loaded? assert_queries 1 do assert_equal 2, subscriber.subscriptions.size end - assert_equal subscriber.subscriptions, Subscription.where(subscriber_id: 'webster132') + assert_equal subscriber.subscriptions, Subscription.where(subscriber_id: "webster132") end def test_association_primary_key_on_new_record_should_fetch_with_query - author = Author.new(:name => "David") + author = Author.new(name: "David") assert !author.essays.loaded? assert_queries 1 do @@ -116,14 +116,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_anonymous_has_many developer = Class.new(ActiveRecord::Base) { - self.table_name = 'developers' + self.table_name = "developers" dev = self developer_project = Class.new(ActiveRecord::Base) { - self.table_name = 'developers_projects' - belongs_to :developer, :anonymous_class => dev + self.table_name = "developers_projects" + belongs_to :developer, anonymous_class: dev } - has_many :developer_projects, :anonymous_class => developer_project, :foreign_key => 'developer_id' + has_many :developer_projects, anonymous_class: developer_project, foreign_key: "developer_id" } dev = developer.first named = Developer.find(dev.id) @@ -135,20 +135,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_default_scope_on_relations_is_not_cached counter = 0 posts = Class.new(ActiveRecord::Base) { - self.table_name = 'posts' - self.inheritance_column = 'not_there' + self.table_name = "posts" + self.inheritance_column = "not_there" post = self comments = Class.new(ActiveRecord::Base) { - self.table_name = 'comments' - self.inheritance_column = 'not_there' - belongs_to :post, :anonymous_class => post + self.table_name = "comments" + self.inheritance_column = "not_there" + belongs_to :post, anonymous_class: post default_scope -> { counter += 1 - where("id = :inc", :inc => counter) + where("id = :inc", inc: counter) } } - has_many :comments, :anonymous_class => comments, :foreign_key => 'post_id' + has_many :comments, anonymous_class: comments, foreign_key: "post_id" } assert_equal 0, counter post = posts.first @@ -159,15 +159,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_has_many_build_with_options - college = College.create(name: 'UFMT') - Student.create(active: true, college_id: college.id, name: 'Sarah') + college = College.create(name: "UFMT") + Student.create(active: true, college_id: college.id, name: "Sarah") assert_equal college.students, Student.where(active: true, college_id: college.id) end def test_add_record_to_collection_should_change_its_updated_at - ship = Ship.create(name: 'dauntless') - part = ShipPart.create(name: 'cockpit') + ship = Ship.create(name: "dauntless") + part = ShipPart.create(name: "cockpit") updated_at = part.updated_at travel(1.second) do @@ -181,8 +181,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_clear_collection_should_not_change_updated_at # GH#17161: .clear calls delete_all (and returns the association), # which is intended to not touch associated objects's updated_at field - ship = Ship.create(name: 'dauntless') - part = ShipPart.create(name: 'cockpit', ship_id: ship.id) + ship = Ship.create(name: "dauntless") + part = ShipPart.create(name: "cockpit", ship_id: ship.id) ship.parts.clear part.reload @@ -192,27 +192,27 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_create_from_association_should_respect_default_scope - car = Car.create(:name => 'honda') - assert_equal 'honda', car.name + car = Car.create(name: "honda") + assert_equal "honda", car.name bulb = Bulb.create - assert_equal 'defaulty', bulb.name + assert_equal "defaulty", bulb.name bulb = car.bulbs.build - assert_equal 'defaulty', bulb.name + assert_equal "defaulty", bulb.name bulb = car.bulbs.create - assert_equal 'defaulty', bulb.name + assert_equal "defaulty", bulb.name end def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope - car = Car.create(name: 'honda') + car = Car.create(name: "honda") - bulb = car.bulbs.build(name: 'exotic') - assert_equal 'exotic', bulb.name + bulb = car.bulbs.build(name: "exotic") + assert_equal "exotic", bulb.name - bulb = car.bulbs.create(name: 'exotic') - assert_equal 'exotic', bulb.name + bulb = car.bulbs.create(name: "exotic") + assert_equal "exotic", bulb.name bulb = car.awesome_bulbs.build(frickinawesome: false) assert_equal false, bulb.frickinawesome @@ -225,36 +225,37 @@ class HasManyAssociationsTest < ActiveRecord::TestCase author = Author.new post = author.thinking_posts.build - assert_equal 'So I was thinking', post.title + assert_equal "So I was thinking", post.title end def test_create_from_association_with_nil_values_should_work - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") bulb = car.bulbs.new(nil) - assert_equal 'defaulty', bulb.name + assert_equal "defaulty", bulb.name bulb = car.bulbs.build(nil) - assert_equal 'defaulty', bulb.name + assert_equal "defaulty", bulb.name bulb = car.bulbs.create(nil) - assert_equal 'defaulty', bulb.name + assert_equal "defaulty", bulb.name end def test_do_not_call_callbacks_for_delete_all - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") car.funky_bulbs.create! + assert_equal 1, car.funky_bulbs.count assert_nothing_raised { car.reload.funky_bulbs.delete_all } - assert_equal 0, Bulb.count, "bulbs should have been deleted using :delete_all strategy" + assert_equal 0, car.funky_bulbs.count, "bulbs should have been deleted using :delete_all strategy" end def test_delete_all_on_association_is_the_same_as_not_loaded author = authors :david - author.thinking_posts.create!(:body => "test") + author.thinking_posts.create!(body: "test") author.reload expected_sql = capture_sql { author.thinking_posts.delete_all } - author.thinking_posts.create!(:body => "test") + author.thinking_posts.create!(body: "test") author.reload author.thinking_posts.inspect loaded_sql = capture_sql { author.thinking_posts.delete_all } @@ -263,11 +264,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_delete_all_on_association_with_nil_dependency_is_the_same_as_not_loaded author = authors :david - author.posts.create!(:title => "test", :body => "body") + author.posts.create!(title: "test", body: "body") author.reload expected_sql = capture_sql { author.posts.delete_all } - author.posts.create!(:title => "test", :body => "body") + author.posts.create!(title: "test", body: "body") author.reload author.posts.to_a loaded_sql = capture_sql { author.posts.delete_all } @@ -282,29 +283,29 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_building_the_associated_object_with_explicit_sti_base_class firm = DependentFirm.new - company = firm.companies.build(:type => "Company") + company = firm.companies.build(type: "Company") assert_kind_of Company, company, "Expected #{company.class} to be a Company" end def test_building_the_associated_object_with_sti_subclass firm = DependentFirm.new - company = firm.companies.build(:type => "Client") + company = firm.companies.build(type: "Client") assert_kind_of Client, company, "Expected #{company.class} to be a Client" end def test_building_the_associated_object_with_an_invalid_type firm = DependentFirm.new - assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(:type => "Invalid") } + assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(type: "Invalid") } end def test_building_the_associated_object_with_an_unrelated_type firm = DependentFirm.new - assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(:type => "Account") } + assert_raise(ActiveRecord::SubclassNotFound) { firm.companies.build(type: "Account") } end test "building the association with an array" do speedometer = Speedometer.new(speedometer_id: "a") - data = [{name: "first"}, {name: "second"}] + data = [{ name: "first" }, { name: "second" }] speedometer.minivans.build(data) assert_equal 2, speedometer.minivans.size @@ -313,24 +314,24 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_association_keys_bypass_attribute_protection - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") bulb = car.bulbs.new assert_equal car.id, bulb.car_id - bulb = car.bulbs.new :car_id => car.id + 1 + bulb = car.bulbs.new car_id: car.id + 1 assert_equal car.id, bulb.car_id bulb = car.bulbs.build assert_equal car.id, bulb.car_id - bulb = car.bulbs.build :car_id => car.id + 1 + bulb = car.bulbs.build car_id: car.id + 1 assert_equal car.id, bulb.car_id bulb = car.bulbs.create assert_equal car.id, bulb.car_id - bulb = car.bulbs.create :car_id => car.id + 1 + bulb = car.bulbs.create car_id: car.id + 1 assert_equal car.id, bulb.car_id end @@ -340,19 +341,19 @@ class HasManyAssociationsTest < ActiveRecord::TestCase line_item = invoice.line_items.new assert_equal invoice.id, line_item.invoice_id - line_item = invoice.line_items.new :invoice_id => invoice.id + 1 + line_item = invoice.line_items.new invoice_id: invoice.id + 1 assert_equal invoice.id, line_item.invoice_id line_item = invoice.line_items.build assert_equal invoice.id, line_item.invoice_id - line_item = invoice.line_items.build :invoice_id => invoice.id + 1 + line_item = invoice.line_items.build invoice_id: invoice.id + 1 assert_equal invoice.id, line_item.invoice_id line_item = invoice.line_items.create assert_equal invoice.id, line_item.invoice_id - line_item = invoice.line_items.create :invoice_id => invoice.id + 1 + line_item = invoice.line_items.create invoice_id: invoice.id + 1 assert_equal invoice.id, line_item.invoice_id end @@ -373,64 +374,95 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_no_sql_should_be_fired_if_association_already_loaded - Car.create(:name => 'honda') + Car.create(name: "honda") bulbs = Car.first.bulbs bulbs.to_a # to load all instances of bulbs assert_no_queries do bulbs.first() - bulbs.first({}) end assert_no_queries do bulbs.second() - bulbs.second({}) end assert_no_queries do bulbs.third() - bulbs.third({}) end assert_no_queries do bulbs.fourth() - bulbs.fourth({}) end assert_no_queries do bulbs.fifth() - bulbs.fifth({}) end assert_no_queries do bulbs.forty_two() - bulbs.forty_two({}) end assert_no_queries do bulbs.third_to_last() - bulbs.third_to_last({}) end assert_no_queries do bulbs.second_to_last() - bulbs.second_to_last({}) end assert_no_queries do bulbs.last() - bulbs.last({}) + end + end + + def test_finder_method_with_dirty_target + company = companies(:first_firm) + new_clients = [] + assert_no_queries(ignore_none: false) do + new_clients << company.clients_of_firm.build(name: "Another Client") + new_clients << company.clients_of_firm.build(name: "Another Client II") + new_clients << company.clients_of_firm.build(name: "Another Client III") + end + + assert_not company.clients_of_firm.loaded? + assert_queries(1) do + assert_same new_clients[0], company.clients_of_firm.third + assert_same new_clients[1], company.clients_of_firm.fourth + assert_same new_clients[2], company.clients_of_firm.fifth + assert_same new_clients[0], company.clients_of_firm.third_to_last + assert_same new_clients[1], company.clients_of_firm.second_to_last + assert_same new_clients[2], company.clients_of_firm.last + end + end + + def test_finder_bang_method_with_dirty_target + company = companies(:first_firm) + new_clients = [] + assert_no_queries(ignore_none: false) do + new_clients << company.clients_of_firm.build(name: "Another Client") + new_clients << company.clients_of_firm.build(name: "Another Client II") + new_clients << company.clients_of_firm.build(name: "Another Client III") + end + + assert_not company.clients_of_firm.loaded? + assert_queries(1) do + assert_same new_clients[0], company.clients_of_firm.third! + assert_same new_clients[1], company.clients_of_firm.fourth! + assert_same new_clients[2], company.clients_of_firm.fifth! + assert_same new_clients[0], company.clients_of_firm.third_to_last! + assert_same new_clients[1], company.clients_of_firm.second_to_last! + assert_same new_clients[2], company.clients_of_firm.last! end end def test_create_resets_cached_counters - person = Person.create!(:first_name => 'tenderlove') + person = Person.create!(first_name: "tenderlove") post = Post.first assert_equal [], person.readers assert_nil person.readers.find_by_post_id(post.id) - person.readers.create(:post_id => post.id) + person.readers.create(post_id: post.id) assert_equal 1, person.readers.count assert_equal 1, person.readers.length @@ -438,25 +470,41 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal person, person.readers.first.person end - def force_signal37_to_load_all_clients_of_firm - companies(:first_firm).clients_of_firm.each {|f| } + def test_update_all_respects_association_scope + person = Person.new + person.first_name = "Naruto" + person.references << Reference.new + person.id = 10 + person.references + person.save! + assert_equal 1, person.references.update_all(favourite: true) + end + + def test_exists_respects_association_scope + person = Person.new + person.first_name = "Sasuke" + person.references << Reference.new + person.id = 10 + person.references + person.save! + assert_predicate person.references, :exists? end # sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first def test_counting_with_counter_sql - assert_equal 3, Firm.all.merge!(:order => "id").first.clients.count + assert_equal 3, Firm.all.merge!(order: "id").first.clients.count end def test_counting - assert_equal 3, Firm.all.merge!(:order => "id").first.plain_clients.count + assert_equal 3, Firm.all.merge!(order: "id").first.plain_clients.count end def test_counting_with_single_hash - assert_equal 1, Firm.all.merge!(:order => "id").first.plain_clients.where(:name => "Microsoft").count + assert_equal 1, Firm.all.merge!(order: "id").first.plain_clients.where(name: "Microsoft").count end def test_counting_with_column_name_and_hash - assert_equal 3, Firm.all.merge!(:order => "id").first.plain_clients.count(:name) + assert_equal 3, Firm.all.merge!(order: "id").first.plain_clients.count(:name) end def test_counting_with_association_limit @@ -466,11 +514,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_finding - assert_equal 3, Firm.all.merge!(:order => "id").first.clients.length + assert_equal 3, Firm.all.merge!(order: "id").first.clients.length end def test_finding_array_compatibility - assert_equal 3, Firm.order(:id).find{|f| f.id > 0}.clients.length + assert_equal 3, Firm.order(:id).find { |f| f.id > 0 }.clients.length end def test_find_many_with_merged_options @@ -480,13 +528,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_find_should_append_to_association_order - ordered_clients = companies(:first_firm).clients_sorted_desc.order('companies.id') - assert_equal ['id DESC', 'companies.id'], ordered_clients.order_values + ordered_clients = companies(:first_firm).clients_sorted_desc.order("companies.id") + assert_equal ["id DESC", "companies.id"], ordered_clients.order_values end def test_dynamic_find_should_respect_association_order assert_equal companies(:another_first_firm_client), companies(:first_firm).clients_sorted_desc.where("type = 'Client'").first - assert_equal companies(:another_first_firm_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client') + assert_equal companies(:another_first_firm_client), companies(:first_firm).clients_sorted_desc.find_by_type("Client") end def test_taking @@ -508,14 +556,18 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_taking_with_a_number # taking from unloaded Relation bob = Author.find(authors(:bob).id) + new_post = bob.posts.build + assert_not bob.posts.loaded? assert_equal [posts(:misc_by_bob)], bob.posts.take(1) - bob = Author.find(authors(:bob).id) assert_equal [posts(:misc_by_bob), posts(:other_by_bob)], bob.posts.take(2) + assert_equal [posts(:misc_by_bob), posts(:other_by_bob), new_post], bob.posts.take(3) # taking from loaded Relation - bob.posts.to_a - assert_equal [posts(:misc_by_bob)], authors(:bob).posts.take(1) - assert_equal [posts(:misc_by_bob), posts(:other_by_bob)], authors(:bob).posts.take(2) + bob.posts.load + assert bob.posts.loaded? + assert_equal [posts(:misc_by_bob)], bob.posts.take(1) + assert_equal [posts(:misc_by_bob), posts(:other_by_bob)], bob.posts.take(2) + assert_equal [posts(:misc_by_bob), posts(:other_by_bob), new_post], bob.posts.take(3) end def test_taking_with_inverse_of @@ -534,45 +586,45 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_finding_default_orders - assert_equal "Summit", Firm.all.merge!(:order => "id").first.clients.first.name + assert_equal "Summit", Firm.all.merge!(order: "id").first.clients.first.name end def test_finding_with_different_class_name_and_order - assert_equal "Apex", Firm.all.merge!(:order => "id").first.clients_sorted_desc.first.name + assert_equal "Apex", Firm.all.merge!(order: "id").first.clients_sorted_desc.first.name end def test_finding_with_foreign_key - assert_equal "Microsoft", Firm.all.merge!(:order => "id").first.clients_of_firm.first.name + assert_equal "Microsoft", Firm.all.merge!(order: "id").first.clients_of_firm.first.name end def test_finding_with_condition - assert_equal "Microsoft", Firm.all.merge!(:order => "id").first.clients_like_ms.first.name + assert_equal "Microsoft", Firm.all.merge!(order: "id").first.clients_like_ms.first.name end def test_finding_with_condition_hash - assert_equal "Microsoft", Firm.all.merge!(:order => "id").first.clients_like_ms_with_hash_conditions.first.name + assert_equal "Microsoft", Firm.all.merge!(order: "id").first.clients_like_ms_with_hash_conditions.first.name end def test_finding_using_primary_key - assert_equal "Summit", Firm.all.merge!(:order => "id").first.clients_using_primary_key.first.name + assert_equal "Summit", Firm.all.merge!(order: "id").first.clients_using_primary_key.first.name end def test_update_all_on_association_accessed_before_save - firm = Firm.new(name: 'Firm') + firm = Firm.new(name: "Firm") clients_proxy_id = firm.clients.object_id firm.clients << Client.first firm.save! - assert_equal firm.clients.count, firm.clients.update_all(description: 'Great!') + assert_equal firm.clients.count, firm.clients.update_all(description: "Great!") assert_not_equal clients_proxy_id, firm.clients.object_id end def test_update_all_on_association_accessed_before_save_with_explicit_foreign_key # We can use the same cached proxy object because the id is available for the scope - firm = Firm.new(name: 'Firm', id: 100) + firm = Firm.new(name: "Firm", id: 100) clients_proxy_id = firm.clients.object_id firm.clients << Client.first firm.save! - assert_equal firm.clients.count, firm.clients.update_all(description: 'Great!') + assert_equal firm.clients.count, firm.clients.update_all(description: "Great!") assert_equal clients_proxy_id, firm.clients.object_id end @@ -582,7 +634,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_find_ids - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find } @@ -601,9 +653,23 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) } end + def test_find_one_message_on_primary_key + firm = Firm.all.merge!(order: "id").first + + e = assert_raises(ActiveRecord::RecordNotFound) do + firm.clients.find(0) + end + assert_equal 0, e.id + assert_equal "id", e.primary_key + assert_equal "Client", e.model + assert_match (/\ACouldn't find Client with 'id'=0/), e.message + end + def test_find_ids_and_inverse_of force_signal37_to_load_all_clients_of_firm + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + firm = companies(:first_firm) client = firm.clients_of_firm.find(3) assert_kind_of Client, client @@ -614,7 +680,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_find_all - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first assert_equal 3, firm.clients.where("#{QUOTED_TYPE} = 'Client'").to_a.length assert_equal 1, firm.clients.where("name = 'Summit'").to_a.length end @@ -625,7 +691,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert ! firm.clients.loaded? assert_queries(4) do - firm.clients.find_each(:batch_size => 1) {|c| assert_equal firm.id, c.firm_id } + firm.clients.find_each(batch_size: 1) { |c| assert_equal firm.id, c.firm_id } end assert ! firm.clients.loaded? @@ -635,7 +701,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase firm = companies(:first_firm) assert_queries(2) do - firm.clients.where(name: 'Microsoft').find_each(batch_size: 1) do |c| + firm.clients.where(name: "Microsoft").find_each(batch_size: 1) do |c| assert_equal firm.id, c.firm_id assert_equal "Microsoft", c.name end @@ -650,8 +716,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert ! firm.clients.loaded? assert_queries(2) do - firm.clients.find_in_batches(:batch_size => 2) do |clients| - clients.each {|c| assert_equal firm.id, c.firm_id } + firm.clients.find_in_batches(batch_size: 2) do |clients| + clients.each { |c| assert_equal firm.id, c.firm_id } end end @@ -660,29 +726,29 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_find_all_sanitized # sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first summit = firm.clients.where("name = 'Summit'").to_a assert_equal summit, firm.clients.where("name = ?", "Summit").to_a - assert_equal summit, firm.clients.where("name = :name", { :name => "Summit" }).to_a + assert_equal summit, firm.clients.where("name = :name", name: "Summit").to_a end def test_find_first - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first client2 = Client.find(2) assert_equal firm.clients.first, firm.clients.order("id").first assert_equal client2, firm.clients.where("#{QUOTED_TYPE} = 'Client'").order("id").first end def test_find_first_sanitized - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first client2 = Client.find(2) - assert_equal client2, firm.clients.merge!(:where => ["#{QUOTED_TYPE} = ?", 'Client'], :order => "id").first - assert_equal client2, firm.clients.merge!(:where => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }], :order => "id").first + assert_equal client2, firm.clients.merge!(where: ["#{QUOTED_TYPE} = ?", "Client"], order: "id").first + assert_equal client2, firm.clients.merge!(where: ["#{QUOTED_TYPE} = :type", { type: "Client" }], order: "id").first end def test_find_all_with_include_and_conditions assert_nothing_raised do - Developer.all.merge!(:joins => :audit_logs, :where => {'audit_logs.message' => nil, :name => 'Smith'}).to_a + Developer.all.merge!(joins: :audit_logs, where: { "audit_logs.message" => nil, :name => "Smith" }).to_a end end @@ -692,8 +758,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_find_grouped - all_clients_of_firm1 = Client.all.merge!(:where => "firm_id = 1").to_a - grouped_clients_of_firm1 = Client.all.merge!(:where => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count').to_a + all_clients_of_firm1 = Client.all.merge!(where: "firm_id = 1").to_a + grouped_clients_of_firm1 = Client.all.merge!(where: "firm_id = 1", group: "firm_id", select: "firm_id, count(id) as clients_count").to_a assert_equal 3, all_clients_of_firm1.size assert_equal 1, grouped_clients_of_firm1.size end @@ -715,7 +781,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_select_query_method - assert_equal ['id', 'body'], posts(:welcome).comments.select(:id, :body).first.attributes.keys + assert_equal ["id", "body"], posts(:welcome).comments.select(:id, :body).first.attributes.keys end def test_select_with_block @@ -728,6 +794,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_adding force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + natural = Client.new("name" => "Natural Company") companies(:first_firm).clients_of_firm << natural assert_equal 3, companies(:first_firm).clients_of_firm.size # checking via the collection @@ -738,7 +807,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_adding_using_create first_firm = companies(:first_firm) assert_equal 3, first_firm.plain_clients.size - first_firm.plain_clients.create(:name => "Natural Company") + first_firm.plain_clients.create(name: "Natural Company") assert_equal 4, first_firm.plain_clients.length assert_equal 4, first_firm.plain_clients.size end @@ -746,7 +815,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_create_with_bang_on_has_many_when_parent_is_new_raises error = assert_raise(ActiveRecord::RecordNotSaved) do firm = Firm.new - firm.plain_clients.create! :name=>"Whoever" + firm.plain_clients.create! name: "Whoever" end assert_equal "You cannot call create unless the parent is saved", error.message @@ -755,7 +824,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_regular_create_on_has_many_when_parent_is_new_raises error = assert_raise(ActiveRecord::RecordNotSaved) do firm = Firm.new - firm.plain_clients.create :name=>"Whoever" + firm.plain_clients.create name: "Whoever" end assert_equal "You cannot call create unless the parent is saved", error.message @@ -763,7 +832,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_create_with_bang_on_has_many_raises_when_record_not_saved assert_raise(ActiveRecord::RecordInvalid) do - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first firm.plain_clients.create! end end @@ -784,21 +853,24 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_adding_a_collection force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")]) assert_equal 4, companies(:first_firm).clients_of_firm.size assert_equal 4, companies(:first_firm).clients_of_firm.reload.size end def test_transactions_when_adding_to_persisted - good = Client.new(:name => "Good") - bad = Client.new(:name => "Bad", :raise_on_save => true) + good = Client.new(name: "Good") + bad = Client.new(name: "Bad", raise_on_save: true) begin companies(:first_firm).clients_of_firm.concat(good, bad) rescue Client::RaisedOnSave end - assert !companies(:first_firm).clients_of_firm.reload.include?(good) + assert_not_includes companies(:first_firm).clients_of_firm.reload, good end def test_transactions_when_adding_to_new_record @@ -863,7 +935,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build_many company = companies(:first_firm) - new_clients = assert_no_queries(ignore_none: false) { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) } + new_clients = assert_no_queries(ignore_none: false) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) } assert_equal 2, new_clients.size end @@ -880,7 +952,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 1, first_topic.replies.length assert_no_queries do - first_topic.replies.build(:title => "Not saved", :content => "Superstars") + first_topic.replies.build(title: "Not saved", content: "Superstars") assert_equal 2, first_topic.replies.size end @@ -889,7 +961,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build_via_block company = companies(:first_firm) - new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build {|client| client.name = "Another Client" } } + new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build { |client| client.name = "Another Client" } } assert !company.clients_of_firm.loaded? assert_equal "Another Client", new_client.name @@ -900,7 +972,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build_many_via_block company = companies(:first_firm) new_clients = assert_no_queries(ignore_none: false) do - company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client| + company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) do |client| client.name = "changed" end end @@ -919,7 +991,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase first_firm.clients_of_firm.reset assert_queries(1) do - first_firm.clients_of_firm.create(:name => "Superstars") + first_firm.clients_of_firm.create(name: "Superstars") end assert_equal 3, first_firm.clients_of_firm.size @@ -927,6 +999,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_create force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client") assert new_client.persisted? assert_equal new_client, companies(:first_firm).clients_of_firm.last @@ -934,7 +1009,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_create_many - companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}]) + companies(:first_firm).clients_of_firm.create([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) assert_equal 4, companies(:first_firm).clients_of_firm.reload.size end @@ -946,6 +1021,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_deleting force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first) assert_equal 1, companies(:first_firm).clients_of_firm.size assert_equal 1, companies(:first_firm).clients_of_firm.reload.size @@ -962,7 +1040,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_has_many_without_counter_cache_option # Ship has a conventionally named `treasures_count` column, but the counter_cache # option is not given on the association. - ship = Ship.create(name: 'Countless', treasures_count: 10) + ship = Ship.create(name: "Countless", treasures_count: 10) assert_not Ship.reflect_on_association(:treasures).has_cached_counter? @@ -970,7 +1048,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal ship.treasures.size, 0 assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed" do - ship.treasures.create(name: 'Gold') + ship.treasures.create(name: "Gold") end assert_no_difference lambda { ship.reload.treasures_count }, "treasures_count should not be changed" do @@ -1073,10 +1151,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal original_count, topic.replies_count first_reply = topic.replies.first - first_reply.update_attributes(:parent_id => nil) + first_reply.update_attributes(parent_id: nil) assert_equal original_count - 1, topic.reload.replies_count - first_reply.update_attributes(:parent_id => topic.id) + first_reply.update_attributes(parent_id: topic.id) assert_equal original_count, topic.reload.replies_count end @@ -1089,17 +1167,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase reply1 = topic1.replies.first reply2 = topic2.replies.first - reply1.update_attributes(:parent_id => topic2.id) + reply1.update_attributes(parent_id: topic2.id) assert_equal original_count1 - 1, topic1.reload.replies_count assert_equal original_count2 + 1, topic2.reload.replies_count - reply2.update_attributes(:parent_id => topic1.id) + reply2.update_attributes(parent_id: topic1.id) assert_equal original_count1, topic1.reload.replies_count assert_equal original_count2, topic2.reload.replies_count end def test_deleting_a_collection force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + companies(:first_firm).clients_of_firm.create("name" => "Another Client") assert_equal 3, companies(:first_firm).clients_of_firm.size companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1], companies(:first_firm).clients_of_firm[2]]) @@ -1109,6 +1190,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_delete_all force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + companies(:first_firm).dependent_clients_of_firm.create("name" => "Another Client") clients = companies(:first_firm).dependent_clients_of_firm.to_a assert_equal 3, clients.count @@ -1120,6 +1204,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_delete_all_with_not_yet_loaded_association_collection force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + companies(:first_firm).clients_of_firm.create("name" => "Another Client") assert_equal 3, companies(:first_firm).clients_of_firm.size companies(:first_firm).clients_of_firm.reset @@ -1129,8 +1216,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_transaction_when_deleting_persisted - good = Client.new(:name => "Good") - bad = Client.new(:name => "Bad", :raise_on_destroy => true) + good = Client.new(name: "Good") + bad = Client.new(name: "Bad", raise_on_destroy: true) companies(:first_firm).clients_of_firm = [good, bad] @@ -1171,7 +1258,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_clearing_updates_counter_cache topic = Topic.first - assert_difference 'topic.reload.replies_count', -1 do + assert_difference "topic.reload.replies_count", -1 do topic.replies.clear end end @@ -1180,7 +1267,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase car = Car.first car.engines.create! - assert_difference 'car.reload.engines_count', -1 do + assert_difference "car.reload.engines_count", -1 do car.engines.clear end end @@ -1238,8 +1325,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_dependent_association_respects_optional_conditions_on_delete firm = companies(:odegy) - Client.create(:client_of => firm.id, :name => "BigShot Inc.") - Client.create(:client_of => firm.id, :name => "SmallTime Inc.") + Client.create(client_of: firm.id, name: "BigShot Inc.") + Client.create(client_of: firm.id, name: "SmallTime Inc.") # only one of two clients is included in the association due to the :conditions key assert_equal 2, Client.where(client_of: firm.id).size assert_equal 1, firm.dependent_conditional_clients_of_firm.size @@ -1250,8 +1337,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_dependent_association_respects_optional_sanitized_conditions_on_delete firm = companies(:odegy) - Client.create(:client_of => firm.id, :name => "BigShot Inc.") - Client.create(:client_of => firm.id, :name => "SmallTime Inc.") + Client.create(client_of: firm.id, name: "BigShot Inc.") + Client.create(client_of: firm.id, name: "SmallTime Inc.") # only one of two clients is included in the association due to the :conditions key assert_equal 2, Client.where(client_of: firm.id).size assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size @@ -1262,8 +1349,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_dependent_association_respects_optional_hash_conditions_on_delete firm = companies(:odegy) - Client.create(:client_of => firm.id, :name => "BigShot Inc.") - Client.create(:client_of => firm.id, :name => "SmallTime Inc.") + Client.create(client_of: firm.id, name: "BigShot Inc.") + Client.create(client_of: firm.id, name: "SmallTime Inc.") # only one of two clients is included in the association due to the :conditions key assert_equal 2, Client.where(client_of: firm.id).size assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size @@ -1289,12 +1376,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.build assert ms_client.save - assert_equal 'Microsoft', ms_client.name + assert_equal "Microsoft", ms_client.name another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create assert another_ms_client.persisted? - assert_equal 'Microsoft', another_ms_client.name + assert_equal "Microsoft", another_ms_client.name end def test_clearing_without_initial_access @@ -1308,17 +1395,20 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_deleting_a_item_which_is_not_in_the_collection force_signal37_to_load_all_clients_of_firm - summit = Client.find_by_name('Summit') + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + + summit = Client.find_by_name("Summit") companies(:first_firm).clients_of_firm.delete(summit) assert_equal 2, companies(:first_firm).clients_of_firm.size assert_equal 2, companies(:first_firm).clients_of_firm.reload.size assert_equal 2, summit.client_of end - def test_deleting_by_fixnum_id + def test_deleting_by_integer_id david = Developer.find(1) - assert_difference 'david.projects.count', -1 do + assert_difference "david.projects.count", -1 do assert_equal 1, david.projects.delete(1).size end @@ -1328,8 +1418,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_deleting_by_string_id david = Developer.find(1) - assert_difference 'david.projects.count', -1 do - assert_equal 1, david.projects.delete('1').size + assert_difference "david.projects.count", -1 do + assert_equal 1, david.projects.delete("1").size end assert_equal 1, david.projects.size @@ -1344,6 +1434,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_destroying force_signal37_to_load_all_clients_of_firm + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + assert_difference "Client.count", -1 do companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first) end @@ -1352,9 +1444,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 1, companies(:first_firm).clients_of_firm.reload.size end - def test_destroying_by_fixnum_id + def test_destroying_by_integer_id force_signal37_to_load_all_clients_of_firm + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + assert_difference "Client.count", -1 do companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first.id) end @@ -1366,6 +1460,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_destroying_by_string_id force_signal37_to_load_all_clients_of_firm + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + assert_difference "Client.count", -1 do companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first.id.to_s) end @@ -1376,6 +1472,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_destroying_a_collection force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + companies(:first_firm).clients_of_firm.create("name" => "Another Client") assert_equal 3, companies(:first_firm).clients_of_firm.size @@ -1389,6 +1488,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_destroy_all force_signal37_to_load_all_clients_of_firm + + assert_predicate companies(:first_firm).clients_of_firm, :loaded? + clients = companies(:first_firm).clients_of_firm.to_a assert !clients.empty?, "37signals has clients after load" destroyed = companies(:first_firm).clients_of_firm.destroy_all @@ -1402,17 +1504,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase firm = companies(:first_firm) assert_equal 3, firm.clients.size firm.destroy - assert Client.all.merge!(:where => "firm_id=#{firm.id}").to_a.empty? + assert Client.all.merge!(where: "firm_id=#{firm.id}").to_a.empty? end def test_dependence_for_associations_with_hash_condition david = authors(:david) - assert_difference('Post.count', -1) { assert david.destroy } + assert_difference("Post.count", -1) { assert david.destroy } end def test_destroy_dependent_when_deleted_from_association # sometimes tests on Oracle fail if ORDER BY is not provided therefore add always :order with :first - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first assert_equal 3, firm.clients.size client = firm.clients.first @@ -1439,7 +1541,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase firm.destroy rescue "do nothing" - assert_equal 3, Client.all.merge!(:where => "firm_id=#{firm.id}").to_a.size + assert_equal 3, Client.all.merge!(where: "firm_id=#{firm.id}").to_a.size end def test_dependence_on_account @@ -1463,21 +1565,21 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_restrict_with_exception - firm = RestrictedWithExceptionFirm.create!(:name => 'restrict') - firm.companies.create(:name => 'child') + firm = RestrictedWithExceptionFirm.create!(name: "restrict") + firm.companies.create(name: "child") assert !firm.companies.empty? assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy } - assert RestrictedWithExceptionFirm.exists?(:name => 'restrict') - assert firm.companies.exists?(:name => 'child') + assert RestrictedWithExceptionFirm.exists?(name: "restrict") + assert firm.companies.exists?(name: "child") end def test_restrict_with_error_is_deprecated_using_key_many I18n.backend = I18n::Backend::Simple.new - I18n.backend.store_translations :en, activerecord: { errors: { messages: { restrict_dependent_destroy: { many: 'message for deprecated key' } } } } + I18n.backend.store_translations :en, activerecord: { errors: { messages: { restrict_dependent_destroy: { many: "message for deprecated key" } } } } - firm = RestrictedWithErrorFirm.create!(name: 'restrict') - firm.companies.create(name: 'child') + firm = RestrictedWithErrorFirm.create!(name: "restrict") + firm.companies.create(name: "child") assert !firm.companies.empty? @@ -1485,16 +1587,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert !firm.errors.empty? - assert_equal 'message for deprecated key', firm.errors[:base].first - assert RestrictedWithErrorFirm.exists?(name: 'restrict') - assert firm.companies.exists?(name: 'child') + assert_equal "message for deprecated key", firm.errors[:base].first + assert RestrictedWithErrorFirm.exists?(name: "restrict") + assert firm.companies.exists?(name: "child") ensure I18n.backend.reload! end def test_restrict_with_error - firm = RestrictedWithErrorFirm.create!(:name => 'restrict') - firm.companies.create(:name => 'child') + firm = RestrictedWithErrorFirm.create!(name: "restrict") + firm.companies.create(name: "child") assert !firm.companies.empty? @@ -1503,15 +1605,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert !firm.errors.empty? assert_equal "Cannot delete record because dependent companies exist", firm.errors[:base].first - assert RestrictedWithErrorFirm.exists?(:name => 'restrict') - assert firm.companies.exists?(:name => 'child') + assert RestrictedWithErrorFirm.exists?(name: "restrict") + assert firm.companies.exists?(name: "child") end def test_restrict_with_error_with_locale I18n.backend = I18n::Backend::Simple.new - I18n.backend.store_translations 'en', activerecord: {attributes: {restricted_with_error_firm: {companies: 'client companies'}}} - firm = RestrictedWithErrorFirm.create!(name: 'restrict') - firm.companies.create(name: 'child') + I18n.backend.store_translations "en", activerecord: { attributes: { restricted_with_error_firm: { companies: "client companies" } } } + firm = RestrictedWithErrorFirm.create!(name: "restrict") + firm.companies.create(name: "child") assert !firm.companies.empty? @@ -1520,8 +1622,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert !firm.errors.empty? assert_equal "Cannot delete record because dependent client companies exist", firm.errors[:base].first - assert RestrictedWithErrorFirm.exists?(name: 'restrict') - assert firm.companies.exists?(name: 'child') + assert RestrictedWithErrorFirm.exists?(name: "restrict") + assert firm.companies.exists?(name: "child") ensure I18n.backend.reload! end @@ -1531,10 +1633,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_included_in_collection_for_new_records - client = Client.create(:name => 'Persisted') + client = Client.create(name: "Persisted") assert_nil client.client_of assert_equal false, Firm.new.clients_of_firm.include?(client), - 'includes a client that does not belong to any firm' + "includes a client that does not belong to any firm" end def test_adding_array_and_collection @@ -1542,7 +1644,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_replace_with_less - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first firm.clients = [companies(:first_client)] assert firm.save, "Could not save firm" firm.reload @@ -1556,7 +1658,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_replace_with_new - firm = Firm.all.merge!(:order => "id").first + firm = Firm.all.merge!(order: "id").first firm.clients = [companies(:second_client), Client.new("name" => "New Client")] firm.save firm.reload @@ -1589,12 +1691,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase firm.clients = [] end - assert_equal [], firm.send('clients=', []) + assert_equal [], firm.send("clients=", []) end def test_transactions_when_replacing_on_persisted - good = Client.new(:name => "Good") - bad = Client.new(:name => "Bad", :raise_on_save => true) + good = Client.new(name: "Good") + bad = Client.new(name: "Bad", raise_on_save: true) companies(:first_firm).clients_of_firm = [good] @@ -1657,7 +1759,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase contract_a = Contract.create! contract_b = Contract.create! Contract.create! # another contract - company = Company.new(:name => "Some Company") + company = Company.new(name: "Some Company") company.contract_ids = [contract_a.id, contract_b.id] assert_equal [contract_a.id, contract_b.id], company.contract_ids @@ -1669,8 +1771,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_assign_ids_ignoring_blanks - firm = Firm.create!(:name => 'Apple') - firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, ''] + firm = Firm.create!(name: "Apple") + firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, ""] firm.save! assert_equal 2, firm.clients.reload.size @@ -1685,14 +1787,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase [ lambda { authors(:mary).comment_ids = [comments(:greetings).id, comments(:more_greetings).id] }, lambda { authors(:mary).comments = [comments(:greetings), comments(:more_greetings)] }, - lambda { authors(:mary).comments << Comment.create!(:body => "Yay", :post_id => 424242) }, + lambda { authors(:mary).comments << Comment.create!(body: "Yay", post_id: 424242) }, lambda { authors(:mary).comments.delete(authors(:mary).comments.first) }, - ].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) } + ].each { |block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) } end def test_dynamic_find_should_respect_association_order_for_through assert_equal Comment.find(10), authors(:david).comments_desc.where("comments.type = 'SpecialComment'").first - assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type('SpecialComment') + assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type("SpecialComment") end def test_has_many_through_respects_hash_conditions @@ -1726,7 +1828,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_include_returns_false_for_non_matching_record_to_verify_scoping firm = companies(:first_firm) - client = Client.create!(:name => 'Not Associated') + client = Client.create!(name: "Not Associated") assert ! firm.clients.loaded? assert_equal false, firm.clients.include?(client) @@ -1755,7 +1857,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_calling_first_or_last_on_existing_record_with_build_should_load_association firm = companies(:first_firm) - firm.clients.build(:name => 'Foo') + firm.clients.build(name: "Foo") assert !firm.clients.loaded? assert_queries 1 do @@ -1769,7 +1871,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_calling_first_nth_or_last_on_existing_record_with_create_should_not_load_association firm = companies(:first_firm) - firm.clients.create(:name => 'Foo') + firm.clients.create(name: "Foo") assert !firm.clients.loaded? assert_queries 3 do @@ -1793,7 +1895,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_calling_first_or_last_with_integer_on_association_should_not_load_association firm = companies(:first_firm) - firm.clients.create(:name => 'Foo') + firm.clients.create(name: "Foo") assert !firm.clients.loaded? assert_queries 2 do @@ -1923,13 +2025,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase old = ActiveRecord::Base.store_full_sti_class ActiveRecord::Base.store_full_sti_class = true - firm = Namespaced::Firm.create({ :name => 'Some Company' }) - firm.clients.create({ :name => 'Some Client' }) + firm = Namespaced::Firm.create(name: "Some Company") + firm.clients.create(name: "Some Client") stats = Namespaced::Firm.all.merge!( - :select => "#{Namespaced::Firm.table_name}.id, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients", - :joins => :clients, - :group => "#{Namespaced::Firm.table_name}.id" + select: "#{Namespaced::Firm.table_name}.id, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients", + joins: :clients, + group: "#{Namespaced::Firm.table_name}.id" ).find firm.id assert_equal 1, stats.num_clients.to_i ensure @@ -1955,8 +2057,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_creating_using_primary_key - firm = Firm.all.merge!(:order => "id").first - client = firm.clients_using_primary_key.create!(:name => 'test') + firm = Firm.all.merge!(order: "id").first + client = firm.clients_using_primary_key.create!(name: "test") assert_equal firm.name, client.firm_name end @@ -1979,12 +2081,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_attributes_are_being_set_when_initialized_from_has_many_association_with_where_clause - new_comment = posts(:welcome).comments.where(:body => "Some content").build + new_comment = posts(:welcome).comments.where(body: "Some content").build assert_equal new_comment.body, "Some content" end def test_attributes_are_being_set_when_initialized_from_has_many_association_with_multiple_where_clauses - new_comment = posts(:welcome).comments.where(:body => "Some content").where(:type => 'SpecialComment').build + new_comment = posts(:welcome).comments.where(body: "Some content").where(type: "SpecialComment").build assert_equal new_comment.body, "Some content" assert_equal new_comment.type, "SpecialComment" assert_equal new_comment.post_id, posts(:welcome).id @@ -1998,7 +2100,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_load_target_respects_protected_attributes topic = Topic.create! - reply = topic.replies.create(:title => "reply 1") + reply = topic.replies.create(title: "reply 1") reply.approved = false reply.save! @@ -2025,7 +2127,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_merging_with_custom_attribute_writer - bulb = Bulb.new(:color => "red") + bulb = Bulb.new(color: "red") assert_equal "RED!", bulb.color car = Car.create! @@ -2035,13 +2137,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_abstract_class_with_polymorphic_has_many - post = SubStiPost.create! :title => "fooo", :body => "baa" - tagging = Tagging.create! :taggable => post + post = SubStiPost.create! title: "fooo", body: "baa" + tagging = Tagging.create! taggable: post assert_equal [tagging], post.taggings end def test_with_polymorphic_has_many_with_custom_columns_name - post = Post.create! :title => 'foo', :body => 'bar' + post = Post.create! title: "foo", body: "bar" image = Image.create! post.images << image @@ -2051,10 +2153,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_build_with_polymorphic_has_many_does_not_allow_to_override_type_and_id welcome = posts(:welcome) - tagging = welcome.taggings.build(:taggable_id => 99, :taggable_type => 'ShouldNotChange') + tagging = welcome.taggings.build(taggable_id: 99, taggable_type: "ShouldNotChange") assert_equal welcome.id, tagging.taggable_id - assert_equal 'Post', tagging.taggable_type + assert_equal "Post", tagging.taggable_type end def test_dont_call_save_callbacks_twice_on_has_many @@ -2066,30 +2168,30 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_association_attributes_are_available_to_after_initialize - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") bulb = car.bulbs.build - assert_equal car.id, bulb.attributes_after_initialize['car_id'] + assert_equal car.id, bulb.attributes_after_initialize["car_id"] end def test_attributes_are_set_when_initialized_from_has_many_null_relationship - car = Car.new name: 'honda' - bulb = car.bulbs.where(name: 'headlight').first_or_initialize - assert_equal 'headlight', bulb.name + car = Car.new name: "honda" + bulb = car.bulbs.where(name: "headlight").first_or_initialize + assert_equal "headlight", bulb.name end def test_attributes_are_set_when_initialized_from_polymorphic_has_many_null_relationship - post = Post.new title: 'title', body: 'bar' - tag = Tag.create!(name: 'foo') + post = Post.new title: "title", body: "bar" + tag = Tag.create!(name: "foo") tagging = post.taggings.where(tag: tag).first_or_initialize assert_equal tag.id, tagging.tag_id - assert_equal 'Post', tagging.taggable_type + assert_equal "Post", tagging.taggable_type end def test_replace - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") bulb1 = car.bulbs.create bulb2 = Bulb.create @@ -2100,7 +2202,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_replace_returns_target - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") bulb1 = car.bulbs.create bulb2 = car.bulbs.create bulb3 = Bulb.create @@ -2117,15 +2219,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end test "first_or_initialize adds the record to the association" do - firm = Firm.create! name: 'omg' + firm = Firm.create! name: "omg" client = firm.clients_of_firm.first_or_initialize assert_equal [client], firm.clients_of_firm end test "first_or_create adds the record to the association" do - firm = Firm.create! name: 'omg' + firm = Firm.create! name: "omg" firm.clients_of_firm.load_target - client = firm.clients_of_firm.first_or_create name: 'lol' + client = firm.clients_of_firm.first_or_create name: "lol" assert_equal [client], firm.clients_of_firm assert_equal [client], firm.reload.clients_of_firm end @@ -2147,7 +2249,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_no_queries(ignore_none: false) do assert_equal [], post.comments - assert_equal [], post.comments.where(body: 'omg') + assert_equal [], post.comments.where(body: "omg") assert_equal [], post.comments.pluck(:body) assert_equal 0, post.comments.sum(:id) assert_equal 0, post.comments.count @@ -2175,7 +2277,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase david = authors(:david) post = david.posts.first - post.type = 'PostWithSpecialCategorization' + post.type = "PostWithSpecialCategorization" post.save categorization = post.categorizations.first @@ -2188,8 +2290,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end test "does not duplicate associations when used with natural primary keys" do - speedometer = Speedometer.create!(id: '4') - speedometer.minivans.create!(minivan_id: 'a-van-red' ,name: 'a van', color: 'red') + speedometer = Speedometer.create!(id: "4") + speedometer.minivans.create!(minivan_id: "a-van-red" ,name: "a van", color: "red") assert_equal 1, speedometer.minivans.to_a.size, "Only one association should be present:\n#{speedometer.minivans.to_a}" assert_equal 1, speedometer.reload.minivans.to_a.size @@ -2205,7 +2307,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end test "can unscope and where the default scope of the associated model" do - Car.has_many :other_bulbs, -> { unscope(where: [:name]).where(name: 'other') }, class_name: "Bulb" + Car.has_many :other_bulbs, -> { unscope(where: [:name]).where(name: "other") }, class_name: "Bulb" car = Car.create! bulb1 = Bulb.create! name: "defaulty", car: car bulb2 = Bulb.create! name: "other", car: car @@ -2215,7 +2317,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end test "can rewhere the default scope of the associated model" do - Car.has_many :old_bulbs, -> { rewhere(name: 'old') }, class_name: "Bulb" + Car.has_many :old_bulbs, -> { rewhere(name: "old") }, class_name: "Bulb" car = Car.create! bulb1 = Bulb.create! name: "defaulty", car: car bulb2 = Bulb.create! name: "old", car: car @@ -2224,7 +2326,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal [bulb2], car.old_bulbs end - test 'unscopes the default scope of associated model when used with include' do + test "unscopes the default scope of associated model when used with include" do car = Car.create! bulb = Bulb.create! name: "other", car: car @@ -2244,7 +2346,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal "Failed to destroy the record", error.message end - test 'updates counter cache when default scope is given' do + test "updates counter cache when default scope is given" do topic = DefaultRejectedTopic.create approved: true assert_difference "topic.reload.replies_count", 1 do @@ -2252,8 +2354,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end end - test 'dangerous association name raises ArgumentError' do - [:errors, 'errors', :save, 'save'].each do |name| + test "dangerous association name raises ArgumentError" do + [:errors, "errors", :save, "save"].each do |name| assert_raises(ArgumentError, "Association #{name} should not be allowed") do Class.new(ActiveRecord::Base) do has_many name @@ -2262,7 +2364,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end end - test 'passes custom context validation to validate children' do + test "passes custom context validation to validate children" do pirate = FamousPirate.new pirate.famous_ships << ship = FamousShip.new @@ -2271,7 +2373,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal "can't be blank", ship.errors[:name].first end - test 'association with instance dependent scope' do + test "association with instance dependent scope" do bob = authors(:bob) Post.create!(title: "signed post by bob", body: "stuff", author: authors(:bob)) Post.create!(title: "anonymous post", body: "more stuff", author: authors(:bob)) @@ -2281,7 +2383,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal [], authors(:david).posts_with_signature.map(&:title) end - test 'associations autosaves when object is already persisted' do + test "associations autosaves when object is already persisted" do bulb = Bulb.create! tyre = Tyre.create! @@ -2294,7 +2396,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal 1, car.tyres.count end - test 'associations replace in memory when records have the same id' do + test "associations replace in memory when records have the same id" do bulb = Bulb.create! car = Car.create!(bulbs: [bulb]) @@ -2305,7 +2407,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal "foo", car.bulbs.first.name end - test 'in memory replacement executes no queries' do + test "in memory replacement executes no queries" do bulb = Bulb.create! car = Car.create!(bulbs: [bulb]) @@ -2316,7 +2418,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end end - test 'in memory replacements do not execute callbacks' do + test "in memory replacements do not execute callbacks" do raise_after_add = false klass = Class.new(ActiveRecord::Base) do self.table_name = :cars @@ -2337,7 +2439,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end end - test 'in memory replacements sets inverse instance' do + test "in memory replacements sets inverse instance" do bulb = Bulb.create! car = Car.create!(bulbs: [bulb]) @@ -2347,7 +2449,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_same car, new_bulb.car end - test 'in memory replacement maintains order' do + test "in memory replacement maintains order" do first_bulb = Bulb.create! second_bulb = Bulb.create! car = Car.create!(bulbs: [first_bulb, second_bulb]) @@ -2358,10 +2460,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal [first_bulb, second_bulb], car.bulbs end - test 'double insertion of new object to association when same association used in the after create callback of a new object' do - car = Car.create! - car.bulbs << TrickyBulb.new - assert_equal 1, car.bulbs.size + test "double insertion of new object to association when same association used in the after create callback of a new object" do + reset_callbacks(:save, Bulb) do + Bulb.after_save { |record| record.car.bulbs.to_a } + car = Car.create! + car.bulbs << Bulb.new + assert_equal 1, car.bulbs.size + end end def test_association_force_reload_with_only_true_is_deprecated @@ -2401,10 +2506,41 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_ids_reader_memoization - car = Car.create!(name: 'Tofaş') + car = Car.create!(name: "Tofaş") bulb = Bulb.create!(car: car) assert_equal [bulb.id], car.bulb_ids assert_no_queries { car.bulb_ids } end + + def test_loading_association_in_validate_callback_doesnt_affect_persistence + reset_callbacks(:validation, Bulb) do + Bulb.after_validation { |m| m.car.bulbs.load } + + car = Car.create!(name: "Car") + bulb = car.bulbs.create! + + assert_equal [bulb], car.bulbs + end + end + + private + + def force_signal37_to_load_all_clients_of_firm + companies(:first_firm).clients_of_firm.load_target + end + + def reset_callbacks(kind, klass) + old_callbacks = {} + old_callbacks[klass] = klass.send("_#{kind}_callbacks").dup + klass.subclasses.each do |subclass| + old_callbacks[subclass] = subclass.send("_#{kind}_callbacks").dup + end + yield + ensure + klass.send("_#{kind}_callbacks=", old_callbacks[klass]) + klass.subclasses.each do |subclass| + subclass.send("_#{kind}_callbacks=", old_callbacks[subclass]) + end + end end diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb index aff0dabee7..9f716d7820 100644 --- a/activerecord/test/cases/associations/has_many_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb @@ -1,33 +1,33 @@ require "cases/helper" -require 'models/post' -require 'models/person' -require 'models/reference' -require 'models/job' -require 'models/reader' -require 'models/comment' -require 'models/rating' -require 'models/tag' -require 'models/tagging' -require 'models/author' -require 'models/owner' -require 'models/pet' -require 'models/pet_treasure' -require 'models/toy' -require 'models/treasure' -require 'models/contract' -require 'models/company' -require 'models/developer' -require 'models/computer' -require 'models/subscriber' -require 'models/book' -require 'models/subscription' -require 'models/essay' -require 'models/category' -require 'models/categorization' -require 'models/member' -require 'models/membership' -require 'models/club' -require 'models/organization' +require "models/post" +require "models/person" +require "models/reference" +require "models/job" +require "models/reader" +require "models/comment" +require "models/rating" +require "models/tag" +require "models/tagging" +require "models/author" +require "models/owner" +require "models/pet" +require "models/pet_treasure" +require "models/toy" +require "models/treasure" +require "models/contract" +require "models/company" +require "models/developer" +require "models/computer" +require "models/subscriber" +require "models/book" +require "models/subscription" +require "models/essay" +require "models/category" +require "models/categorization" +require "models/member" +require "models/membership" +require "models/club" +require "models/organization" class HasManyThroughAssociationsTest < ActiveRecord::TestCase fixtures :posts, :readers, :people, :comments, :authors, :categories, :taggings, :tags, @@ -37,8 +37,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase # Dummies to force column loads so query counts are clean. def setup - Person.create :first_name => 'gummy' - Reader.create :person_id => 0, :post_id => 0 + Person.create first_name: "gummy" + Reader.create person_id: 0, post_id: 0 end def test_preload_sti_rhs_class @@ -49,9 +49,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_preload_sti_middle_relation - club = Club.create!(name: 'Aaron cool banana club') - member1 = Member.create!(name: 'Aaron') - member2 = Member.create!(name: 'Cat') + club = Club.create!(name: "Aaron cool banana club") + member1 = Member.create!(name: "Aaron") + member2 = Member.create!(name: "Cat") SuperMembership.create! club: club, member: member1 CurrentMembership.create! club: club, member: member2 @@ -65,12 +65,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase Class.new(ActiveRecord::Base) { define_singleton_method(:name) { name } } end - def test_ordered_habtm + def test_ordered_has_many_through person_prime = Class.new(ActiveRecord::Base) do - def self.name; 'Person'; end + def self.name; "Person"; end has_many :readers - has_many :posts, -> { order('posts.id DESC') }, :through => :readers + has_many :posts, -> { order("posts.id DESC") }, through: :readers end posts = person_prime.includes(:posts).first.posts @@ -85,7 +85,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase subscription = make_model "Subscription" subscriber = make_model "Subscriber" - subscriber.primary_key = 'nick' + subscriber.primary_key = "nick" subscription.belongs_to :book, anonymous_class: book subscription.belongs_to :subscriber, anonymous_class: subscriber @@ -106,8 +106,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_no_pk_join_table_append lesson, _, student = make_no_pk_hm_t - sicp = lesson.new(:name => "SICP") - ben = student.new(:name => "Ben Bitdiddle") + sicp = lesson.new(name: "SICP") + ben = student.new(name: "Ben Bitdiddle") sicp.students << ben assert sicp.save! end @@ -115,17 +115,17 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_no_pk_join_table_delete lesson, lesson_student, student = make_no_pk_hm_t - sicp = lesson.new(:name => "SICP") - ben = student.new(:name => "Ben Bitdiddle") - louis = student.new(:name => "Louis Reasoner") + sicp = lesson.new(name: "SICP") + ben = student.new(name: "Ben Bitdiddle") + louis = student.new(name: "Louis Reasoner") sicp.students << ben sicp.students << louis assert sicp.save! sicp.students.reload assert_operator lesson_student.count, :>=, 2 - assert_no_difference('student.count') do - assert_difference('lesson_student.count', -2) do + assert_no_difference("student.count") do + assert_difference("lesson_student.count", -2) do sicp.students.destroy(*student.all.to_a) end end @@ -139,8 +139,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase after_destroy_called = true end - sicp = lesson.new(:name => "SICP") - ben = student.new(:name => "Ben Bitdiddle") + sicp = lesson.new(name: "SICP") + ben = student.new(name: "Ben Bitdiddle") sicp.students << ben assert sicp.save! @@ -150,16 +150,16 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def make_no_pk_hm_t - lesson = make_model 'Lesson' - student = make_model 'Student' + lesson = make_model "Lesson" + student = make_model "Student" - lesson_student = make_model 'LessonStudent' - lesson_student.table_name = 'lessons_students' + lesson_student = make_model "LessonStudent" + lesson_student.table_name = "lessons_students" - lesson_student.belongs_to :lesson, :anonymous_class => lesson - lesson_student.belongs_to :student, :anonymous_class => student - lesson.has_many :lesson_students, :anonymous_class => lesson_student - lesson.has_many :students, :through => :lesson_students, :anonymous_class => student + lesson_student.belongs_to :lesson, anonymous_class: lesson + lesson_student.belongs_to :student, anonymous_class: student + lesson.has_many :lesson_students, anonymous_class: lesson_student + lesson.has_many :students, through: :lesson_students, anonymous_class: student [lesson, lesson_student, student] end @@ -175,7 +175,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase person = Person.new post = Post.new person.posts << post - assert person.posts.include?(post) + assert_includes person.posts, post end def test_associate_existing @@ -187,18 +187,18 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end assert_queries(1) do - assert post.people.include?(person) + assert_includes post.people, person end - assert post.reload.people.reload.include?(person) + assert_includes post.reload.people.reload, person end def test_delete_all_for_with_dependent_option_destroy person = people(:david) assert_equal 1, person.jobs_with_dependent_destroy.count - assert_no_difference 'Job.count' do - assert_difference 'Reference.count', -1 do + assert_no_difference "Job.count" do + assert_difference "Reference.count", -1 do person.reload.jobs_with_dependent_destroy.delete_all end end @@ -208,8 +208,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase person = people(:david) assert_equal 1, person.jobs_with_dependent_nullify.count - assert_no_difference 'Job.count' do - assert_no_difference 'Reference.count' do + assert_no_difference "Job.count" do + assert_no_difference "Reference.count" do person.reload.jobs_with_dependent_nullify.delete_all end end @@ -219,8 +219,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase person = people(:david) assert_equal 1, person.jobs_with_dependent_delete_all.count - assert_no_difference 'Job.count' do - assert_difference 'Reference.count', -1 do + assert_no_difference "Job.count" do + assert_difference "Reference.count", -1 do person.reload.jobs_with_dependent_delete_all.delete_all end end @@ -238,7 +238,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase post = posts(:thinking) person = people(:david) - assert_difference 'post.people.to_a.count', 2 do + assert_difference "post.people.to_a.count", 2 do post.people << person post.people << person end @@ -248,7 +248,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase post = posts(:thinking) person = people(:david) - assert_difference 'post.people.count', 2 do + assert_difference "post.people.count", 2 do post.people << person post.people << person end @@ -261,12 +261,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase post.people << person post.people << person - counts = ['post.people.count', 'post.people.to_a.count', 'post.readers.count', 'post.readers.to_a.count'] + counts = ["post.people.count", "post.people.to_a.count", "post.readers.count", "post.readers.to_a.count"] assert_difference counts, -2 do post.people.delete(person) end - assert !post.people.reload.include?(person) + assert_not_includes post.people.reload, person end def test_associating_new @@ -274,7 +274,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase new_person = nil # so block binding catches it assert_queries(0) do - new_person = Person.new :first_name => 'bob' + new_person = Person.new first_name: "bob" end # Associating new records always saves them @@ -284,59 +284,59 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end assert_queries(1) do - assert posts(:thinking).people.include?(new_person) + assert_includes posts(:thinking).people, new_person end - assert posts(:thinking).reload.people.reload.include?(new_person) + assert_includes posts(:thinking).reload.people.reload, new_person end def test_associate_new_by_building assert_queries(1) { posts(:thinking) } assert_queries(0) do - posts(:thinking).people.build(:first_name => "Bob") - posts(:thinking).people.new(:first_name => "Ted") + posts(:thinking).people.build(first_name: "Bob") + posts(:thinking).people.new(first_name: "Ted") end # Should only need to load the association once assert_queries(1) do - assert posts(:thinking).people.collect(&:first_name).include?("Bob") - assert posts(:thinking).people.collect(&:first_name).include?("Ted") + assert_includes posts(:thinking).people.collect(&:first_name), "Bob" + assert_includes posts(:thinking).people.collect(&:first_name), "Ted" end # 2 queries for each new record (1 to save the record itself, 1 for the join model) # * 2 new records = 4 # + 1 query to save the actual post = 5 assert_queries(5) do - posts(:thinking).body += '-changed' + posts(:thinking).body += "-changed" posts(:thinking).save end - assert posts(:thinking).reload.people.reload.collect(&:first_name).include?("Bob") - assert posts(:thinking).reload.people.reload.collect(&:first_name).include?("Ted") + assert_includes posts(:thinking).reload.people.reload.collect(&:first_name), "Bob" + assert_includes posts(:thinking).reload.people.reload.collect(&:first_name), "Ted" end def test_build_then_save_with_has_many_inverse post = posts(:thinking) - person = post.people.build(:first_name => "Bob") + person = post.people.build(first_name: "Bob") person.save post.reload - assert post.people.include?(person) + assert_includes post.people, person end def test_build_then_save_with_has_one_inverse post = posts(:thinking) - person = post.single_people.build(:first_name => "Bob") + person = post.single_people.build(first_name: "Bob") person.save post.reload - assert post.single_people.include?(person) + assert_includes post.single_people, person end def test_both_parent_ids_set_when_saving_new - post = Post.new(title: 'Hello', body: 'world') - person = Person.new(first_name: 'Sean') + post = Post.new(title: "Hello", body: "world") + person = Person.new(first_name: "Sean") post.people = [person] post.save @@ -348,7 +348,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_delete_association - assert_queries(2){posts(:welcome);people(:michael); } + assert_queries(2) { posts(:welcome);people(:michael); } assert_queries(1) do posts(:welcome).people.delete(people(:michael)) @@ -394,10 +394,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase person = people(:michael) job = jobs(:magician) - reference = Reference.where(:job_id => job.id, :person_id => person.id).first + reference = Reference.where(job_id: job.id, person_id: person.id).first - assert_no_difference ['Job.count', 'Reference.count'] do - assert_difference 'person.jobs.count', -1 do + assert_no_difference ["Job.count", "Reference.count"] do + assert_difference "person.jobs.count", -1 do person.jobs_with_dependent_nullify.delete(job) end end @@ -416,8 +416,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase # Make sure we're not deleting everything assert person.jobs.count >= 2 - assert_no_difference 'Job.count' do - assert_difference ['person.jobs.count', 'Reference.count'], -1 do + assert_no_difference "Job.count" do + assert_difference ["person.jobs.count", "Reference.count"], -1 do person.jobs_with_dependent_delete_all.delete(job) end end @@ -437,8 +437,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase # Make sure we're not deleting everything assert person.jobs.count >= 2 - assert_no_difference 'Job.count' do - assert_difference ['person.jobs.count', 'Reference.count'], -1 do + assert_no_difference "Job.count" do + assert_difference ["person.jobs.count", "Reference.count"], -1 do person.jobs_with_dependent_destroy.delete(job) end end @@ -455,8 +455,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase # Create a reference which is not linked to a job. This should not be destroyed. person.references.create! - assert_no_difference 'Job.count' do - assert_difference 'Reference.count', -person.jobs.count do + assert_no_difference "Job.count" do + assert_difference "Reference.count", -person.jobs.count do person.destroy end end @@ -468,8 +468,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase # Create a reference which is not linked to a job. This should not be destroyed. person.references.create! - assert_no_difference 'Job.count' do - assert_difference 'Reference.count', -person.jobs.count do + assert_no_difference "Job.count" do + assert_difference "Reference.count", -person.jobs.count do person.destroy end end @@ -480,7 +480,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase references = person.references.to_a - assert_no_difference ['Reference.count', 'Job.count'] do + assert_no_difference ["Reference.count", "Job.count"] do person.destroy end @@ -491,30 +491,30 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_update_counter_caches_on_delete post = posts(:welcome) - tag = post.tags.create!(:name => 'doomed') + tag = post.tags.create!(name: "doomed") - assert_difference ['post.reload.tags_count'], -1 do + assert_difference ["post.reload.tags_count"], -1 do posts(:welcome).tags.delete(tag) end end def test_update_counter_caches_on_delete_with_dependent_destroy post = posts(:welcome) - tag = post.tags.create!(:name => 'doomed') + tag = post.tags.create!(name: "doomed") post.update_columns(tags_with_destroy_count: post.tags.count) - assert_difference ['post.reload.tags_with_destroy_count'], -1 do + assert_difference ["post.reload.tags_with_destroy_count"], -1 do posts(:welcome).tags_with_destroy.delete(tag) end end def test_update_counter_caches_on_delete_with_dependent_nullify post = posts(:welcome) - tag = post.tags.create!(:name => 'doomed') + tag = post.tags.create!(name: "doomed") post.update_columns(tags_with_nullify_count: post.tags.count) - assert_no_difference 'post.reload.tags_count' do - assert_difference 'post.reload.tags_with_nullify_count', -1 do + assert_no_difference "post.reload.tags_count" do + assert_difference "post.reload.tags_with_nullify_count", -1 do posts(:welcome).tags_with_nullify.delete(tag) end end @@ -522,7 +522,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_update_counter_caches_on_replace_association post = posts(:welcome) - tag = post.tags.create!(:name => 'doomed') + tag = post.tags.create!(name: "doomed") tag.tagged_posts << posts(:thinking) tag.tagged_posts = [] @@ -533,15 +533,15 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_update_counter_caches_on_destroy post = posts(:welcome) - tag = post.tags.create!(name: 'doomed') + tag = post.tags.create!(name: "doomed") - assert_difference 'post.reload.tags_count', -1 do + assert_difference "post.reload.tags_count", -1 do tag.tagged_posts.destroy(post) end end def test_replace_association - assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people.reload} + assert_queries(4) { posts(:welcome);people(:david);people(:michael); posts(:welcome).people.reload } # 1 query to delete the existing reader (michael) # 1 query to associate the new reader (david) @@ -549,35 +549,35 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase posts(:welcome).people = [people(:david)] end - assert_queries(0){ - assert posts(:welcome).people.include?(people(:david)) - assert !posts(:welcome).people.include?(people(:michael)) + assert_queries(0) { + assert_includes posts(:welcome).people, people(:david) + assert_not_includes posts(:welcome).people, people(:michael) } - assert posts(:welcome).reload.people.reload.include?(people(:david)) - assert !posts(:welcome).reload.people.reload.include?(people(:michael)) + assert_includes posts(:welcome).reload.people.reload, people(:david) + assert_not_includes posts(:welcome).reload.people.reload, people(:michael) end def test_replace_order_is_preserved posts(:welcome).people.clear posts(:welcome).people = [people(:david), people(:michael)] - assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order('id').map(&:person_id) + assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order("id").map(&:person_id) # Test the inverse order in case the first success was a coincidence posts(:welcome).people.clear posts(:welcome).people = [people(:michael), people(:david)] - assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order('id').map(&:person_id) + assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order("id").map(&:person_id) end def test_replace_by_id_order_is_preserved posts(:welcome).people.clear posts(:welcome).person_ids = [people(:david).id, people(:michael).id] - assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order('id').map(&:person_id) + assert_equal [people(:david).id, people(:michael).id], posts(:welcome).readers.order("id").map(&:person_id) # Test the inverse order in case the first success was a coincidence posts(:welcome).people.clear posts(:welcome).person_ids = [people(:michael).id, people(:david).id] - assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order('id').map(&:person_id) + assert_equal [people(:michael).id, people(:david).id], posts(:welcome).readers.order("id").map(&:person_id) end def test_associate_with_create @@ -586,15 +586,15 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase # 1 query for the new record, 1 for the join table record # No need to update the actual collection yet! assert_queries(2) do - posts(:thinking).people.create(:first_name=>"Jeb") + posts(:thinking).people.create(first_name: "Jeb") end # *Now* we actually need the collection so it's loaded assert_queries(1) do - assert posts(:thinking).people.collect(&:first_name).include?("Jeb") + assert_includes posts(:thinking).people.collect(&:first_name), "Jeb" end - assert posts(:thinking).reload.people.reload.collect(&:first_name).include?("Jeb") + assert_includes posts(:thinking).reload.people.reload.collect(&:first_name), "Jeb" end def test_through_record_is_built_when_created_with_where @@ -605,66 +605,66 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_associate_with_create_and_no_options peeps = posts(:thinking).people.count - posts(:thinking).people.create(:first_name => 'foo') + posts(:thinking).people.create(first_name: "foo") assert_equal peeps + 1, posts(:thinking).people.count end def test_associate_with_create_with_through_having_conditions impatient_people = posts(:thinking).impatient_people.count - posts(:thinking).impatient_people.create!(:first_name => 'foo') + posts(:thinking).impatient_people.create!(first_name: "foo") assert_equal impatient_people + 1, posts(:thinking).impatient_people.count end def test_associate_with_create_exclamation_and_no_options peeps = posts(:thinking).people.count - posts(:thinking).people.create!(:first_name => 'foo') + posts(:thinking).people.create!(first_name: "foo") assert_equal peeps + 1, posts(:thinking).people.count end def test_create_on_new_record p = Post.new - error = assert_raises(ActiveRecord::RecordNotSaved) { p.people.create(:first_name => "mew") } + error = assert_raises(ActiveRecord::RecordNotSaved) { p.people.create(first_name: "mew") } assert_equal "You cannot call create unless the parent is saved", error.message - error = assert_raises(ActiveRecord::RecordNotSaved) { p.people.create!(:first_name => "snow") } + error = assert_raises(ActiveRecord::RecordNotSaved) { p.people.create!(first_name: "snow") } assert_equal "You cannot call create unless the parent is saved", error.message end def test_associate_with_create_and_invalid_options firm = companies(:first_firm) - assert_no_difference('firm.developers.count') { assert_nothing_raised { firm.developers.create(:name => '0') } } + assert_no_difference("firm.developers.count") { assert_nothing_raised { firm.developers.create(name: "0") } } end def test_associate_with_create_and_valid_options firm = companies(:first_firm) - assert_difference('firm.developers.count', 1) { firm.developers.create(:name => 'developer') } + assert_difference("firm.developers.count", 1) { firm.developers.create(name: "developer") } end def test_associate_with_create_bang_and_invalid_options firm = companies(:first_firm) - assert_no_difference('firm.developers.count') { assert_raises(ActiveRecord::RecordInvalid) { firm.developers.create!(:name => '0') } } + assert_no_difference("firm.developers.count") { assert_raises(ActiveRecord::RecordInvalid) { firm.developers.create!(name: "0") } } end def test_associate_with_create_bang_and_valid_options firm = companies(:first_firm) - assert_difference('firm.developers.count', 1) { firm.developers.create!(:name => 'developer') } + assert_difference("firm.developers.count", 1) { firm.developers.create!(name: "developer") } end def test_push_with_invalid_record firm = companies(:first_firm) - assert_raises(ActiveRecord::RecordInvalid) { firm.developers << Developer.new(:name => '0') } + assert_raises(ActiveRecord::RecordInvalid) { firm.developers << Developer.new(name: "0") } end def test_push_with_invalid_join_record repair_validations(Contract) do - Contract.validate {|r| r.errors[:base] << 'Invalid Contract' } + Contract.validate { |r| r.errors[:base] << "Invalid Contract" } firm = companies(:first_firm) - lifo = Developer.new(:name => 'lifo') + lifo = Developer.new(name: "lifo") assert_raises(ActiveRecord::RecordInvalid) { firm.developers << lifo } - lifo = Developer.create!(:name => 'lifo') + lifo = Developer.create!(name: "lifo") assert_raises(ActiveRecord::RecordInvalid) { firm.developers << lifo } end end @@ -694,7 +694,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase [:added, :after, "Michael"] ], log.last(2) - post.people_with_callbacks.push(people(:david), Person.create!(:first_name => "Bob"), Person.new(:first_name => "Lary")) + post.people_with_callbacks.push(people(:david), Person.create!(first_name: "Bob"), Person.new(first_name: "Lary")) assert_equal [ [:added, :before, "David"], [:added, :after, "David"], @@ -704,19 +704,19 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase [:added, :after, "Lary"] ],log.last(6) - post.people_with_callbacks.build(:first_name => "Ted") + post.people_with_callbacks.build(first_name: "Ted") assert_equal [ [:added, :before, "Ted"], [:added, :after, "Ted"] ], log.last(2) - post.people_with_callbacks.create(:first_name => "Sam") + post.people_with_callbacks.create(first_name: "Sam") assert_equal [ [:added, :before, "Sam"], [:added, :after, "Sam"] ], log.last(2) - post.people_with_callbacks = [people(:michael),people(:david), Person.new(:first_name => "Julian"), Person.create!(:first_name => "Roger")] + post.people_with_callbacks = [people(:michael),people(:david), Person.new(first_name: "Julian"), Person.create!(first_name: "Roger")] assert_equal((%w(Ted Bob Sam Lary) * 2).sort, log[-12..-5].collect(&:last).sort) assert_equal [ [:added, :before, "Julian"], @@ -729,7 +729,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_dynamic_find_should_respect_association_include # SQL error in sort clause if :include is not included # due to Unknown column 'comments.id' - assert Person.find(1).posts_with_comments_sorted_by_comment_id.find_by_title('Welcome to the weblog') + assert Person.find(1).posts_with_comments_sorted_by_comment_id.find_by_title("Welcome to the weblog") end def test_count_with_include_should_alias_join_table @@ -745,7 +745,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_get_ids_for_has_many_through_with_conditions_should_not_preload - Tagging.create!(:taggable_type => 'Post', :taggable_id => posts(:welcome).id, :tag => tags(:misc)) + Tagging.create!(taggable_type: "Post", taggable_id: posts(:welcome).id, tag: tags(:misc)) assert_not_called(ActiveRecord::Associations::Preloader, :new) do posts(:welcome).misc_tag_ids end @@ -776,16 +776,16 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_has_many_association_through_a_belongs_to_association_where_the_association_doesnt_exist - post = Post.create!(:title => "TITLE", :body => "BODY") + post = Post.create!(title: "TITLE", body: "BODY") assert_equal [], post.author_favorites end def test_has_many_association_through_a_belongs_to_association author = authors(:mary) - post = Post.create!(:author => author, :title => "TITLE", :body => "BODY") - author.author_favorites.create(:favorite_author_id => 1) - author.author_favorites.create(:favorite_author_id => 2) - author.author_favorites.create(:favorite_author_id => 3) + post = Post.create!(author: author, title: "TITLE", body: "BODY") + author.author_favorites.create(favorite_author_id: 1) + author.author_favorites.create(favorite_author_id: 2) + author.author_favorites.create(favorite_author_id: 3) assert_equal post.author.author_favorites, post.author_favorites end @@ -809,37 +809,37 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_modifying_has_many_through_has_one_reflection_should_raise [ - lambda { authors(:david).very_special_comments = [VerySpecialComment.create!(:body => "Gorp!", :post_id => 1011), VerySpecialComment.create!(:body => "Eep!", :post_id => 1012)] }, - lambda { authors(:david).very_special_comments << VerySpecialComment.create!(:body => "Hoohah!", :post_id => 1013) }, + lambda { authors(:david).very_special_comments = [VerySpecialComment.create!(body: "Gorp!", post_id: 1011), VerySpecialComment.create!(body: "Eep!", post_id: 1012)] }, + lambda { authors(:david).very_special_comments << VerySpecialComment.create!(body: "Hoohah!", post_id: 1013) }, lambda { authors(:david).very_special_comments.delete(authors(:david).very_special_comments.first) }, - ].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) } + ].each { |block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection, &block) } end def test_has_many_association_through_a_has_many_association_to_self - sarah = Person.create!(:first_name => 'Sarah', :primary_contact_id => people(:susan).id, :gender => 'F', :number1_fan_id => 1) - john = Person.create!(:first_name => 'John', :primary_contact_id => sarah.id, :gender => 'M', :number1_fan_id => 1) + sarah = Person.create!(first_name: "Sarah", primary_contact_id: people(:susan).id, gender: "F", number1_fan_id: 1) + john = Person.create!(first_name: "John", primary_contact_id: sarah.id, gender: "M", number1_fan_id: 1) assert_equal sarah.agents, [john] assert_equal people(:susan).agents.flat_map(&:agents), people(:susan).agents_of_agents end def test_associate_existing_with_nonstandard_primary_key_on_belongs_to - Categorization.create(:author => authors(:mary), :named_category_name => categories(:general).name) + Categorization.create(author: authors(:mary), named_category_name: categories(:general).name) assert_equal categories(:general), authors(:mary).named_categories.first end def test_collection_build_with_nonstandard_primary_key_on_belongs_to author = authors(:mary) - category = author.named_categories.build(:name => "Primary") + category = author.named_categories.build(name: "Primary") author.save - assert Categorization.exists?(:author_id => author.id, :named_category_name => category.name) - assert author.named_categories.reload.include?(category) + assert Categorization.exists?(author_id: author.id, named_category_name: category.name) + assert_includes author.named_categories.reload, category end def test_collection_create_with_nonstandard_primary_key_on_belongs_to author = authors(:mary) - category = author.named_categories.create(:name => "Primary") - assert Categorization.exists?(:author_id => author.id, :named_category_name => category.name) - assert author.named_categories.reload.include?(category) + category = author.named_categories.create(name: "Primary") + assert Categorization.exists?(author_id: author.id, named_category_name: category.name) + assert_includes author.named_categories.reload, category end def test_collection_exists @@ -851,9 +851,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_collection_delete_with_nonstandard_primary_key_on_belongs_to author = authors(:mary) - category = author.named_categories.create(:name => "Primary") + category = author.named_categories.create(name: "Primary") author.named_categories.delete(category) - assert !Categorization.exists?(:author_id => author.id, :named_category_name => category.name) + assert !Categorization.exists?(author_id: author.id, named_category_name: category.name) assert author.named_categories.reload.empty? end @@ -886,20 +886,20 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_collection_singular_ids_setter_raises_exception_when_invalid_ids_set company = companies(:rails_core) ids = [Developer.first.id, -9999] - assert_raises(ActiveRecord::AssociationTypeMismatch) {company.developer_ids= ids} + assert_raises(ActiveRecord::AssociationTypeMismatch) { company.developer_ids= ids } end def test_build_a_model_from_hm_through_association_with_where_clause - assert_nothing_raised { books(:awdr).subscribers.where(:nick => "marklazz").build } + assert_nothing_raised { books(:awdr).subscribers.where(nick: "marklazz").build } end def test_attributes_are_being_set_when_initialized_from_hm_through_association_with_where_clause - new_subscriber = books(:awdr).subscribers.where(:nick => "marklazz").build + new_subscriber = books(:awdr).subscribers.where(nick: "marklazz").build assert_equal new_subscriber.nick, "marklazz" end def test_attributes_are_being_set_when_initialized_from_hm_through_association_with_multiple_where_clauses - new_subscriber = books(:awdr).subscribers.where(:nick => "marklazz").where(:name => 'Marcelo Giorgi').build + new_subscriber = books(:awdr).subscribers.where(nick: "marklazz").where(name: "Marcelo Giorgi").build assert_equal new_subscriber.nick, "marklazz" assert_equal new_subscriber.name, "Marcelo Giorgi" end @@ -908,14 +908,14 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase person = Person.new reference = person.references.build job = reference.build_job - assert person.jobs.include?(job) + assert_includes person.jobs, job end def test_include_method_in_association_through_should_return_true_for_instance_added_with_nested_builds author = Author.new post = author.posts.build comment = post.comments.build - assert author.comments.include?(comment) + assert_includes author.comments, comment end def test_through_association_readonly_should_be_false @@ -932,7 +932,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_polymorphic_with_primary_key_option assert_equal [categories(:general)], authors(:david).essay_categories - authors = Author.joins(:essay_categories).where('categories.id' => categories(:general).id) + authors = Author.joins(:essay_categories).where("categories.id" => categories(:general).id) assert_equal authors(:david), authors.first assert_equal [owners(:blackbeard)], authors(:david).essay_owners @@ -944,7 +944,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_with_primary_key_option assert_equal [categories(:general)], authors(:david).essay_categories_2 - authors = Author.joins(:essay_categories_2).where('categories.id' => categories(:general).id) + authors = Author.joins(:essay_categories_2).where("categories.id" => categories(:general).id) assert_equal authors(:david), authors.first end @@ -956,30 +956,30 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_has_many_through_with_default_scope_on_join_model - assert_equal posts(:welcome).comments.order('id').to_a, authors(:david).comments_on_first_posts + assert_equal posts(:welcome).comments.order("id").to_a, authors(:david).comments_on_first_posts end def test_create_has_many_through_with_default_scope_on_join_model - category = authors(:david).special_categories.create(:name => "Foo") - assert_equal 1, category.categorizations.where(:special => true).count + category = authors(:david).special_categories.create(name: "Foo") + assert_equal 1, category.categorizations.where(special: true).count end def test_joining_has_many_through_with_distinct - mary = Author.joins(:unique_categorized_posts).where(:id => authors(:mary).id).first + mary = Author.joins(:unique_categorized_posts).where(id: authors(:mary).id).first assert_equal 1, mary.unique_categorized_posts.length assert_equal 1, mary.unique_categorized_post_ids.length end def test_joining_has_many_through_belongs_to - posts = Post.joins(:author_categorizations).order('posts.id'). - where('categorizations.id' => categorizations(:mary_thinking_sti).id) + posts = Post.joins(:author_categorizations).order("posts.id"). + where("categorizations.id" => categorizations(:mary_thinking_sti).id) assert_equal [posts(:eager_other), posts(:misc_by_mary), posts(:other_by_mary)], posts end def test_select_chosen_fields_only author = authors(:david) - assert_equal ['body', 'id'].sort, author.comments.select('comments.body').first.attributes.keys.sort + assert_equal ["body", "id"].sort, author.comments.select("comments.body").first.attributes.keys.sort end def test_get_has_many_through_belongs_to_ids_with_conditions @@ -1022,7 +1022,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase post = posts(:welcome) address = author_addresses(:david_address) - assert post.author_addresses.include?(address) + assert_includes post.author_addresses, address post.author_addresses.delete(address) assert post[:author_count].nil? end @@ -1030,7 +1030,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_primary_key_option_on_source post = posts(:welcome) category = categories(:general) - Categorization.create!(:post_id => post.id, :named_category_name => category.name) + Categorization.create!(post_id: post.id, named_category_name: category.name) assert_equal [category], post.named_categories assert_equal [category.name], post.named_category_ids # checks when target loaded @@ -1039,29 +1039,29 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_create_should_not_raise_exception_when_join_record_has_errors repair_validations(Categorization) do - Categorization.validate { |r| r.errors[:base] << 'Invalid Categorization' } - Category.create(:name => 'Fishing', :authors => [Author.first]) + Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" } + Category.create(name: "Fishing", authors: [Author.first]) end end def test_assign_array_to_new_record_builds_join_records - c = Category.new(:name => 'Fishing', :authors => [Author.first]) + c = Category.new(name: "Fishing", authors: [Author.first]) assert_equal 1, c.categorizations.size end def test_create_bang_should_raise_exception_when_join_record_has_errors repair_validations(Categorization) do - Categorization.validate { |r| r.errors[:base] << 'Invalid Categorization' } + Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" } assert_raises(ActiveRecord::RecordInvalid) do - Category.create!(:name => 'Fishing', :authors => [Author.first]) + Category.create!(name: "Fishing", authors: [Author.first]) end end end def test_save_bang_should_raise_exception_when_join_record_has_errors repair_validations(Categorization) do - Categorization.validate { |r| r.errors[:base] << 'Invalid Categorization' } - c = Category.new(:name => 'Fishing', :authors => [Author.first]) + Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" } + c = Category.new(name: "Fishing", authors: [Author.first]) assert_raises(ActiveRecord::RecordInvalid) do c.save! end @@ -1070,17 +1070,17 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase def test_save_returns_falsy_when_join_record_has_errors repair_validations(Categorization) do - Categorization.validate { |r| r.errors[:base] << 'Invalid Categorization' } - c = Category.new(:name => 'Fishing', :authors => [Author.first]) + Categorization.validate { |r| r.errors[:base] << "Invalid Categorization" } + c = Category.new(name: "Fishing", authors: [Author.first]) assert_not c.save end end def test_preloading_empty_through_association_via_joins - person = Person.create!(:first_name => "Gaga") - person = Person.where(:id => person.id).where('readers.id = 1 or 1=1').references(:readers).includes(:posts).to_a.first + person = Person.create!(first_name: "Gaga") + person = Person.where(id: person.id).where("readers.id = 1 or 1=1").references(:readers).includes(:posts).to_a.first - assert person.posts.loaded?, 'person.posts should be loaded' + assert person.posts.loaded?, "person.posts should be loaded" assert_equal [], person.posts end @@ -1101,13 +1101,13 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_has_many_through_with_polymorphic_source - post = tags(:general).tagged_posts.create! :title => "foo", :body => "bar" + post = tags(:general).tagged_posts.create! title: "foo", body: "bar" assert_equal [tags(:general)], post.reload.tags end def test_has_many_through_obeys_order_on_through_association owner = owners(:blackbeard) - assert owner.toys.to_sql.include?("pets.name desc") + assert_includes owner.toys.to_sql, "pets.name desc" assert_equal ["parrot", "bulbul"], owner.toys.map { |r| r.pet.name } end @@ -1116,7 +1116,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase assert_no_queries(ignore_none: false) do assert_equal [], person.posts - assert_equal [], person.posts.where(body: 'omg') + assert_equal [], person.posts.where(body: "omg") assert_equal [], person.posts.pluck(:body) assert_equal 0, person.posts.sum(:tags_count) assert_equal 0, person.posts.count @@ -1148,9 +1148,9 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_has_many_through_unscope_default_scope - post = Post.create!(:title => 'Beaches', :body => "I like beaches!") - Reader.create! :person => people(:david), :post => post - LazyReader.create! :person => people(:susan), :post => post + post = Post.create!(title: "Beaches", body: "I like beaches!") + Reader.create! person: people(:david), post: post + LazyReader.create! person: people(:susan), post: post assert_equal 2, post.people.to_a.size assert_equal 1, post.lazy_people.to_a.size @@ -1160,8 +1160,8 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase end def test_has_many_through_add_with_sti_middle_relation - club = SuperClub.create!(name: 'Fight Club') - member = Member.create!(name: 'Tyler Durden') + club = SuperClub.create!(name: "Fight Club") + member = Member.create!(name: "Tyler Durden") club.members << member assert_equal 1, SuperMembership.where(member_id: member.id, club_id: club.id).count diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index c9d9e29f09..1a0e6d2f8e 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -1,15 +1,15 @@ require "cases/helper" -require 'models/developer' -require 'models/computer' -require 'models/project' -require 'models/company' -require 'models/ship' -require 'models/pirate' -require 'models/car' -require 'models/bulb' -require 'models/author' -require 'models/image' -require 'models/post' +require "models/developer" +require "models/computer" +require "models/project" +require "models/company" +require "models/ship" +require "models/pirate" +require "models/car" +require "models/bulb" +require "models/author" +require "models/image" +require "models/post" class HasOneAssociationsTest < ActiveRecord::TestCase self.use_transactional_tests = false unless supports_savepoints? @@ -28,7 +28,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase ActiveRecord::SQLCounter.clear_log companies(:first_firm).account ensure - assert ActiveRecord::SQLCounter.log_all.all? { |sql| /order by/i !~ sql }, 'ORDER BY was used in the query' + assert ActiveRecord::SQLCounter.log_all.all? { |sql| /order by/i !~ sql }, "ORDER BY was used in the query" end def test_has_one_cache_nils @@ -36,13 +36,13 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_queries(1) { assert_nil firm.account } assert_queries(0) { assert_nil firm.account } - firms = Firm.all.merge!(:includes => :account).to_a + firms = Firm.all.merge!(includes: :account).to_a assert_queries(0) { firms.each(&:account) } end def test_with_select assert_equal Firm.find(1).account_with_select.attributes.size, 2 - assert_equal Firm.all.merge!(:includes => :account_with_select).find(1).account_with_select.attributes.size, 2 + assert_equal Firm.all.merge!(includes: :account_with_select).find(1).account_with_select.attributes.size, 2 end def test_finding_using_primary_key @@ -102,7 +102,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase def test_nullification_on_association_change firm = companies(:rails_core) old_account_id = firm.account.id - firm.account = Account.new(:credit_limit => 5) + firm.account = Account.new(credit_limit: 5) # account is dependent with nullify, therefore its firm_id should be nil assert_nil Account.find(old_account_id).firm_id end @@ -125,12 +125,12 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_association_change_calls_delete - companies(:first_firm).deletable_account = Account.new(:credit_limit => 5) + companies(:first_firm).deletable_account = Account.new(credit_limit: 5) assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id] end def test_association_change_calls_destroy - companies(:first_firm).account = Account.new(:credit_limit => 5) + companies(:first_firm).account = Account.new(credit_limit: 5) assert_equal [companies(:first_firm).id], Account.destroyed_account_ids[companies(:first_firm).id] end @@ -170,27 +170,27 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_dependence_with_nil_associate - firm = DependentFirm.new(:name => 'nullify') + firm = DependentFirm.new(name: "nullify") firm.save! assert_nothing_raised { firm.destroy } end def test_restrict_with_exception - firm = RestrictedWithExceptionFirm.create!(:name => 'restrict') - firm.create_account(:credit_limit => 10) + firm = RestrictedWithExceptionFirm.create!(name: "restrict") + firm.create_account(credit_limit: 10) assert_not_nil firm.account assert_raise(ActiveRecord::DeleteRestrictionError) { firm.destroy } - assert RestrictedWithExceptionFirm.exists?(:name => 'restrict') + assert RestrictedWithExceptionFirm.exists?(name: "restrict") assert firm.account.present? end def test_restrict_with_error_is_deprecated_using_key_one I18n.backend = I18n::Backend::Simple.new - I18n.backend.store_translations :en, activerecord: { errors: { messages: { restrict_dependent_destroy: { one: 'message for deprecated key' } } } } + I18n.backend.store_translations :en, activerecord: { errors: { messages: { restrict_dependent_destroy: { one: "message for deprecated key" } } } } - firm = RestrictedWithErrorFirm.create!(name: 'restrict') + firm = RestrictedWithErrorFirm.create!(name: "restrict") firm.create_account(credit_limit: 10) assert_not_nil firm.account @@ -198,16 +198,16 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_deprecated { firm.destroy } assert !firm.errors.empty? - assert_equal 'message for deprecated key', firm.errors[:base].first - assert RestrictedWithErrorFirm.exists?(name: 'restrict') + assert_equal "message for deprecated key", firm.errors[:base].first + assert RestrictedWithErrorFirm.exists?(name: "restrict") assert firm.account.present? ensure I18n.backend.reload! end def test_restrict_with_error - firm = RestrictedWithErrorFirm.create!(:name => 'restrict') - firm.create_account(:credit_limit => 10) + firm = RestrictedWithErrorFirm.create!(name: "restrict") + firm.create_account(credit_limit: 10) assert_not_nil firm.account @@ -215,14 +215,14 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert !firm.errors.empty? assert_equal "Cannot delete record because a dependent account exists", firm.errors[:base].first - assert RestrictedWithErrorFirm.exists?(:name => 'restrict') + assert RestrictedWithErrorFirm.exists?(name: "restrict") assert firm.account.present? end def test_restrict_with_error_with_locale I18n.backend = I18n::Backend::Simple.new - I18n.backend.store_translations 'en', activerecord: {attributes: {restricted_with_error_firm: {account: 'firm account'}}} - firm = RestrictedWithErrorFirm.create!(name: 'restrict') + I18n.backend.store_translations "en", activerecord: { attributes: { restricted_with_error_firm: { account: "firm account" } } } + firm = RestrictedWithErrorFirm.create!(name: "restrict") firm.create_account(credit_limit: 10) assert_not_nil firm.account @@ -231,7 +231,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert !firm.errors.empty? assert_equal "Cannot delete record because a dependent firm account exists", firm.errors[:base].first - assert RestrictedWithErrorFirm.exists?(name: 'restrict') + assert RestrictedWithErrorFirm.exists?(name: "restrict") assert firm.account.present? ensure I18n.backend.reload! @@ -260,24 +260,24 @@ class HasOneAssociationsTest < ActiveRecord::TestCase def test_building_the_associated_object_with_explicit_sti_base_class firm = DependentFirm.new - company = firm.build_company(:type => "Company") + company = firm.build_company(type: "Company") assert_kind_of Company, company, "Expected #{company.class} to be a Company" end def test_building_the_associated_object_with_sti_subclass firm = DependentFirm.new - company = firm.build_company(:type => "Client") + company = firm.build_company(type: "Client") assert_kind_of Client, company, "Expected #{company.class} to be a Client" end def test_building_the_associated_object_with_an_invalid_type firm = DependentFirm.new - assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(:type => "Invalid") } + assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(type: "Invalid") } end def test_building_the_associated_object_with_an_unrelated_type firm = DependentFirm.new - assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(:type => "Account") } + assert_raise(ActiveRecord::SubclassNotFound) { firm.build_company(type: "Account") } end def test_build_and_create_should_not_happen_within_scope @@ -295,19 +295,19 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_create_association - firm = Firm.create(:name => "GlobalMegaCorp") - account = firm.create_account(:credit_limit => 1000) + firm = Firm.create(name: "GlobalMegaCorp") + account = firm.create_account(credit_limit: 1000) assert_equal account, firm.reload.account end def test_create_association_with_bang - firm = Firm.create(:name => "GlobalMegaCorp") - account = firm.create_account!(:credit_limit => 1000) + firm = Firm.create(name: "GlobalMegaCorp") + account = firm.create_account!(credit_limit: 1000) assert_equal account, firm.reload.account end def test_create_association_with_bang_failing - firm = Firm.create(:name => "GlobalMegaCorp") + firm = Firm.create(name: "GlobalMegaCorp") assert_raise ActiveRecord::RecordInvalid do firm.create_account! end @@ -319,7 +319,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_create_with_inexistent_foreign_key_failing - firm = Firm.create(name: 'GlobalMegaCorp') + firm = Firm.create(name: "GlobalMegaCorp") assert_raises(ActiveRecord::UnknownAttributeError) do firm.create_account_with_inexistent_foreign_key @@ -365,7 +365,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase def test_finding_with_interpolated_condition firm = Firm.first - superior = firm.clients.create(:name => 'SuperiorCo') + superior = firm.clients.create(name: "SuperiorCo") superior.rating = 10 superior.save assert_equal 10, firm.clients_with_interpolated_conditions.first.rating @@ -382,7 +382,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_save_still_works_after_accessing_nil_has_one - jp = Company.new :name => 'Jaded Pixel' + jp = Company.new name: "Jaded Pixel" jp.dummy_account.nil? assert_nothing_raised do @@ -411,14 +411,14 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_nothing_raised do Firm.find(@firm.id).save! - Firm.all.merge!(:includes => :account).find(@firm.id).save! + Firm.all.merge!(includes: :account).find(@firm.id).save! end @firm.account.destroy assert_nothing_raised do Firm.find(@firm.id).save! - Firm.all.merge!(:includes => :account).find(@firm.id).save! + Firm.all.merge!(includes: :account).find(@firm.id).save! end end @@ -435,7 +435,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_attributes_are_being_set_when_initialized_from_has_one_association_with_where_clause - new_account = companies(:first_firm).build_account(:firm_name => 'Account') + new_account = companies(:first_firm).build_account(firm_name: "Account") assert_equal new_account.firm_name, "Account" end @@ -505,63 +505,63 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_association_keys_bypass_attribute_protection - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") bulb = car.build_bulb assert_equal car.id, bulb.car_id - bulb = car.build_bulb :car_id => car.id + 1 + bulb = car.build_bulb car_id: car.id + 1 assert_equal car.id, bulb.car_id bulb = car.create_bulb assert_equal car.id, bulb.car_id - bulb = car.create_bulb :car_id => car.id + 1 + bulb = car.create_bulb car_id: car.id + 1 assert_equal car.id, bulb.car_id end def test_association_protect_foreign_key - pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") + pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") ship = pirate.build_ship assert_equal pirate.id, ship.pirate_id - ship = pirate.build_ship :pirate_id => pirate.id + 1 + ship = pirate.build_ship pirate_id: pirate.id + 1 assert_equal pirate.id, ship.pirate_id ship = pirate.create_ship assert_equal pirate.id, ship.pirate_id - ship = pirate.create_ship :pirate_id => pirate.id + 1 + ship = pirate.create_ship pirate_id: pirate.id + 1 assert_equal pirate.id, ship.pirate_id end def test_build_with_block - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") - bulb = car.build_bulb{ |b| b.color = 'Red' } - assert_equal 'RED!', bulb.color + bulb = car.build_bulb { |b| b.color = "Red" } + assert_equal "RED!", bulb.color end def test_create_with_block - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") - bulb = car.create_bulb{ |b| b.color = 'Red' } - assert_equal 'RED!', bulb.color + bulb = car.create_bulb { |b| b.color = "Red" } + assert_equal "RED!", bulb.color end def test_create_bang_with_block - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") - bulb = car.create_bulb!{ |b| b.color = 'Red' } - assert_equal 'RED!', bulb.color + bulb = car.create_bulb! { |b| b.color = "Red" } + assert_equal "RED!", bulb.color end def test_association_attributes_are_available_to_after_initialize - car = Car.create(:name => 'honda') + car = Car.create(name: "honda") bulb = car.create_bulb - assert_equal car.id, bulb.attributes_after_initialize['car_id'] + assert_equal car.id, bulb.attributes_after_initialize["car_id"] end def test_has_one_transaction @@ -581,36 +581,36 @@ class HasOneAssociationsTest < ActiveRecord::TestCase def test_has_one_assignment_dont_trigger_save_on_change_of_same_object pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") - ship = pirate.build_ship(name: 'old name') + ship = pirate.build_ship(name: "old name") ship.save! - ship.name = 'new name' + ship.name = "new name" assert ship.changed? assert_queries(1) do # One query for updating name, not triggering query for updating pirate_id pirate.ship = ship end - assert_equal 'new name', pirate.ship.reload.name + assert_equal "new name", pirate.ship.reload.name end def test_has_one_assignment_triggers_save_on_change_on_replacing_object pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") - ship = pirate.build_ship(name: 'old name') + ship = pirate.build_ship(name: "old name") ship.save! - new_ship = Ship.create(name: 'new name') + new_ship = Ship.create(name: "new name") assert_queries(2) do # One query for updating name and second query for updating pirate_id pirate.ship = new_ship end - assert_equal 'new name', pirate.ship.reload.name + assert_equal "new name", pirate.ship.reload.name end def test_has_one_autosave_with_primary_key_manually_set - post = Post.create(id: 1234, title: "Some title", body: 'Some content') - author = Author.new(id: 33, name: 'Hank Moody') + post = Post.create(id: 1234, title: "Some title", body: "Some content") + author = Author.new(id: 33, name: "Hank Moody") author.post = post author.save @@ -621,7 +621,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_has_one_loading_for_new_record - post = Post.create!(author_id: 42, title: 'foo', body: 'bar') + post = Post.create!(author_id: 42, title: "foo", body: "bar") author = Author.new(id: 42) assert_equal post, author.post end @@ -635,7 +635,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end def test_with_polymorphic_has_one_with_custom_columns_name - post = Post.create! :title => 'foo', :body => 'bar' + post = Post.create! title: "foo", body: "bar" image = Image.create! post.main_image = image @@ -644,8 +644,8 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_equal image, post.main_image end - test 'dangerous association name raises ArgumentError' do - [:errors, 'errors', :save, 'save'].each do |name| + test "dangerous association name raises ArgumentError" do + [:errors, "errors", :save, "save"].each do |name| assert_raises(ArgumentError, "Association #{name} should not be allowed") do Class.new(ActiveRecord::Base) do has_one name @@ -659,4 +659,22 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_deprecated { firm.account(true) } end + + class SpecialBook < ActiveRecord::Base + self.table_name = "books" + belongs_to :author, class_name: "SpecialAuthor" + end + + class SpecialAuthor < ActiveRecord::Base + self.table_name = "authors" + has_one :book, class_name: "SpecialBook", foreign_key: "author_id" + end + + def test_assocation_enum_works_properly + author = SpecialAuthor.create!(name: "Test") + book = SpecialBook.create!(status: "published") + author.book = book + + refute_equal 0, SpecialAuthor.joins(:book).where(books: { status: "published" } ).count + end end diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb index b2b46812b9..b2f47d2daf 100644 --- a/activerecord/test/cases/associations/has_one_through_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb @@ -1,25 +1,25 @@ require "cases/helper" -require 'models/club' -require 'models/member_type' -require 'models/member' -require 'models/membership' -require 'models/sponsor' -require 'models/organization' -require 'models/member_detail' -require 'models/minivan' -require 'models/dashboard' -require 'models/speedometer' -require 'models/category' -require 'models/author' -require 'models/essay' -require 'models/owner' -require 'models/post' -require 'models/comment' -require 'models/categorization' -require 'models/customer' -require 'models/carrier' -require 'models/shop_account' -require 'models/customer_carrier' +require "models/club" +require "models/member_type" +require "models/member" +require "models/membership" +require "models/sponsor" +require "models/organization" +require "models/member_detail" +require "models/minivan" +require "models/dashboard" +require "models/speedometer" +require "models/category" +require "models/author" +require "models/essay" +require "models/owner" +require "models/post" +require "models/comment" +require "models/categorization" +require "models/customer" +require "models/carrier" +require "models/shop_account" +require "models/customer_carrier" class HasOneThroughAssociationsTest < ActiveRecord::TestCase fixtures :member_types, :members, :clubs, :memberships, :sponsors, :organizations, :minivans, @@ -34,14 +34,14 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase end def test_creating_association_creates_through_record - new_member = Member.create(:name => "Chris") - new_member.club = Club.create(:name => "LRUG") + new_member = Member.create(name: "Chris") + new_member.club = Club.create(name: "LRUG") assert_not_nil new_member.current_membership assert_not_nil new_member.club end def test_creating_association_builds_through_record_for_new - new_member = Member.new(:name => "Jane") + new_member = Member.new(name: "Jane") new_member.club = clubs(:moustache_club) assert new_member.current_membership assert_equal clubs(:moustache_club), new_member.current_membership.club @@ -51,8 +51,8 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase end def test_creating_association_sets_both_parent_ids_for_new - member = Member.new(name: 'Sean Griffin') - club = Club.new(name: 'Da Club') + member = Member.new(name: "Sean Griffin") + club = Club.new(name: "Da Club") member.club = club @@ -65,7 +65,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase end def test_replace_target_record - new_club = Club.create(:name => "Marx Bros") + new_club = Club.create(name: "Marx Bros") @member.club = new_club @member.reload assert_equal new_club, @member.club @@ -73,7 +73,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase def test_replacing_target_record_deletes_old_association assert_no_difference "Membership.count" do - new_club = Club.create(:name => "Bananarama") + new_club = Club.create(name: "Bananarama") @member.club = new_club @member.reload end @@ -92,30 +92,30 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase def test_has_one_through_eager_loading members = assert_queries(3) do #base table, through table, clubs table - Member.all.merge!(:includes => :club, :where => ["name = ?", "Groucho Marx"]).to_a + Member.all.merge!(includes: :club, where: ["name = ?", "Groucho Marx"]).to_a end assert_equal 1, members.size - assert_not_nil assert_no_queries {members[0].club} + assert_not_nil assert_no_queries { members[0].club } end def test_has_one_through_eager_loading_through_polymorphic members = assert_queries(3) do #base table, through table, clubs table - Member.all.merge!(:includes => :sponsor_club, :where => ["name = ?", "Groucho Marx"]).to_a + Member.all.merge!(includes: :sponsor_club, where: ["name = ?", "Groucho Marx"]).to_a end assert_equal 1, members.size - assert_not_nil assert_no_queries {members[0].sponsor_club} + assert_not_nil assert_no_queries { members[0].sponsor_club } end def test_has_one_through_with_conditions_eager_loading # conditions on the through table - assert_equal clubs(:moustache_club), Member.all.merge!(:includes => :favourite_club).find(@member.id).favourite_club + assert_equal clubs(:moustache_club), Member.all.merge!(includes: :favourite_club).find(@member.id).favourite_club memberships(:membership_of_favourite_club).update_columns(favourite: false) - assert_equal nil, Member.all.merge!(:includes => :favourite_club).find(@member.id).reload.favourite_club + assert_equal nil, Member.all.merge!(includes: :favourite_club).find(@member.id).reload.favourite_club # conditions on the source table - assert_equal clubs(:moustache_club), Member.all.merge!(:includes => :hairy_club).find(@member.id).hairy_club + assert_equal clubs(:moustache_club), Member.all.merge!(includes: :hairy_club).find(@member.id).hairy_club clubs(:moustache_club).update_columns(name: "Association of Clean-Shaven Persons") - assert_equal nil, Member.all.merge!(:includes => :hairy_club).find(@member.id).reload.hairy_club + assert_equal nil, Member.all.merge!(includes: :hairy_club).find(@member.id).reload.hairy_club end def test_has_one_through_polymorphic_with_source_type @@ -123,31 +123,31 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase end def test_eager_has_one_through_polymorphic_with_source_type - clubs = Club.all.merge!(:includes => :sponsored_member, :where => ["name = ?","Moustache and Eyebrow Fancier Club"]).to_a + clubs = Club.all.merge!(includes: :sponsored_member, where: ["name = ?","Moustache and Eyebrow Fancier Club"]).to_a # Only the eyebrow fanciers club has a sponsored_member - assert_not_nil assert_no_queries {clubs[0].sponsored_member} + assert_not_nil assert_no_queries { clubs[0].sponsored_member } end def test_has_one_through_nonpreload_eagerloading members = assert_queries(1) do - Member.all.merge!(:includes => :club, :where => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name').to_a #force fallback + Member.all.merge!(includes: :club, where: ["members.name = ?", "Groucho Marx"], order: "clubs.name").to_a #force fallback end assert_equal 1, members.size - assert_not_nil assert_no_queries {members[0].club} + assert_not_nil assert_no_queries { members[0].club } end def test_has_one_through_nonpreload_eager_loading_through_polymorphic members = assert_queries(1) do - Member.all.merge!(:includes => :sponsor_club, :where => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name').to_a #force fallback + Member.all.merge!(includes: :sponsor_club, where: ["members.name = ?", "Groucho Marx"], order: "clubs.name").to_a #force fallback end assert_equal 1, members.size - assert_not_nil assert_no_queries {members[0].sponsor_club} + assert_not_nil assert_no_queries { members[0].sponsor_club } end def test_has_one_through_nonpreload_eager_loading_through_polymorphic_with_more_than_one_through_record - Sponsor.new(:sponsor_club => clubs(:crazy_club), :sponsorable => members(:groucho)).save! + Sponsor.new(sponsor_club: clubs(:crazy_club), sponsorable: members(:groucho)).save! members = assert_queries(1) do - Member.all.merge!(:includes => :sponsor_club, :where => ["members.name = ?", "Groucho Marx"], :order => 'clubs.name DESC').to_a #force fallback + Member.all.merge!(includes: :sponsor_club, where: ["members.name = ?", "Groucho Marx"], order: "clubs.name DESC").to_a #force fallback end assert_equal 1, members.size assert_not_nil assert_no_queries { members[0].sponsor_club } @@ -159,8 +159,8 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase end def test_assigning_association_correctly_assigns_target - new_member = Member.create(:name => "Chris") - new_member.club = new_club = Club.create(:name => "LRUG") + new_member = Member.create(name: "Chris") + new_member.club = new_club = Club.create(name: "LRUG") assert_equal new_club, new_member.association(:club).target end @@ -176,37 +176,37 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase def test_assigning_to_has_one_through_preserves_decorated_join_record @organization = organizations(:nsa) - assert_difference 'MemberDetail.count', 1 do - @member_detail = MemberDetail.new(:extra_data => 'Extra') + assert_difference "MemberDetail.count", 1 do + @member_detail = MemberDetail.new(extra_data: "Extra") @member.member_detail = @member_detail @member.organization = @organization end assert_equal @organization, @member.organization - assert @organization.members.include?(@member) - assert_equal 'Extra', @member.member_detail.extra_data + assert_includes @organization.members, @member + assert_equal "Extra", @member.member_detail.extra_data end def test_reassigning_has_one_through @organization = organizations(:nsa) @new_organization = organizations(:discordians) - assert_difference 'MemberDetail.count', 1 do - @member_detail = MemberDetail.new(:extra_data => 'Extra') + assert_difference "MemberDetail.count", 1 do + @member_detail = MemberDetail.new(extra_data: "Extra") @member.member_detail = @member_detail @member.organization = @organization end assert_equal @organization, @member.organization - assert_equal 'Extra', @member.member_detail.extra_data - assert @organization.members.include?(@member) - assert !@new_organization.members.include?(@member) + assert_equal "Extra", @member.member_detail.extra_data + assert_includes @organization.members, @member + assert_not_includes @new_organization.members, @member - assert_no_difference 'MemberDetail.count' do + assert_no_difference "MemberDetail.count" do @member.organization = @new_organization end assert_equal @new_organization, @member.organization - assert_equal 'Extra', @member.member_detail.extra_data - assert !@organization.members.include?(@member) - assert @new_organization.members.include?(@member) + assert_equal "Extra", @member.member_detail.extra_data + assert_not_includes @organization.members, @member + assert_includes @new_organization.members, @member end def test_preloading_has_one_through_on_belongs_to @@ -217,7 +217,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase @member.member_detail = @member_detail @member.organization = @organization @member_details = assert_queries(3) do - MemberDetail.all.merge!(:includes => :member_type).to_a + MemberDetail.all.merge!(includes: :member_type).to_a end @new_detail = @member_details[0] assert @new_detail.send(:association, :member_type).loaded? @@ -230,19 +230,19 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase assert_nothing_raised do Club.find(@club.id).save! - Club.all.merge!(:includes => :sponsored_member).find(@club.id).save! + Club.all.merge!(includes: :sponsored_member).find(@club.id).save! end @club.sponsor.destroy assert_nothing_raised do Club.find(@club.id).save! - Club.all.merge!(:includes => :sponsored_member).find(@club.id).save! + Club.all.merge!(includes: :sponsored_member).find(@club.id).save! end end def test_through_belongs_to_after_destroy - @member_detail = MemberDetail.new(:extra_data => 'Extra') + @member_detail = MemberDetail.new(extra_data: "Extra") @member.member_detail = @member_detail @member.save! @@ -261,7 +261,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase end def test_value_is_properly_quoted - minivan = Minivan.find('m1') + minivan = Minivan.find("m1") assert_nothing_raised do minivan.dashboard end @@ -270,7 +270,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase def test_has_one_through_polymorphic_with_primary_key_option assert_equal categories(:general), authors(:david).essay_category - authors = Author.joins(:essay_category).where('categories.id' => categories(:general).id) + authors = Author.joins(:essay_category).where("categories.id" => categories(:general).id) assert_equal authors(:david), authors.first assert_equal owners(:blackbeard), authors(:david).essay_owner @@ -282,12 +282,12 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase def test_has_one_through_with_primary_key_option assert_equal categories(:general), authors(:david).essay_category_2 - authors = Author.joins(:essay_category_2).where('categories.id' => categories(:general).id) + authors = Author.joins(:essay_category_2).where("categories.id" => categories(:general).id) assert_equal authors(:david), authors.first end def test_has_one_through_with_default_scope_on_join_model - assert_equal posts(:welcome).comments.order('id').first, authors(:david).comment_on_first_post + assert_equal posts(:welcome).comments.order("id").first, authors(:david).comment_on_first_post end def test_has_one_through_many_raises_exception diff --git a/activerecord/test/cases/associations/inner_join_association_test.rb b/activerecord/test/cases/associations/inner_join_association_test.rb index b3fe759ad9..7414869c8f 100644 --- a/activerecord/test/cases/associations/inner_join_association_test.rb +++ b/activerecord/test/cases/associations/inner_join_association_test.rb @@ -1,13 +1,13 @@ require "cases/helper" -require 'models/post' -require 'models/comment' -require 'models/author' -require 'models/essay' -require 'models/category' -require 'models/categorization' -require 'models/person' -require 'models/tagging' -require 'models/tag' +require "models/post" +require "models/comment" +require "models/author" +require "models/essay" +require "models/category" +require "models/categorization" +require "models/person" +require "models/tagging" +require "models/tag" class InnerJoinAssociationTest < ActiveRecord::TestCase fixtures :authors, :essays, :posts, :comments, :categories, :categories_posts, :categorizations, @@ -20,7 +20,7 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase def test_construct_finder_sql_does_not_table_name_collide_on_duplicate_associations assert_nothing_raised do - sql = Person.joins(:agents => {:agents => :agents}).joins(:agents => {:agents => {:primary_contact => :agents}}).to_sql + sql = Person.joins(agents: { agents: :agents }).joins(agents: { agents: { primary_contact: :agents } }).to_sql assert_match(/agents_people_4/i, sql) end end @@ -47,7 +47,7 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase end def test_join_conditions_allow_nil_associations - authors = Author.includes(:essays).where(:essays => {:id => nil}) + authors = Author.includes(:essays).where(essays: { id: nil }) assert_equal 2, authors.count end @@ -58,41 +58,41 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase end def test_find_with_implicit_inner_joins_honors_readonly_with_select - authors = Author.joins(:posts).select('authors.*').to_a + authors = Author.joins(:posts).select("authors.*").to_a assert !authors.empty?, "expected authors to be non-empty" - assert authors.all? {|a| !a.readonly? }, "expected no authors to be readonly" + assert authors.all? { |a| !a.readonly? }, "expected no authors to be readonly" end def test_find_with_implicit_inner_joins_honors_readonly_false authors = Author.joins(:posts).readonly(false).to_a assert !authors.empty?, "expected authors to be non-empty" - assert authors.all? {|a| !a.readonly? }, "expected no authors to be readonly" + assert authors.all? { |a| !a.readonly? }, "expected no authors to be readonly" end def test_find_with_implicit_inner_joins_does_not_set_associations - authors = Author.joins(:posts).select('authors.*').to_a + authors = Author.joins(:posts).select("authors.*").to_a assert !authors.empty?, "expected authors to be non-empty" assert authors.all? { |a| !a.instance_variable_defined?(:@posts) }, "expected no authors to have the @posts association loaded" end def test_count_honors_implicit_inner_joins - real_count = Author.all.to_a.sum{|a| a.posts.count } + real_count = Author.all.to_a.sum { |a| a.posts.count } assert_equal real_count, Author.joins(:posts).count, "plain inner join count should match the number of referenced posts records" end def test_calculate_honors_implicit_inner_joins - real_count = Author.all.to_a.sum{|a| a.posts.count } - assert_equal real_count, Author.joins(:posts).calculate(:count, 'authors.id'), "plain inner join count should match the number of referenced posts records" + real_count = Author.all.to_a.sum { |a| a.posts.count } + assert_equal real_count, Author.joins(:posts).calculate(:count, "authors.id"), "plain inner join count should match the number of referenced posts records" end def test_calculate_honors_implicit_inner_joins_and_distinct_and_conditions - real_count = Author.all.to_a.select {|a| a.posts.any? {|p| p.title =~ /^Welcome/} }.length - authors_with_welcoming_post_titles = Author.all.merge!(joins: :posts, where: "posts.title like 'Welcome%'").distinct.calculate(:count, 'authors.id') + real_count = Author.all.to_a.select { |a| a.posts.any? { |p| p.title.start_with?("Welcome") } }.length + authors_with_welcoming_post_titles = Author.all.merge!(joins: :posts, where: "posts.title like 'Welcome%'").distinct.calculate(:count, "authors.id") assert_equal real_count, authors_with_welcoming_post_titles, "inner join and conditions should have only returned authors posting titles starting with 'Welcome'" end def test_find_with_sti_join - scope = Post.joins(:special_comments).where(:id => posts(:sti_comments).id) + scope = Post.joins(:special_comments).where(id: posts(:sti_comments).id) # The join should match SpecialComment and its subclasses only assert scope.where("comments.type" => "Comment").empty? @@ -102,12 +102,12 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase def test_find_with_conditions_on_reflection assert !posts(:welcome).comments.empty? - assert Post.joins(:nonexistent_comments).where(:id => posts(:welcome).id).empty? # [sic!] + assert Post.joins(:nonexistent_comments).where(id: posts(:welcome).id).empty? # [sic!] end def test_find_with_conditions_on_through_reflection assert !posts(:welcome).tags.empty? - assert Post.joins(:misc_tags).where(:id => posts(:welcome).id).empty? + assert Post.joins(:misc_tags).where(id: posts(:welcome).id).empty? end test "the default scope of the target is applied when joining associations" do @@ -120,8 +120,8 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase test "the default scope of the target is correctly aliased when joining associations" do author = Author.create! name: "Jon" - author.categories.create! name: 'Not Special' - author.special_categories.create! name: 'Special' + author.categories.create! name: "Not Special" + author.special_categories.create! name: "Special" categories = author.categories.includes(:special_categorizations).references(:special_categorizations).to_a assert_equal 2, categories.size @@ -129,8 +129,8 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase test "the correct records are loaded when including an aliased association" do author = Author.create! name: "Jon" - author.categories.create! name: 'Not Special' - author.special_categories.create! name: 'Special' + author.categories.create! name: "Not Special" + author.special_categories.create! name: "Special" categories = author.categories.eager_load(:special_categorizations).order(:name).to_a assert_equal 0, categories.first.special_categorizations.size diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb index c9743e80d3..6fe6ee6783 100644 --- a/activerecord/test/cases/associations/inverse_associations_test.rb +++ b/activerecord/test/cases/associations/inverse_associations_test.rb @@ -1,21 +1,21 @@ require "cases/helper" -require 'models/man' -require 'models/face' -require 'models/interest' -require 'models/zine' -require 'models/club' -require 'models/sponsor' -require 'models/rating' -require 'models/comment' -require 'models/car' -require 'models/bulb' -require 'models/mixed_case_monkey' -require 'models/admin' -require 'models/admin/account' -require 'models/admin/user' -require 'models/developer' -require 'models/company' -require 'models/project' +require "models/man" +require "models/face" +require "models/interest" +require "models/zine" +require "models/club" +require "models/sponsor" +require "models/rating" +require "models/comment" +require "models/car" +require "models/bulb" +require "models/mixed_case_monkey" +require "models/admin" +require "models/admin/account" +require "models/admin/user" +require "models/developer" +require "models/company" +require "models/project" class AutomaticInverseFindingTests < ActiveRecord::TestCase fixtures :ratings, :comments, :cars @@ -131,15 +131,15 @@ end class InverseAssociationTests < ActiveRecord::TestCase def test_should_allow_for_inverse_of_options_in_associations assert_nothing_raised do - Class.new(ActiveRecord::Base).has_many(:wheels, :inverse_of => :car) + Class.new(ActiveRecord::Base).has_many(:wheels, inverse_of: :car) end assert_nothing_raised do - Class.new(ActiveRecord::Base).has_one(:engine, :inverse_of => :car) + Class.new(ActiveRecord::Base).has_one(:engine, inverse_of: :car) end assert_nothing_raised do - Class.new(ActiveRecord::Base).belongs_to(:car, :inverse_of => :driver) + Class.new(ActiveRecord::Base).belongs_to(:car, inverse_of: :driver) end end @@ -203,9 +203,9 @@ class InverseAssociationTests < ActiveRecord::TestCase end def test_this_inverse_stuff - firm = Firm.create!(name: 'Adequate Holdings') - Project.create!(name: 'Project 1', firm: firm) - Developer.create!(name: 'Gorbypuff', firm: firm) + firm = Firm.create!(name: "Adequate Holdings") + Project.create!(name: "Project 1", firm: firm) + Developer.create!(name: "Gorbypuff", firm: firm) new_project = Project.last assert Project.reflect_on_association(:lead_developer).inverse_of.present?, "Expected inverse of to be present" @@ -220,73 +220,72 @@ class InverseHasOneTests < ActiveRecord::TestCase m = men(:gordon) f = m.face assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" - f.man.name = 'Mungo' + f.man.name = "Mungo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance" end - def test_parent_instance_should_be_shared_with_eager_loaded_child_on_find - m = Man.all.merge!(:where => {:name => 'Gordon'}, :includes => :face).first + m = Man.all.merge!(where: { name: "Gordon" }, includes: :face).first f = m.face assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" - f.man.name = 'Mungo' + f.man.name = "Mungo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance" - m = Man.all.merge!(:where => {:name => 'Gordon'}, :includes => :face, :order => 'faces.id').first + m = Man.all.merge!(where: { name: "Gordon" }, includes: :face, order: "faces.id").first f = m.face assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" - f.man.name = 'Mungo' + f.man.name = "Mungo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to child-owned instance" end def test_parent_instance_should_be_shared_with_newly_built_child m = Man.first - f = m.build_face(:description => 'haunted') + f = m.build_face(description: "haunted") assert_not_nil f.man assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" - f.man.name = 'Mungo' + f.man.name = "Mungo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to just-built-child-owned instance" end def test_parent_instance_should_be_shared_with_newly_created_child m = Man.first - f = m.create_face(:description => 'haunted') + f = m.create_face(description: "haunted") assert_not_nil f.man assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" - f.man.name = 'Mungo' + f.man.name = "Mungo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance" end def test_parent_instance_should_be_shared_with_newly_created_child_via_bang_method m = Man.first - f = m.create_face!(:description => 'haunted') + f = m.create_face!(description: "haunted") assert_not_nil f.man assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" - f.man.name = 'Mungo' + f.man.name = "Mungo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to newly-created-child-owned instance" end def test_parent_instance_should_be_shared_with_replaced_via_accessor_child m = Man.first - f = Face.new(:description => 'haunted') + f = Face.new(description: "haunted") m.face = f assert_not_nil f.man assert_equal m.name, f.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to parent instance" - f.man.name = 'Mungo' + f.man.name = "Mungo" assert_equal m.name, f.man.name, "Name of man should be the same after changes to replaced-child-owned instance" end @@ -303,67 +302,67 @@ class InverseHasManyTests < ActiveRecord::TestCase is = m.interests is.each do |i| assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" - i.man.name = 'Mungo' + i.man.name = "Mungo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance" end end def test_parent_instance_should_be_shared_with_eager_loaded_children - m = Man.all.merge!(:where => {:name => 'Gordon'}, :includes => :interests).first + m = Man.all.merge!(where: { name: "Gordon" }, includes: :interests).first is = m.interests is.each do |i| assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" - i.man.name = 'Mungo' + i.man.name = "Mungo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance" end - m = Man.all.merge!(:where => {:name => 'Gordon'}, :includes => :interests, :order => 'interests.id').first + m = Man.all.merge!(where: { name: "Gordon" }, includes: :interests, order: "interests.id").first is = m.interests is.each do |i| assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" - i.man.name = 'Mungo' + i.man.name = "Mungo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to child-owned instance" end end def test_parent_instance_should_be_shared_with_newly_block_style_built_child m = Man.first - i = m.interests.build {|ii| ii.topic = 'Industrial Revolution Re-enactment'} + i = m.interests.build { |ii| ii.topic = "Industrial Revolution Re-enactment" } assert_not_nil i.topic, "Child attributes supplied to build via blocks should be populated" assert_not_nil i.man assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" - i.man.name = 'Mungo' + i.man.name = "Mungo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to just-built-child-owned instance" end def test_parent_instance_should_be_shared_with_newly_created_via_bang_method_child m = Man.first - i = m.interests.create!(:topic => 'Industrial Revolution Re-enactment') + i = m.interests.create!(topic: "Industrial Revolution Re-enactment") assert_not_nil i.man assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" - i.man.name = 'Mungo' + i.man.name = "Mungo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance" end def test_parent_instance_should_be_shared_with_newly_block_style_created_child m = Man.first - i = m.interests.create {|ii| ii.topic = 'Industrial Revolution Re-enactment'} + i = m.interests.create { |ii| ii.topic = "Industrial Revolution Re-enactment" } assert_not_nil i.topic, "Child attributes supplied to create via blocks should be populated" assert_not_nil i.man assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" - i.man.name = 'Mungo' + i.man.name = "Mungo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance" end @@ -385,25 +384,25 @@ class InverseHasManyTests < ActiveRecord::TestCase def test_parent_instance_should_be_shared_with_poked_in_child m = men(:gordon) - i = Interest.create(:topic => 'Industrial Revolution Re-enactment') + i = Interest.create(topic: "Industrial Revolution Re-enactment") m.interests << i assert_not_nil i.man assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" - i.man.name = 'Mungo' + i.man.name = "Mungo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to newly-created-child-owned instance" end def test_parent_instance_should_be_shared_with_replaced_via_accessor_children m = Man.first - i = Interest.new(:topic => 'Industrial Revolution Re-enactment') + i = Interest.new(topic: "Industrial Revolution Re-enactment") m.interests = [i] assert_not_nil i.man assert_equal m.name, i.man.name, "Name of man should be the same before changes to parent instance" - m.name = 'Bongo' + m.name = "Bongo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to parent instance" - i.man.name = 'Mungo' + i.man.name = "Mungo" assert_equal m.name, i.man.name, "Name of man should be the same after changes to replaced-child-owned instance" end @@ -485,7 +484,7 @@ class InverseHasManyTests < ActiveRecord::TestCase def test_child_instance_should_point_to_parent_without_saving man = Man.new - i = Interest.create(:topic => 'Industrial Revolution Re-enactment') + i = Interest.create(topic: "Industrial Revolution Re-enactment") man.interests << i assert_not_nil i.man @@ -495,6 +494,33 @@ class InverseHasManyTests < ActiveRecord::TestCase assert !man.persisted? end + + def test_inverse_instance_should_be_set_before_find_callbacks_are_run + reset_callbacks(Interest, :find) do + Interest.after_find { raise unless association(:man).loaded? && man.present? } + + assert Man.first.interests.reload.any? + assert Man.includes(:interests).first.interests.any? + assert Man.joins(:interests).includes(:interests).first.interests.any? + end + end + + def test_inverse_instance_should_be_set_before_initialize_callbacks_are_run + reset_callbacks(Interest, :initialize) do + Interest.after_initialize { raise unless association(:man).loaded? && man.present? } + + assert Man.first.interests.reload.any? + assert Man.includes(:interests).first.interests.any? + assert Man.joins(:interests).includes(:interests).first.interests.any? + end + end + + def reset_callbacks(target, type) + old_callbacks = target.send(:get_callbacks, type).deep_dup + yield + ensure + target.send(:set_callbacks, type, old_callbacks) if old_callbacks + end end class InverseBelongsToTests < ActiveRecord::TestCase @@ -504,49 +530,49 @@ class InverseBelongsToTests < ActiveRecord::TestCase f = faces(:trusting) m = f.man assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" - m.face.description = 'pleasing' + m.face.description = "pleasing" assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance" end def test_eager_loaded_child_instance_should_be_shared_with_parent_on_find - f = Face.all.merge!(:includes => :man, :where => {:description => 'trusting'}).first + f = Face.all.merge!(includes: :man, where: { description: "trusting" }).first m = f.man assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" - m.face.description = 'pleasing' + m.face.description = "pleasing" assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance" - f = Face.all.merge!(:includes => :man, :order => 'men.id', :where => {:description => 'trusting'}).first + f = Face.all.merge!(includes: :man, order: "men.id", where: { description: "trusting" }).first m = f.man assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" - m.face.description = 'pleasing' + m.face.description = "pleasing" assert_equal f.description, m.face.description, "Description of face should be the same after changes to parent-owned instance" end def test_child_instance_should_be_shared_with_newly_built_parent f = faces(:trusting) - m = f.build_man(:name => 'Charles') + m = f.build_man(name: "Charles") assert_not_nil m.face assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" - m.face.description = 'pleasing' + m.face.description = "pleasing" assert_equal f.description, m.face.description, "Description of face should be the same after changes to just-built-parent-owned instance" end def test_child_instance_should_be_shared_with_newly_created_parent f = faces(:trusting) - m = f.create_man(:name => 'Charles') + m = f.create_man(name: "Charles") assert_not_nil m.face assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" - m.face.description = 'pleasing' + m.face.description = "pleasing" assert_equal f.description, m.face.description, "Description of face should be the same after changes to newly-created-parent-owned instance" end @@ -554,24 +580,24 @@ class InverseBelongsToTests < ActiveRecord::TestCase i = interests(:trainspotting) m = i.man assert_not_nil m.interests - iz = m.interests.detect { |_iz| _iz.id == i.id} + iz = m.interests.detect { |_iz| _iz.id == i.id } assert_not_nil iz assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child" - i.topic = 'Eating cheese with a spoon' + i.topic = "Eating cheese with a spoon" assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to child" - iz.topic = 'Cow tipping' + iz.topic = "Cow tipping" assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance" end def test_child_instance_should_be_shared_with_replaced_via_accessor_parent f = Face.first - m = Man.new(:name => 'Charles') + m = Man.new(name: "Charles") f.man = m assert_not_nil m.face assert_equal f.description, m.face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.face.description, "Description of face should be the same after changes to child instance" - m.face.description = 'pleasing' + m.face.description = "pleasing" assert_equal f.description, m.face.description, "Description of face should be the same after changes to replaced-parent-owned instance" end @@ -584,30 +610,30 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase fixtures :men, :faces, :interests def test_child_instance_should_be_shared_with_parent_on_find - f = Face.all.merge!(:where => {:description => 'confused'}).first + f = Face.all.merge!(where: { description: "confused" }).first m = f.polymorphic_man assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance" - m.polymorphic_face.description = 'pleasing' + m.polymorphic_face.description = "pleasing" assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance" end def test_eager_loaded_child_instance_should_be_shared_with_parent_on_find - f = Face.all.merge!(:where => {:description => 'confused'}, :includes => :man).first + f = Face.all.merge!(where: { description: "confused" }, includes: :man).first m = f.polymorphic_man assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance" - m.polymorphic_face.description = 'pleasing' + m.polymorphic_face.description = "pleasing" assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance" - f = Face.all.merge!(:where => {:description => 'confused'}, :includes => :man, :order => 'men.id').first + f = Face.all.merge!(where: { description: "confused" }, includes: :man, order: "men.id").first m = f.polymorphic_man assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same before changes to child instance" - f.description = 'gormless' + f.description = "gormless" assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to child instance" - m.polymorphic_face.description = 'pleasing' + m.polymorphic_face.description = "pleasing" assert_equal f.description, m.polymorphic_face.description, "Description of face should be the same after changes to parent-owned instance" end @@ -619,9 +645,9 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase face.polymorphic_man = new_man assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same before changes to parent instance" - face.description = 'Bongo' + face.description = "Bongo" assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to parent instance" - new_man.polymorphic_face.description = 'Mungo' + new_man.polymorphic_face.description = "Mungo" assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to replaced-parent-owned instance" end @@ -633,9 +659,9 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase face.polymorphic_man = new_man assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same before changes to parent instance" - face.description = 'Bongo' + face.description = "Bongo" assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to parent instance" - new_man.polymorphic_face.description = 'Mungo' + new_man.polymorphic_face.description = "Mungo" assert_equal face.description, new_man.polymorphic_face.description, "Description of face should be the same after changes to replaced-parent-owned instance" end @@ -655,12 +681,12 @@ class InversePolymorphicBelongsToTests < ActiveRecord::TestCase i = interests(:llama_wrangling) m = i.polymorphic_man assert_not_nil m.polymorphic_interests - iz = m.polymorphic_interests.detect { |_iz| _iz.id == i.id} + iz = m.polymorphic_interests.detect { |_iz| _iz.id == i.id } assert_not_nil iz assert_equal i.topic, iz.topic, "Interest topics should be the same before changes to child" - i.topic = 'Eating cheese with a spoon' + i.topic = "Eating cheese with a spoon" assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to child" - iz.topic = 'Cow tipping' + iz.topic = "Cow tipping" assert_not_equal i.topic, iz.topic, "Interest topics should not be the same after changes to parent-owned instance" end @@ -698,8 +724,8 @@ class InverseMultipleHasManyInversesForSameModel < ActiveRecord::TestCase def test_that_we_can_create_associations_that_have_the_same_reciprocal_name_from_different_models assert_nothing_raised do i = Interest.first - i.build_zine(:title => 'Get Some in Winter! 2008') - i.build_man(:name => 'Gordon') + i.build_zine(title: "Get Some in Winter! 2008") + i.build_man(name: "Gordon") i.save! end end diff --git a/activerecord/test/cases/associations/join_model_test.rb b/activerecord/test/cases/associations/join_model_test.rb index c7bd9d2119..15a7ae941a 100644 --- a/activerecord/test/cases/associations/join_model_test.rb +++ b/activerecord/test/cases/associations/join_model_test.rb @@ -1,20 +1,20 @@ require "cases/helper" -require 'models/tag' -require 'models/tagging' -require 'models/post' -require 'models/rating' -require 'models/item' -require 'models/comment' -require 'models/author' -require 'models/category' -require 'models/categorization' -require 'models/vertex' -require 'models/edge' -require 'models/book' -require 'models/citation' -require 'models/aircraft' -require 'models/engine' -require 'models/car' +require "models/tag" +require "models/tagging" +require "models/post" +require "models/rating" +require "models/item" +require "models/comment" +require "models/author" +require "models/category" +require "models/categorization" +require "models/vertex" +require "models/edge" +require "models/book" +require "models/citation" +require "models/aircraft" +require "models/engine" +require "models/car" class AssociationsJoinModelTest < ActiveRecord::TestCase self.use_transactional_tests = false unless supports_savepoints? @@ -24,15 +24,15 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase :edges def test_has_many - assert authors(:david).categories.include?(categories(:general)) + assert_includes authors(:david).categories, categories(:general) end def test_has_many_inherited - assert authors(:mary).categories.include?(categories(:sti_test)) + assert_includes authors(:mary).categories, categories(:sti_test) end def test_inherited_has_many - assert categories(:sti_test).authors.include?(authors(:mary)) + assert_includes categories(:sti_test).authors, authors(:mary) end def test_has_many_distinct_through_join_model @@ -97,10 +97,10 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_polymorphic_has_many_create_model_with_inheritance_and_custom_base_class - post = SubStiPost.create :title => 'SubStiPost', :body => 'SubStiPost body' + post = SubStiPost.create title: "SubStiPost", body: "SubStiPost body" assert_instance_of SubStiPost, post - tagging = tags(:misc).taggings.create(:taggable => post) + tagging = tags(:misc).taggings.create(taggable: post) assert_equal "SubStiPost", tagging.taggable_type end @@ -116,12 +116,12 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase post = posts(:thinking) assert_instance_of SpecialPost, post - tagging = tags(:misc).taggings.create(:taggable => post) + tagging = tags(:misc).taggings.create(taggable: post) assert_equal "Post", tagging.taggable_type end def test_polymorphic_has_one_create_model_with_inheritance - tagging = tags(:misc).create_tagging(:taggable => posts(:thinking)) + tagging = tags(:misc).create_tagging(taggable: posts(:thinking)) assert_equal "Post", tagging.taggable_type end @@ -142,7 +142,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_set_polymorphic_has_one_on_new_record tagging = tags(:misc).taggings.create - post = Post.new :title => "foo", :body => "bar" + post = Post.new title: "foo", body: "bar" post.tagging = tagging post.save! @@ -153,28 +153,28 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_create_polymorphic_has_many_with_scope old_count = posts(:welcome).taggings.count - tagging = posts(:welcome).taggings.create(:tag => tags(:misc)) + tagging = posts(:welcome).taggings.create(tag: tags(:misc)) assert_equal "Post", tagging.taggable_type assert_equal old_count+1, posts(:welcome).taggings.count end def test_create_bang_polymorphic_with_has_many_scope old_count = posts(:welcome).taggings.count - tagging = posts(:welcome).taggings.create!(:tag => tags(:misc)) + tagging = posts(:welcome).taggings.create!(tag: tags(:misc)) assert_equal "Post", tagging.taggable_type assert_equal old_count+1, posts(:welcome).taggings.count end def test_create_polymorphic_has_one_with_scope old_count = Tagging.count - tagging = posts(:welcome).create_tagging(:tag => tags(:misc)) + tagging = posts(:welcome).create_tagging(tag: tags(:misc)) assert_equal "Post", tagging.taggable_type assert_equal old_count+1, Tagging.count end def test_delete_polymorphic_has_many_with_delete_all assert_equal 1, posts(:welcome).taggings.count - posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyDeleteAll' + posts(:welcome).taggings.first.update_columns taggable_type: "PostWithHasManyDeleteAll" post = find_post_with_dependency(1, :has_many, :taggings, :delete_all) old_count = Tagging.count @@ -185,7 +185,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_delete_polymorphic_has_many_with_destroy assert_equal 1, posts(:welcome).taggings.count - posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyDestroy' + posts(:welcome).taggings.first.update_columns taggable_type: "PostWithHasManyDestroy" post = find_post_with_dependency(1, :has_many, :taggings, :destroy) old_count = Tagging.count @@ -196,7 +196,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_delete_polymorphic_has_many_with_nullify assert_equal 1, posts(:welcome).taggings.count - posts(:welcome).taggings.first.update_columns taggable_type: 'PostWithHasManyNullify' + posts(:welcome).taggings.first.update_columns taggable_type: "PostWithHasManyNullify" post = find_post_with_dependency(1, :has_many, :taggings, :nullify) old_count = Tagging.count @@ -207,7 +207,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_delete_polymorphic_has_one_with_destroy assert posts(:welcome).tagging - posts(:welcome).tagging.update_columns taggable_type: 'PostWithHasOneDestroy' + posts(:welcome).tagging.update_columns taggable_type: "PostWithHasOneDestroy" post = find_post_with_dependency(1, :has_one, :tagging, :destroy) old_count = Tagging.count @@ -219,7 +219,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_delete_polymorphic_has_one_with_nullify assert posts(:welcome).tagging - posts(:welcome).tagging.update_columns taggable_type: 'PostWithHasOneNullify' + posts(:welcome).tagging.update_columns taggable_type: "PostWithHasOneNullify" post = find_post_with_dependency(1, :has_one, :tagging, :nullify) old_count = Tagging.count @@ -235,15 +235,15 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_create_through_has_many_with_piggyback category = categories(:sti_test) - ernie = category.authors_with_select.create(:name => 'Ernie') + ernie = category.authors_with_select.create(name: "Ernie") assert_nothing_raised do - assert_equal ernie, category.authors_with_select.detect {|a| a.name == 'Ernie'} + assert_equal ernie, category.authors_with_select.detect { |a| a.name == "Ernie" } end end def test_include_has_many_through - posts = Post.all.merge!(:order => 'posts.id').to_a - posts_with_authors = Post.all.merge!(:includes => :authors, :order => 'posts.id').to_a + posts = Post.all.merge!(order: "posts.id").to_a + posts_with_authors = Post.all.merge!(includes: :authors, order: "posts.id").to_a assert_equal posts.length, posts_with_authors.length posts.length.times do |i| assert_equal posts[i].authors.length, assert_no_queries { posts_with_authors[i].authors.length } @@ -267,8 +267,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_include_polymorphic_has_many_through - posts = Post.all.merge!(:order => 'posts.id').to_a - posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a + posts = Post.all.merge!(order: "posts.id").to_a + posts_with_tags = Post.all.merge!(includes: :tags, order: "posts.id").to_a assert_equal posts.length, posts_with_tags.length posts.length.times do |i| assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length } @@ -276,8 +276,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_include_polymorphic_has_many - posts = Post.all.merge!(:order => 'posts.id').to_a - posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a + posts = Post.all.merge!(order: "posts.id").to_a + posts_with_taggings = Post.all.merge!(includes: :taggings, order: "posts.id").to_a assert_equal posts.length, posts_with_taggings.length posts.length.times do |i| assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length } @@ -302,7 +302,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_has_many_array_methods_called_by_method_missing - assert authors(:david).categories.any? { |category| category.name == 'General' } + assert authors(:david).categories.any? { |category| category.name == "General" } assert_nothing_raised { authors(:david).categories.sort } end @@ -324,12 +324,12 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_has_many_through_with_custom_primary_key_on_has_many_source - assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order('authors.id') + assert_equal [authors(:david), authors(:bob)], posts(:thinking).authors_using_custom_pk.order("authors.id") end def test_belongs_to_polymorphic_with_counter_cache assert_equal 1, posts(:welcome)[:tags_count] - tagging = posts(:welcome).taggings.create(:tag => tags(:general)) + tagging = posts(:welcome).taggings.create(tag: tags(:general)) assert_equal 2, posts(:welcome, :reload)[:tags_count] tagging.destroy assert_equal 1, posts(:welcome, :reload)[:tags_count] @@ -354,7 +354,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end assert_raise ActiveRecord::EagerLoadPolymorphicError do - tags(:general).taggings.includes(:taggable).where('bogus_table.column = 1').references(:bogus_table).to_a + tags(:general).taggings.includes(:taggable).where("bogus_table.column = 1").references(:bogus_table).to_a end end @@ -365,13 +365,13 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_has_many_polymorphic_associations_merges_through_scope Tag.has_many :null_taggings, -> { none }, class_name: :Tagging - Tag.has_many :null_tagged_posts, :through => :null_taggings, :source => 'taggable', :source_type => 'Post' + Tag.has_many :null_tagged_posts, through: :null_taggings, source: "taggable", source_type: "Post" assert_equal [], tags(:general).null_tagged_posts refute_equal [], tags(:general).tagged_posts end def test_eager_has_many_polymorphic_with_source_type - tag_with_include = Tag.all.merge!(:includes => :tagged_posts).find(tags(:general).id) + tag_with_include = Tag.all.merge!(includes: :tagged_posts).find(tags(:general).id) desired = posts(:welcome, :thinking) assert_no_queries do # added sort by ID as otherwise test using JRuby was failing as array elements were in different order @@ -381,19 +381,19 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_has_many_through_has_many_find_all - assert_equal comments(:greetings), authors(:david).comments.order('comments.id').to_a.first + assert_equal comments(:greetings), authors(:david).comments.order("comments.id").to_a.first end def test_has_many_through_has_many_find_all_with_custom_class - assert_equal comments(:greetings), authors(:david).funky_comments.order('comments.id').to_a.first + assert_equal comments(:greetings), authors(:david).funky_comments.order("comments.id").to_a.first end def test_has_many_through_has_many_find_first - assert_equal comments(:greetings), authors(:david).comments.order('comments.id').first + assert_equal comments(:greetings), authors(:david).comments.order("comments.id").first end def test_has_many_through_has_many_find_conditions - options = { :where => "comments.#{QUOTED_TYPE}='SpecialComment'", :order => 'comments.id' } + options = { where: "comments.#{QUOTED_TYPE}='SpecialComment'", order: "comments.id" } assert_equal comments(:does_it_hurt), authors(:david).comments.merge(options).first end @@ -418,7 +418,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_eager_load_has_many_through_has_many - author = Author.all.merge!(:where => ['name = ?', 'David'], :includes => :comments, :order => 'comments.id').first + author = Author.all.merge!(where: ["name = ?", "David"], includes: :comments, order: "comments.id").first SpecialComment.new; VerySpecialComment.new assert_no_queries do assert_equal [1,2,3,5,6,7,8,9,10,12], author.comments.collect(&:id) @@ -426,7 +426,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_eager_load_has_many_through_has_many_with_conditions - post = Post.all.merge!(:includes => :invalid_tags).first + post = Post.all.merge!(includes: :invalid_tags).first assert_no_queries do post.invalid_tags end @@ -434,8 +434,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_eager_belongs_to_and_has_one_not_singularized assert_nothing_raised do - Author.all.merge!(:includes => :author_address).first - AuthorAddress.all.merge!(:includes => :author).first + Author.all.merge!(includes: :author_address).first + AuthorAddress.all.merge!(includes: :author).first end end @@ -445,8 +445,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_add_to_self_referential_has_many_through - new_author = Author.create(:name => "Bob") - authors(:david).author_favorites.create :favorite_author => new_author + new_author = Author.create(name: "Bob") + authors(:david).author_favorites.create favorite_author: new_author assert_equal new_author, authors(:david).reload.favorite_authors.first end @@ -462,28 +462,27 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_associating_unsaved_records_with_has_many_through saved_post = posts(:thinking) - new_tag = Tag.new(:name => "new") + new_tag = Tag.new(name: "new") saved_post.tags << new_tag assert new_tag.persisted? #consistent with habtm! assert saved_post.persisted? - assert saved_post.tags.include?(new_tag) + assert_includes saved_post.tags, new_tag assert new_tag.persisted? - assert saved_post.reload.tags.reload.include?(new_tag) + assert_includes saved_post.reload.tags.reload, new_tag - - new_post = Post.new(:title => "Association replacement works!", :body => "You best believe it.") + new_post = Post.new(title: "Association replacement works!", body: "You best believe it.") saved_tag = tags(:general) new_post.tags << saved_tag assert !new_post.persisted? assert saved_tag.persisted? - assert new_post.tags.include?(saved_tag) + assert_includes new_post.tags, saved_tag new_post.save! assert new_post.persisted? - assert new_post.reload.tags.reload.include?(saved_tag) + assert_includes new_post.reload.tags.reload, saved_tag assert !posts(:thinking).tags.build.persisted? assert !posts(:thinking).tags.new.persisted? @@ -491,7 +490,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_create_associate_when_adding_to_has_many_through count = posts(:thinking).tags.count - push = Tag.create!(:name => 'pushme') + push = Tag.create!(name: "pushme") post_thinking = posts(:thinking) assert_nothing_raised { post_thinking.tags << push } assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag }, @@ -501,7 +500,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase assert_equal(count + 1, post_thinking.reload.tags.size) assert_equal(count + 1, post_thinking.tags.reload.size) - assert_kind_of Tag, post_thinking.tags.create!(:name => 'foo') + assert_kind_of Tag, post_thinking.tags.create!(name: "foo") assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag }, message = "Expected a Tag in tags collection, got #{wrong.class}.") assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging }, @@ -509,7 +508,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase assert_equal(count + 2, post_thinking.reload.tags.size) assert_equal(count + 2, post_thinking.tags.reload.size) - assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) } + assert_nothing_raised { post_thinking.tags.concat(Tag.create!(name: "abc"), Tag.create!(name: "def")) } assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag }, message = "Expected a Tag in tags collection, got #{wrong.class}.") assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging }, @@ -550,7 +549,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_delete_associate_when_deleting_from_has_many_through_with_nonstandard_id count = books(:awdr).references.count references_before = books(:awdr).references - book = Book.create!(:name => 'Getting Real') + book = Book.create!(name: "Getting Real") book_awdr = books(:awdr) book_awdr.references << book assert_equal(count + 1, book_awdr.references.reload.size) @@ -564,7 +563,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_delete_associate_when_deleting_from_has_many_through count = posts(:thinking).tags.count tags_before = posts(:thinking).tags.sort - tag = Tag.create!(:name => 'doomed') + tag = Tag.create!(name: "doomed") post_thinking = posts(:thinking) post_thinking.tags << tag assert_equal(count + 1, post_thinking.taggings.reload.size) @@ -581,9 +580,9 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_delete_associate_when_deleting_from_has_many_through_with_multiple_tags count = posts(:thinking).tags.count tags_before = posts(:thinking).tags.sort - doomed = Tag.create!(:name => 'doomed') - doomed2 = Tag.create!(:name => 'doomed2') - quaked = Tag.create!(:name => 'quaked') + doomed = Tag.create!(name: "doomed") + doomed2 = Tag.create!(name: "doomed2") + quaked = Tag.create!(name: "quaked") post_thinking = posts(:thinking) post_thinking.tags << doomed << doomed2 assert_equal(count + 2, post_thinking.reload.tags.reload.size) @@ -598,10 +597,10 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:thinking).tags.delete(Object.new) } end - def test_deleting_by_fixnum_id_from_has_many_through + def test_deleting_by_integer_id_from_has_many_through post = posts(:thinking) - assert_difference 'post.tags.count', -1 do + assert_difference "post.tags.count", -1 do assert_equal 1, post.tags.delete(1).size end @@ -611,8 +610,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_deleting_by_string_id_from_has_many_through post = posts(:thinking) - assert_difference 'post.tags.count', -1 do - assert_equal 1, post.tags.delete('1').size + assert_difference "post.tags.count", -1 do + assert_equal 1, post.tags.delete("1").size end assert_equal 0, post.tags.size @@ -642,26 +641,26 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase def test_polymorphic_has_many expected = taggings(:welcome_general) - p = Post.all.merge!(:includes => :taggings).find(posts(:welcome).id) - assert_no_queries {assert p.taggings.include?(expected)} - assert posts(:welcome).taggings.include?(taggings(:welcome_general)) + p = Post.all.merge!(includes: :taggings).find(posts(:welcome).id) + assert_no_queries { assert_includes p.taggings, expected } + assert_includes posts(:welcome).taggings, taggings(:welcome_general) end def test_polymorphic_has_one expected = posts(:welcome) - tagging = Tagging.all.merge!(:includes => :taggable).find(taggings(:welcome_general).id) - assert_no_queries { assert_equal expected, tagging.taggable} + tagging = Tagging.all.merge!(includes: :taggable).find(taggings(:welcome_general).id) + assert_no_queries { assert_equal expected, tagging.taggable } end def test_polymorphic_belongs_to - p = Post.all.merge!(:includes => {:taggings => :taggable}).find(posts(:welcome).id) - assert_no_queries {assert_equal posts(:welcome), p.taggings.first.taggable} + p = Post.all.merge!(includes: { taggings: :taggable }).find(posts(:welcome).id) + assert_no_queries { assert_equal posts(:welcome), p.taggings.first.taggable } end def test_preload_polymorphic_has_many_through - posts = Post.all.merge!(:order => 'posts.id').to_a - posts_with_tags = Post.all.merge!(:includes => :tags, :order => 'posts.id').to_a + posts = Post.all.merge!(order: "posts.id").to_a + posts_with_tags = Post.all.merge!(includes: :tags, order: "posts.id").to_a assert_equal posts.length, posts_with_tags.length posts.length.times do |i| assert_equal posts[i].tags.length, assert_no_queries { posts_with_tags[i].tags.length } @@ -669,26 +668,26 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_preload_polymorph_many_types - taggings = Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type != ?', 'FakeModel']).to_a + taggings = Tagging.all.merge!(includes: :taggable, where: ["taggable_type != ?", "FakeModel"]).to_a assert_no_queries do taggings.first.taggable.id taggings[1].taggable.id end taggables = taggings.map(&:taggable) - assert taggables.include?(items(:dvd)) - assert taggables.include?(posts(:welcome)) + assert_includes taggables, items(:dvd) + assert_includes taggables, posts(:welcome) end def test_preload_nil_polymorphic_belongs_to assert_nothing_raised do - Tagging.all.merge!(:includes => :taggable, :where => ['taggable_type IS NULL']).to_a + Tagging.all.merge!(includes: :taggable, where: ["taggable_type IS NULL"]).to_a end end def test_preload_polymorphic_has_many - posts = Post.all.merge!(:order => 'posts.id').to_a - posts_with_taggings = Post.all.merge!(:includes => :taggings, :order => 'posts.id').to_a + posts = Post.all.merge!(order: "posts.id").to_a + posts_with_taggings = Post.all.merge!(includes: :taggings, order: "posts.id").to_a assert_equal posts.length, posts_with_taggings.length posts.length.times do |i| assert_equal posts[i].taggings.length, assert_no_queries { posts_with_taggings[i].taggings.length } @@ -696,7 +695,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase end def test_belongs_to_shared_parent - comments = Comment.all.merge!(:includes => :post, :where => 'post_id = 1').to_a + comments = Comment.all.merge!(includes: :post, where: "post_id = 1").to_a assert_no_queries do assert_equal comments.first.post, comments[1].post end @@ -710,7 +709,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase assert_no_queries do assert david.categories.loaded? - assert david.categories.include?(category) + assert_includes david.categories, category end end @@ -721,45 +720,45 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase david.reload assert ! david.categories.loaded? assert_queries(1) do - assert david.categories.include?(category) + assert_includes david.categories, category end assert ! david.categories.loaded? end def test_has_many_through_include_returns_false_for_non_matching_record_to_verify_scoping david = authors(:david) - category = Category.create!(:name => 'Not Associated') + category = Category.create!(name: "Not Associated") assert ! david.categories.loaded? assert ! david.categories.include?(category) end def test_has_many_through_goes_through_all_sti_classes - sub_sti_post = SubStiPost.create!(:title => 'test', :body => 'test', :author_id => 1) - new_comment = sub_sti_post.comments.create(:body => 'test') + sub_sti_post = SubStiPost.create!(title: "test", body: "test", author_id: 1) + new_comment = sub_sti_post.comments.create(body: "test") assert_equal [9, 10, new_comment.id], authors(:david).sti_post_comments.map(&:id).sort end def test_has_many_with_pluralize_table_names_false - aircraft = Aircraft.create!(:name => "Airbus 380") - engine = Engine.create!(:car_id => aircraft.id) + aircraft = Aircraft.create!(name: "Airbus 380") + engine = Engine.create!(car_id: aircraft.id) assert_equal aircraft.engines, [engine] end def test_proper_error_message_for_eager_load_and_includes_association_errors includes_error = assert_raises(ActiveRecord::ConfigurationError) { - Post.includes(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1) + Post.includes(:nonexistent_relation).where(nonexistent_relation: { name: "Rochester" }).find(1) } assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", includes_error.message) eager_load_error = assert_raises(ActiveRecord::ConfigurationError) { - Post.eager_load(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1) + Post.eager_load(:nonexistent_relation).where(nonexistent_relation: { name: "Rochester" }).find(1) } assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", eager_load_error.message) includes_and_eager_load_error = assert_raises(ActiveRecord::ConfigurationError) { - Post.eager_load(:nonexistent_relation).includes(:nonexistent_relation).where(nonexistent_relation: {name: 'Rochester'}).find(1) + Post.eager_load(:nonexistent_relation).includes(:nonexistent_relation).where(nonexistent_relation: { name: "Rochester" }).find(1) } assert_equal("Can't join 'Post' to association named 'nonexistent_relation'; perhaps you misspelled it?", includes_and_eager_load_error.message) end @@ -770,8 +769,8 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase class_name = "PostWith#{association.to_s.classify}#{dependency.to_s.classify}" Post.find(post_id).update_columns type: class_name klass = Object.const_set(class_name, Class.new(ActiveRecord::Base)) - klass.table_name = 'posts' - klass.send(association, association_name, :as => :taggable, :dependent => dependency) + klass.table_name = "posts" + klass.send(association, association_name, as: :taggable, dependent: dependency) klass.find(post_id) end end diff --git a/activerecord/test/cases/associations/left_outer_join_association_test.rb b/activerecord/test/cases/associations/left_outer_join_association_test.rb index 4af791b758..2cc6468827 100644 --- a/activerecord/test/cases/associations/left_outer_join_association_test.rb +++ b/activerecord/test/cases/associations/left_outer_join_association_test.rb @@ -1,10 +1,11 @@ require "cases/helper" -require 'models/post' -require 'models/comment' -require 'models/author' -require 'models/essay' -require 'models/categorization' -require 'models/person' +require "models/post" +require "models/comment" +require "models/author" +require "models/essay" +require "models/categorization" +require "models/person" +require "active_support/core_ext/regexp" class LeftOuterJoinAssociationTest < ActiveRecord::TestCase fixtures :authors, :essays, :posts, :comments, :categorizations, :people @@ -17,45 +18,54 @@ class LeftOuterJoinAssociationTest < ActiveRecord::TestCase def test_construct_finder_sql_does_not_table_name_collide_on_duplicate_associations assert_nothing_raised do queries = capture_sql do - Person.left_outer_joins(:agents => {:agents => :agents}) - .left_outer_joins(:agents => {:agents => {:primary_contact => :agents}}).to_a + Person.left_outer_joins(agents: { agents: :agents }) + .left_outer_joins(agents: { agents: { primary_contact: :agents } }).to_a end - assert queries.any? { |sql| /agents_people_4/i =~ sql } + assert queries.any? { |sql| /agents_people_4/i.match?(sql) } end end - def test_construct_finder_sql_executes_a_left_outer_join - assert_not_equal Author.count, Author.joins(:posts).count - assert_equal Author.count, Author.left_outer_joins(:posts).count + def test_left_outer_joins_count_is_same_as_size_of_loaded_results + assert_equal 17, Post.left_outer_joins(:comments).to_a.size + assert_equal 17, Post.left_outer_joins(:comments).count end - def test_left_outer_join_by_left_joins - assert_not_equal Author.count, Author.joins(:posts).count - assert_equal Author.count, Author.left_joins(:posts).count + def test_left_joins_aliases_left_outer_joins + assert_equal Post.left_outer_joins(:comments).to_sql, Post.left_joins(:comments).to_sql + end + + def test_left_outer_joins_return_has_value_for_every_comment + all_post_ids = Post.pluck(:id) + assert_equal all_post_ids, all_post_ids & Post.left_outer_joins(:comments).pluck(:id) + end + + def test_left_outer_joins_actually_does_a_left_outer_join + queries = capture_sql { Author.left_outer_joins(:posts).to_a } + assert queries.any? { |sql| /LEFT OUTER JOIN/i.match?(sql) } end def test_construct_finder_sql_ignores_empty_left_outer_joins_hash - queries = capture_sql { Author.left_outer_joins({}) } - assert queries.none? { |sql| /LEFT OUTER JOIN/i =~ sql } + queries = capture_sql { Author.left_outer_joins({}).to_a } + assert queries.none? { |sql| /LEFT OUTER JOIN/i.match?(sql) } end def test_construct_finder_sql_ignores_empty_left_outer_joins_array - queries = capture_sql { Author.left_outer_joins([]) } - assert queries.none? { |sql| /LEFT OUTER JOIN/i =~ sql } + queries = capture_sql { Author.left_outer_joins([]).to_a } + assert queries.none? { |sql| /LEFT OUTER JOIN/i.match?(sql) } end def test_left_outer_joins_forbids_to_use_string_as_argument - assert_raise(ArgumentError){ Author.left_outer_joins('LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"').to_a } + assert_raise(ArgumentError) { Author.left_outer_joins('LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"').to_a } end def test_join_conditions_added_to_join_clause queries = capture_sql { Author.left_outer_joins(:essays).to_a } - assert queries.any? { |sql| /writer_type.*?=.*?(Author|\?|\$1)/i =~ sql } - assert queries.none? { |sql| /WHERE/i =~ sql } + assert queries.any? { |sql| /writer_type.*?=.*?(Author|\?|\$1|\:a1)/i.match?(sql) } + assert queries.none? { |sql| /WHERE/i.match?(sql) } end def test_find_with_sti_join - scope = Post.left_outer_joins(:special_comments).where(:id => posts(:sti_comments).id) + scope = Post.left_outer_joins(:special_comments).where(id: posts(:sti_comments).id) # The join should match SpecialComment and its subclasses only assert scope.where("comments.type" => "Comment").empty? diff --git a/activerecord/test/cases/associations/nested_through_associations_test.rb b/activerecord/test/cases/associations/nested_through_associations_test.rb index b040485d99..dc26f6a383 100644 --- a/activerecord/test/cases/associations/nested_through_associations_test.rb +++ b/activerecord/test/cases/associations/nested_through_associations_test.rb @@ -1,27 +1,27 @@ require "cases/helper" -require 'models/author' -require 'models/post' -require 'models/person' -require 'models/reference' -require 'models/job' -require 'models/reader' -require 'models/comment' -require 'models/tag' -require 'models/tagging' -require 'models/subscriber' -require 'models/book' -require 'models/subscription' -require 'models/rating' -require 'models/member' -require 'models/member_detail' -require 'models/member_type' -require 'models/sponsor' -require 'models/club' -require 'models/organization' -require 'models/category' -require 'models/categorization' -require 'models/membership' -require 'models/essay' +require "models/author" +require "models/post" +require "models/person" +require "models/reference" +require "models/job" +require "models/reader" +require "models/comment" +require "models/tag" +require "models/tagging" +require "models/subscriber" +require "models/book" +require "models/subscription" +require "models/rating" +require "models/member" +require "models/member_detail" +require "models/member_type" +require "models/sponsor" +require "models/club" +require "models/organization" +require "models/category" +require "models/categorization" +require "models/membership" +require "models/essay" class NestedThroughAssociationsTest < ActiveRecord::TestCase fixtures :authors, :books, :posts, :subscriptions, :subscribers, :tags, :taggings, @@ -65,12 +65,12 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_many_with_has_many_through_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Author.where('tags.id' => tags(:general).id), + Author.where("tags.id" => tags(:general).id), [authors(:david)], :tags ) # This ensures that the polymorphism of taggings is being observed correctly - authors = Author.joins(:tags).where('taggings.taggable_type' => 'FakeModel') + authors = Author.joins(:tags).where("taggings.taggable_type" => "FakeModel") assert authors.empty? end @@ -79,7 +79,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase # Through: has_many through def test_has_many_through_has_many_through_with_has_many_source_reflection luke, david = subscribers(:first), subscribers(:second) - assert_equal [luke, david, david], authors(:david).subscribers.order('subscribers.nick') + assert_equal [luke, david, david], authors(:david).subscribers.order("subscribers.nick") end def test_has_many_through_has_many_through_with_has_many_source_reflection_preload @@ -93,7 +93,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_many_through_with_has_many_source_reflection_preload_via_joins # All authors with subscribers where one of the subscribers' nick is 'alterself' assert_includes_and_joins_equal( - Author.where('subscribers.nick' => 'alterself'), + Author.where("subscribers.nick" => "alterself"), [authors(:david)], :subscribers ) end @@ -115,7 +115,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_one_with_has_one_through_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Member.where('member_types.id' => member_types(:founding).id), + Member.where("member_types.id" => member_types(:founding).id), [members(:groucho)], :nested_member_types ) end @@ -137,7 +137,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_one_through_with_has_one_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Member.where('sponsors.id' => sponsors(:moustache_club_sponsor_for_groucho).id), + Member.where("sponsors.id" => sponsors(:moustache_club_sponsor_for_groucho).id), [members(:groucho)], :nested_sponsors ) end @@ -149,7 +149,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase groucho_details, other_details = member_details(:groucho), member_details(:some_other_guy) assert_equal [groucho_details, other_details], - members(:groucho).organization_member_details.order('member_details.id') + members(:groucho).organization_member_details.order("member_details.id") end def test_has_many_through_has_one_with_has_many_through_source_reflection_preload @@ -164,12 +164,12 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_one_with_has_many_through_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Member.where('member_details.id' => member_details(:groucho).id).order('member_details.id'), + Member.where("member_details.id" => member_details(:groucho).id).order("member_details.id"), [members(:groucho), members(:some_other_guy)], :organization_member_details ) members = Member.joins(:organization_member_details). - where('member_details.id' => 9) + where("member_details.id" => 9) assert members.empty? end @@ -180,7 +180,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase groucho_details, other_details = member_details(:groucho), member_details(:some_other_guy) assert_equal [groucho_details, other_details], - members(:groucho).organization_member_details_2.order('member_details.id') + members(:groucho).organization_member_details_2.order("member_details.id") end def test_has_many_through_has_one_through_with_has_many_source_reflection_preload @@ -196,12 +196,12 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_one_through_with_has_many_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Member.where('member_details.id' => member_details(:groucho).id).order('member_details.id'), + Member.where("member_details.id" => member_details(:groucho).id).order("member_details.id"), [members(:groucho), members(:some_other_guy)], :organization_member_details_2 ) members = Member.joins(:organization_member_details_2). - where('member_details.id' => 9) + where("member_details.id" => 9) assert members.empty? end @@ -211,7 +211,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_many_with_has_and_belongs_to_many_source_reflection general, cooking = categories(:general), categories(:cooking) - assert_equal [general, cooking], authors(:bob).post_categories.order('categories.id') + assert_equal [general, cooking], authors(:bob).post_categories.order("categories.id") end def test_has_many_through_has_many_with_has_and_belongs_to_many_source_reflection_preload @@ -228,7 +228,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase Author.joins(:post_categories).first assert_includes_and_joins_equal( - Author.where('categories.id' => categories(:cooking).id), + Author.where("categories.id" => categories(:cooking).id), [authors(:bob)], :post_categories ) end @@ -239,7 +239,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_and_belongs_to_many_with_has_many_source_reflection greetings, more = comments(:greetings), comments(:more_greetings) - assert_equal [greetings, more], categories(:technology).post_comments.order('comments.id') + assert_equal [greetings, more], categories(:technology).post_comments.order("comments.id") end def test_has_many_through_has_and_belongs_to_many_with_has_many_source_reflection_preload @@ -257,7 +257,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase Category.joins(:post_comments).first assert_includes_and_joins_equal( - Category.where('comments.id' => comments(:more_greetings).id).order('categories.id'), + Category.where("comments.id" => comments(:more_greetings).id).order("categories.id"), [categories(:general), categories(:technology)], :post_comments ) end @@ -268,7 +268,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_many_with_has_many_through_habtm_source_reflection greetings, more = comments(:greetings), comments(:more_greetings) - assert_equal [greetings, more], authors(:bob).category_post_comments.order('comments.id') + assert_equal [greetings, more], authors(:bob).category_post_comments.order("comments.id") end def test_has_many_through_has_many_with_has_many_through_habtm_source_reflection_preload @@ -285,7 +285,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase Author.joins(:category_post_comments).first assert_includes_and_joins_equal( - Author.where('comments.id' => comments(:does_it_hurt).id).order('authors.id'), + Author.where("comments.id" => comments(:does_it_hurt).id).order("authors.id"), [authors(:david), authors(:mary)], :category_post_comments ) end @@ -308,7 +308,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_has_many_through_with_belongs_to_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Author.where('tags.id' => tags(:general).id), + Author.where("tags.id" => tags(:general).id), [authors(:david)], :tagging_tags ) end @@ -320,7 +320,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase welcome_general, thinking_general = taggings(:welcome_general), taggings(:thinking_general) assert_equal [welcome_general, thinking_general], - categorizations(:david_welcome_general).post_taggings.order('taggings.id') + categorizations(:david_welcome_general).post_taggings.order("taggings.id") end def test_has_many_through_belongs_to_with_has_many_through_source_reflection_preload @@ -334,7 +334,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_many_through_belongs_to_with_has_many_through_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Categorization.where('taggings.id' => taggings(:welcome_general).id).order('taggings.id'), + Categorization.where("taggings.id" => taggings(:welcome_general).id).order("taggings.id"), [categorizations(:david_welcome_general)], :post_taggings ) end @@ -357,7 +357,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_one_through_has_one_with_has_one_through_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Member.where('member_types.id' => member_types(:founding).id), + Member.where("member_types.id" => member_types(:founding).id), [members(:groucho)], :nested_member_type ) end @@ -391,7 +391,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_has_one_through_has_one_through_with_belongs_to_source_reflection_preload_via_joins assert_includes_and_joins_equal( - Member.where('categories.id' => categories(:technology).id), + Member.where("categories.id" => categories(:technology).id), [members(:blarpy_winkup)], :club_category ) end @@ -404,7 +404,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_distinct_has_many_through_a_has_many_through_association_on_through_reflection author = authors(:david) assert_equal [subscribers(:first), subscribers(:second)], - author.distinct_subscribers.order('subscribers.nick') + author.distinct_subscribers.order("subscribers.nick") end def test_nested_has_many_through_with_a_table_referenced_multiple_times @@ -413,26 +413,26 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase author.similar_posts.sort_by(&:id) # Mary and Bob both have posts in misc, but they are the only ones. - authors = Author.joins(:similar_posts).where('posts.id' => posts(:misc_by_bob).id) + authors = Author.joins(:similar_posts).where("posts.id" => posts(:misc_by_bob).id) assert_equal [authors(:mary), authors(:bob)], authors.distinct.sort_by(&:id) # Check the polymorphism of taggings is being observed correctly (in both joins) - authors = Author.joins(:similar_posts).where('taggings.taggable_type' => 'FakeModel') + authors = Author.joins(:similar_posts).where("taggings.taggable_type" => "FakeModel") assert authors.empty? - authors = Author.joins(:similar_posts).where('taggings_authors_join.taggable_type' => 'FakeModel') + authors = Author.joins(:similar_posts).where("taggings_authors_join.taggable_type" => "FakeModel") assert authors.empty? end def test_has_many_through_with_foreign_key_option_on_through_reflection - assert_equal [posts(:welcome), posts(:authorless)], people(:david).agents_posts.order('posts.id') + assert_equal [posts(:welcome), posts(:authorless)], people(:david).agents_posts.order("posts.id") assert_equal [authors(:david)], references(:david_unicyclist).agents_posts_authors - references = Reference.joins(:agents_posts_authors).where('authors.id' => authors(:david).id) + references = Reference.joins(:agents_posts_authors).where("authors.id" => authors(:david).id) assert_equal [references(:david_unicyclist)], references end def test_has_many_through_with_foreign_key_option_on_source_reflection - assert_equal [people(:michael), people(:susan)], jobs(:unicyclist).agents.order('people.id') + assert_equal [people(:michael), people(:susan)], jobs(:unicyclist).agents.order("people.id") jobs = Job.joins(:agents) assert_equal [jobs(:unicyclist), jobs(:unicyclist)], jobs @@ -443,7 +443,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase assert_equal [ratings(:special_comment_rating), ratings(:sub_special_comment_rating)], ratings # Ensure STI is respected in the join - scope = Post.joins(:special_comments_ratings).where(:id => posts(:sti_comments).id) + scope = Post.joins(:special_comments_ratings).where(id: posts(:sti_comments).id) assert scope.where("comments.type" => "Comment").empty? assert !scope.where("comments.type" => "SpecialComment").empty? assert !scope.where("comments.type" => "SubSpecialComment").empty? @@ -453,7 +453,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase taggings = posts(:sti_comments).special_comments_ratings_taggings assert_equal [taggings(:special_comment_rating)], taggings - scope = Post.joins(:special_comments_ratings_taggings).where(:id => posts(:sti_comments).id) + scope = Post.joins(:special_comments_ratings_taggings).where(id: posts(:sti_comments).id) assert scope.where("comments.type" => "Comment").empty? assert !scope.where("comments.type" => "SpecialComment").empty? end @@ -505,7 +505,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase end def test_nested_has_many_through_with_conditions_on_through_associations_preload - assert Author.where('tags.id' => 100).joins(:misc_post_first_blue_tags).empty? + assert Author.where("tags.id" => 100).joins(:misc_post_first_blue_tags).empty? authors = assert_queries(3) { Author.includes(:misc_post_first_blue_tags).to_a.sort_by(&:id) } blue = tags(:blue) @@ -518,7 +518,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_nested_has_many_through_with_conditions_on_through_associations_preload_via_joins # Pointless condition to force single-query loading assert_includes_and_joins_equal( - Author.where('tags.id = tags.id').references(:tags), + Author.where("tags.id = tags.id").references(:tags), [authors(:bob)], :misc_post_first_blue_tags ) end @@ -539,7 +539,7 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase def test_nested_has_many_through_with_conditions_on_source_associations_preload_via_joins # Pointless condition to force single-query loading assert_includes_and_joins_equal( - Author.where('tags.id = tags.id').references(:tags), + Author.where("tags.id = tags.id").references(:tags), [authors(:bob)], :misc_post_first_blue_tags_2 ) end @@ -548,13 +548,13 @@ class NestedThroughAssociationsTest < ActiveRecord::TestCase assert_equal [categories(:general)], organizations(:nsa).author_essay_categories organizations = Organization.joins(:author_essay_categories). - where('categories.id' => categories(:general).id) + where("categories.id" => categories(:general).id) assert_equal [organizations(:nsa)], organizations assert_equal categories(:general), organizations(:nsa).author_owned_essay_category organizations = Organization.joins(:author_owned_essay_category). - where('categories.id' => categories(:general).id) + where("categories.id" => categories(:general).id) assert_equal [organizations(:nsa)], organizations end diff --git a/activerecord/test/cases/associations/required_test.rb b/activerecord/test/cases/associations/required_test.rb index 3e5494e897..f8b686721e 100644 --- a/activerecord/test/cases/associations/required_test.rb +++ b/activerecord/test/cases/associations/required_test.rb @@ -18,8 +18,8 @@ class RequiredAssociationsTest < ActiveRecord::TestCase end teardown do - @connection.drop_table 'parents', if_exists: true - @connection.drop_table 'children', if_exists: true + @connection.drop_table "parents", if_exists: true + @connection.drop_table "children", if_exists: true end test "belongs_to associations are not required by default" do @@ -92,11 +92,11 @@ class RequiredAssociationsTest < ActiveRecord::TestCase private - def subclass_of(klass, &block) - subclass = Class.new(klass, &block) - def subclass.name - superclass.name + def subclass_of(klass, &block) + subclass = Class.new(klass, &block) + def subclass.name + superclass.name + end + subclass end - subclass - end end diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 01a058918a..c095b3a91c 100644 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -1,80 +1,77 @@ require "cases/helper" -require 'models/computer' -require 'models/developer' -require 'models/project' -require 'models/company' -require 'models/categorization' -require 'models/category' -require 'models/post' -require 'models/author' -require 'models/comment' -require 'models/tag' -require 'models/tagging' -require 'models/person' -require 'models/reader' -require 'models/ship_part' -require 'models/ship' -require 'models/liquid' -require 'models/molecule' -require 'models/electron' -require 'models/man' -require 'models/interest' +require "models/computer" +require "models/developer" +require "models/project" +require "models/company" +require "models/categorization" +require "models/category" +require "models/post" +require "models/author" +require "models/comment" +require "models/tag" +require "models/tagging" +require "models/person" +require "models/reader" +require "models/ship_part" +require "models/ship" +require "models/liquid" +require "models/molecule" +require "models/electron" +require "models/man" +require "models/interest" class AssociationsTest < ActiveRecord::TestCase fixtures :accounts, :companies, :developers, :projects, :developers_projects, :computers, :people, :readers, :authors, :author_favorites def test_eager_loading_should_not_change_count_of_children - liquid = Liquid.create(:name => 'salty') - molecule = liquid.molecules.create(:name => 'molecule_1') - molecule.electrons.create(:name => 'electron_1') - molecule.electrons.create(:name => 'electron_2') + liquid = Liquid.create(name: "salty") + molecule = liquid.molecules.create(name: "molecule_1") + molecule.electrons.create(name: "electron_1") + molecule.electrons.create(name: "electron_2") - liquids = Liquid.includes(:molecules => :electrons).references(:molecules).where('molecules.id is not null') + liquids = Liquid.includes(molecules: :electrons).references(:molecules).where("molecules.id is not null") assert_equal 1, liquids[0].molecules.length end def test_subselect author = authors :david favs = author.author_favorites - fav2 = author.author_favorites.where(:author => Author.where(id: author.id)).to_a + fav2 = author.author_favorites.where(author: Author.where(id: author.id)).to_a assert_equal favs, fav2 end def test_loading_the_association_target_should_keep_child_records_marked_for_destruction - ship = Ship.create!(:name => "The good ship Dollypop") - part = ship.parts.create!(:name => "Mast") + ship = Ship.create!(name: "The good ship Dollypop") + part = ship.parts.create!(name: "Mast") part.mark_for_destruction - ship.parts.send(:load_target) assert ship.parts[0].marked_for_destruction? end def test_loading_the_association_target_should_load_most_recent_attributes_for_child_records_marked_for_destruction - ship = Ship.create!(:name => "The good ship Dollypop") - part = ship.parts.create!(:name => "Mast") + ship = Ship.create!(name: "The good ship Dollypop") + part = ship.parts.create!(name: "Mast") part.mark_for_destruction - ShipPart.find(part.id).update_columns(name: 'Deck') - ship.parts.send(:load_target) - assert_equal 'Deck', ship.parts[0].name + ShipPart.find(part.id).update_columns(name: "Deck") + assert_equal "Deck", ship.parts[0].name end - def test_include_with_order_works - assert_nothing_raised {Account.all.merge!(:order => 'id', :includes => :firm).first} - assert_nothing_raised {Account.all.merge!(:order => :id, :includes => :firm).first} + assert_nothing_raised { Account.all.merge!(order: "id", includes: :firm).first } + assert_nothing_raised { Account.all.merge!(order: :id, includes: :firm).first } end def test_bad_collection_keys - assert_raise(ArgumentError, 'ActiveRecord should have barked on bad collection keys') do - Class.new(ActiveRecord::Base).has_many(:wheels, :name => 'wheels') + assert_raise(ArgumentError, "ActiveRecord should have barked on bad collection keys") do + Class.new(ActiveRecord::Base).has_many(:wheels, name: "wheels") end end def test_should_construct_new_finder_sql_after_create - person = Person.new :first_name => 'clark' + person = Person.new first_name: "clark" assert_equal [], person.readers.to_a person.save! - reader = Reader.create! :person => person, :post => Post.new(:title => "foo", :body => "bar") + reader = Reader.create! person: person, post: Post.new(title: "foo", body: "bar") assert person.readers.find(reader.id) end @@ -122,9 +119,8 @@ class AssociationsTest < ActiveRecord::TestCase def test_association_with_references firm = companies(:first_firm) - assert_includes firm.association_with_references.references_values, 'foo' + assert_includes firm.association_with_references.references_values, "foo" end - end class AssociationProxyTest < ActiveRecord::TestCase @@ -133,9 +129,9 @@ class AssociationProxyTest < ActiveRecord::TestCase def test_push_does_not_load_target david = authors(:david) - david.posts << (post = Post.new(:title => "New on Edge", :body => "More cool stuff!")) + david.posts << (post = Post.new(title: "New on Edge", body: "More cool stuff!")) assert !david.posts.loaded? - assert david.posts.include?(post) + assert_includes david.posts, post end def test_push_has_many_through_does_not_load_target @@ -143,35 +139,35 @@ class AssociationProxyTest < ActiveRecord::TestCase david.categories << categories(:technology) assert !david.categories.loaded? - assert david.categories.include?(categories(:technology)) + assert_includes david.categories, categories(:technology) end def test_push_followed_by_save_does_not_load_target david = authors(:david) - david.posts << (post = Post.new(:title => "New on Edge", :body => "More cool stuff!")) + david.posts << (post = Post.new(title: "New on Edge", body: "More cool stuff!")) assert !david.posts.loaded? david.save assert !david.posts.loaded? - assert david.posts.include?(post) + assert_includes david.posts, post end def test_push_does_not_lose_additions_to_new_record - josh = Author.new(:name => "Josh") - josh.posts << Post.new(:title => "New on Edge", :body => "More cool stuff!") + josh = Author.new(name: "Josh") + josh.posts << Post.new(title: "New on Edge", body: "More cool stuff!") assert josh.posts.loaded? assert_equal 1, josh.posts.size end def test_append_behaves_like_push - josh = Author.new(:name => "Josh") - josh.posts.append Post.new(:title => "New on Edge", :body => "More cool stuff!") + josh = Author.new(name: "Josh") + josh.posts.append Post.new(title: "New on Edge", body: "More cool stuff!") assert josh.posts.loaded? assert_equal 1, josh.posts.size end def test_prepend_is_not_defined - josh = Author.new(:name => "Josh") + josh = Author.new(name: "Josh") assert_raises(NoMethodError) { josh.posts.prepend Post.new } end @@ -183,25 +179,33 @@ class AssociationProxyTest < ActiveRecord::TestCase assert !david.projects.loaded? end + def test_load_does_load_target + david = developers(:david) + + assert !david.projects.loaded? + david.projects.load + assert david.projects.loaded? + end + def test_inspect_does_not_reload_a_not_yet_loaded_target - andreas = Developer.new :name => 'Andreas', :log => 'new developer added' + andreas = Developer.new name: "Andreas", log: "new developer added" assert !andreas.audit_logs.loaded? assert_match(/message: "new developer added"/, andreas.audit_logs.inspect) end def test_save_on_parent_saves_children - developer = Developer.create :name => "Bryan", :salary => 50_000 + developer = Developer.create name: "Bryan", salary: 50_000 assert_equal 1, developer.reload.audit_logs.size end def test_create_via_association_with_block - post = authors(:david).posts.create(:title => "New on Edge") {|p| p.body = "More cool stuff!"} + post = authors(:david).posts.create(title: "New on Edge") { |p| p.body = "More cool stuff!" } assert_equal post.title, "New on Edge" assert_equal post.body, "More cool stuff!" end def test_create_with_bang_via_association_with_block - post = authors(:david).posts.create!(:title => "New on Edge") {|p| p.body = "More cool stuff!"} + post = authors(:david).posts.create!(title: "New on Edge") { |p| p.body = "More cool stuff!" } assert_equal post.title, "New on Edge" assert_equal post.body, "More cool stuff!" end @@ -219,7 +223,7 @@ class AssociationProxyTest < ActiveRecord::TestCase end def test_scoped_allows_conditions - assert developers(:david).projects.merge(where: 'foo').to_sql.include?('foo') + assert developers(:david).projects.merge(where: "foo").to_sql.include?("foo") end test "getting a scope from an association" do @@ -248,6 +252,15 @@ class AssociationProxyTest < ActiveRecord::TestCase test "first! works on loaded associations" do david = authors(:david) assert_equal david.posts.first, david.posts.reload.first! + assert david.posts.loaded? + assert_no_queries { david.posts.first! } + end + + def test_pluck_uses_loaded_target + david = authors(:david) + assert_equal david.posts.pluck(:title), david.posts.load.pluck(:title) + assert david.posts.loaded? + assert_no_queries { david.posts.pluck(:title) } end def test_reset_unloads_target @@ -264,18 +277,18 @@ class OverridingAssociationsTest < ActiveRecord::TestCase class DifferentPerson < ActiveRecord::Base; end class PeopleList < ActiveRecord::Base - has_and_belongs_to_many :has_and_belongs_to_many, :before_add => :enlist - has_many :has_many, :before_add => :enlist + has_and_belongs_to_many :has_and_belongs_to_many, before_add: :enlist + has_many :has_many, before_add: :enlist belongs_to :belongs_to has_one :has_one end class DifferentPeopleList < PeopleList # Different association with the same name, callbacks should be omitted here. - has_and_belongs_to_many :has_and_belongs_to_many, :class_name => 'DifferentPerson' - has_many :has_many, :class_name => 'DifferentPerson' - belongs_to :belongs_to, :class_name => 'DifferentPerson' - has_one :has_one, :class_name => 'DifferentPerson' + has_and_belongs_to_many :has_and_belongs_to_many, class_name: "DifferentPerson" + has_many :has_many, class_name: "DifferentPerson" + belongs_to :belongs_to, class_name: "DifferentPerson" + has_one :has_one, class_name: "DifferentPerson" end def test_habtm_association_redefinition_callbacks_should_differ_and_not_inherited diff --git a/activerecord/test/cases/attribute_decorators_test.rb b/activerecord/test/cases/attribute_decorators_test.rb index 2aeb2601c2..cfa6ed1da6 100644 --- a/activerecord/test/cases/attribute_decorators_test.rb +++ b/activerecord/test/cases/attribute_decorators_test.rb @@ -1,9 +1,9 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class AttributeDecoratorsTest < ActiveRecord::TestCase class Model < ActiveRecord::Base - self.table_name = 'attribute_decorators_model' + self.table_name = "attribute_decorators_model" end class StringDecorator < SimpleDelegator @@ -28,19 +28,19 @@ module ActiveRecord teardown do return unless @connection - @connection.drop_table 'attribute_decorators_model', if_exists: true + @connection.drop_table "attribute_decorators_model", if_exists: true Model.attribute_type_decorations.clear Model.reset_column_information end test "attributes can be decorated" do - model = Model.new(a_string: 'Hello') - assert_equal 'Hello', model.a_string + model = Model.new(a_string: "Hello") + assert_equal "Hello", model.a_string Model.decorate_attribute_type(:a_string, :test) { |t| StringDecorator.new(t) } - model = Model.new(a_string: 'Hello') - assert_equal 'Hello decorated!', model.a_string + model = Model.new(a_string: "Hello") + assert_equal "Hello decorated!", model.a_string end test "decoration does not eagerly load existing columns" do @@ -51,54 +51,54 @@ module ActiveRecord end test "undecorated columns are not touched" do - Model.attribute :another_string, :string, default: 'something or other' + Model.attribute :another_string, :string, default: "something or other" Model.decorate_attribute_type(:a_string, :test) { |t| StringDecorator.new(t) } - assert_equal 'something or other', Model.new.another_string + assert_equal "something or other", Model.new.another_string end test "decorators can be chained" do Model.decorate_attribute_type(:a_string, :test) { |t| StringDecorator.new(t) } Model.decorate_attribute_type(:a_string, :other) { |t| StringDecorator.new(t) } - model = Model.new(a_string: 'Hello!') + model = Model.new(a_string: "Hello!") - assert_equal 'Hello! decorated! decorated!', model.a_string + assert_equal "Hello! decorated! decorated!", model.a_string end test "decoration of the same type multiple times is idempotent" do Model.decorate_attribute_type(:a_string, :test) { |t| StringDecorator.new(t) } Model.decorate_attribute_type(:a_string, :test) { |t| StringDecorator.new(t) } - model = Model.new(a_string: 'Hello') - assert_equal 'Hello decorated!', model.a_string + model = Model.new(a_string: "Hello") + assert_equal "Hello decorated!", model.a_string end test "decorations occur in order of declaration" do Model.decorate_attribute_type(:a_string, :test) { |t| StringDecorator.new(t) } Model.decorate_attribute_type(:a_string, :other) do |type| - StringDecorator.new(type, 'decorated again!') + StringDecorator.new(type, "decorated again!") end - model = Model.new(a_string: 'Hello!') + model = Model.new(a_string: "Hello!") - assert_equal 'Hello! decorated! decorated again!', model.a_string + assert_equal "Hello! decorated! decorated again!", model.a_string end test "decorating attributes does not modify parent classes" do - Model.attribute :another_string, :string, default: 'whatever' + Model.attribute :another_string, :string, default: "whatever" Model.decorate_attribute_type(:a_string, :test) { |t| StringDecorator.new(t) } child_class = Class.new(Model) child_class.decorate_attribute_type(:another_string, :test) { |t| StringDecorator.new(t) } child_class.decorate_attribute_type(:a_string, :other) { |t| StringDecorator.new(t) } - model = Model.new(a_string: 'Hello!') - child = child_class.new(a_string: 'Hello!') + model = Model.new(a_string: "Hello!") + child = child_class.new(a_string: "Hello!") - assert_equal 'Hello! decorated!', model.a_string - assert_equal 'whatever', model.another_string - assert_equal 'Hello! decorated! decorated!', child.a_string - assert_equal 'whatever decorated!', child.another_string + assert_equal "Hello! decorated!", model.a_string + assert_equal "whatever", model.another_string + assert_equal "Hello! decorated! decorated!", child.a_string + assert_equal "whatever decorated!", child.another_string end class Multiplier < SimpleDelegator @@ -116,9 +116,9 @@ module ActiveRecord Multiplier.new(type) end - model = Model.new(a_string: 'whatever', an_int: 1) + model = Model.new(a_string: "whatever", an_int: 1) - assert_equal 'whatever', model.a_string + assert_equal "whatever", model.a_string assert_equal 2, model.an_int end end diff --git a/activerecord/test/cases/attribute_methods/read_test.rb b/activerecord/test/cases/attribute_methods/read_test.rb index 74e556211b..a8592bd179 100644 --- a/activerecord/test/cases/attribute_methods/read_test.rb +++ b/activerecord/test/cases/attribute_methods/read_test.rb @@ -1,5 +1,4 @@ require "cases/helper" -require 'thread' module ActiveRecord module AttributeMethods @@ -40,13 +39,13 @@ module ActiveRecord instance = @klass.new @klass.attribute_names.each do |name| - assert !instance.methods.map(&:to_s).include?(name) + assert_not_includes instance.methods.map(&:to_s), name end @klass.define_attribute_methods @klass.attribute_names.each do |name| - assert instance.methods.map(&:to_s).include?(name), "#{name} is not defined" + assert_includes instance.methods.map(&:to_s), name, "#{name} is not defined" end end diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 1db52af59b..4c77ecab7c 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -1,15 +1,15 @@ require "cases/helper" -require 'models/minimalistic' -require 'models/developer' -require 'models/auto_id' -require 'models/boolean' -require 'models/computer' -require 'models/topic' -require 'models/company' -require 'models/category' -require 'models/reply' -require 'models/contact' -require 'models/keyboard' +require "models/minimalistic" +require "models/developer" +require "models/auto_id" +require "models/boolean" +require "models/computer" +require "models/topic" +require "models/company" +require "models/category" +require "models/reply" +require "models/contact" +require "models/keyboard" class AttributeMethodsTest < ActiveRecord::TestCase include InTimeZone @@ -19,7 +19,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase def setup @old_matchers = ActiveRecord::Base.send(:attribute_method_matchers).dup @target = Class.new(ActiveRecord::Base) - @target.table_name = 'topics' + @target.table_name = "topics" end teardown do @@ -27,15 +27,34 @@ class AttributeMethodsTest < ActiveRecord::TestCase ActiveRecord::Base.send(:attribute_method_matchers).concat(@old_matchers) end - def test_attribute_for_inspect + test "attribute_for_inspect with a string" do t = topics(:first) t.title = "The First Topic Now Has A Title With\nNewlines And More Than 50 Characters" - assert_equal %("#{t.written_on.to_s(:db)}"), t.attribute_for_inspect(:written_on) assert_equal '"The First Topic Now Has A Title With\nNewlines And ..."', t.attribute_for_inspect(:title) end - def test_attribute_present + test "attribute_for_inspect with a date" do + t = topics(:first) + + assert_equal %("#{t.written_on.to_s(:db)}"), t.attribute_for_inspect(:written_on) + end + + test "attribute_for_inspect with an array" do + t = topics(:first) + t.content = [Object.new] + + assert_match %r(\[#<Object:0x[0-9a-f]+>\]), t.attribute_for_inspect(:content) + end + + test "attribute_for_inspect with a long array" do + t = topics(:first) + t.content = (1..11).to_a + + assert_equal "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]", t.attribute_for_inspect(:content) + end + + test "attribute_present" do t = Topic.new t.title = "hello there!" t.written_on = Time.now @@ -46,7 +65,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert !t.attribute_present?("author_name") end - def test_attribute_present_with_booleans + test "attribute_present with booleans" do b1 = Boolean.new b1.value = false assert b1.attribute_present?(:value) @@ -64,44 +83,44 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert Boolean.find(b4.id).attribute_present?(:value) end - def test_caching_nil_primary_key + test "caching a nil primary key" do klass = Class.new(Minimalistic) assert_called(klass, :reset_primary_key, returns: nil) do 2.times { klass.primary_key } end end - def test_attribute_keys_on_new_instance + test "attribute keys on a new instance" do t = Topic.new assert_equal nil, t.title, "The topics table has a title column, so it should be nil" assert_raise(NoMethodError) { t.title2 } end - def test_boolean_attributes + test "boolean attributes" do assert !Topic.find(1).approved? assert Topic.find(2).approved? end - def test_set_attributes + test "set attributes" do topic = Topic.find(1) - topic.attributes = { "title" => "Budget", "author_name" => "Jason" } + topic.attributes = { title: "Budget", author_name: "Jason" } topic.save assert_equal("Budget", topic.title) assert_equal("Jason", topic.author_name) assert_equal(topics(:first).author_email_address, Topic.find(1).author_email_address) end - def test_set_attributes_without_hash + test "set attributes without a hash" do topic = Topic.new - assert_raise(ArgumentError) { topic.attributes = '' } + assert_raise(ArgumentError) { topic.attributes = "" } end - def test_integers_as_nil - test = AutoId.create('value' => '') + test "integers as nil" do + test = AutoId.create(value: "") assert_nil AutoId.find(test.id).value end - def test_set_attributes_with_block + test "set attributes with a block" do topic = Topic.new do |t| t.title = "Budget" t.author_name = "Jason" @@ -111,7 +130,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal("Jason", topic.author_name) end - def test_respond_to? + test "respond_to?" do topic = Topic.find(1) assert_respond_to topic, "title" assert_respond_to topic, "title?" @@ -125,27 +144,27 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert !topic.respond_to?(:nothingness) end - def test_respond_to_with_custom_primary_key + test "respond_to? with a custom primary key" do keyboard = Keyboard.create assert_not_nil keyboard.key_number assert_equal keyboard.key_number, keyboard.id - assert keyboard.respond_to?('key_number') - assert keyboard.respond_to?('id') + assert keyboard.respond_to?("key_number") + assert keyboard.respond_to?("id") end - def test_id_before_type_cast_with_custom_primary_key + test "id_before_type_cast with a custom primary key" do keyboard = Keyboard.create - keyboard.key_number = '10' - assert_equal '10', keyboard.id_before_type_cast - assert_equal nil, keyboard.read_attribute_before_type_cast('id') - assert_equal '10', keyboard.read_attribute_before_type_cast('key_number') - assert_equal '10', keyboard.read_attribute_before_type_cast(:key_number) + keyboard.key_number = "10" + assert_equal "10", keyboard.id_before_type_cast + assert_equal nil, keyboard.read_attribute_before_type_cast("id") + assert_equal "10", keyboard.read_attribute_before_type_cast("key_number") + assert_equal "10", keyboard.read_attribute_before_type_cast(:key_number) end - # Syck calls respond_to? before actually calling initialize - def test_respond_to_with_allocated_object + # Syck calls respond_to? before actually calling initialize. + test "respond_to? with an allocated object" do klass = Class.new(ActiveRecord::Base) do - self.table_name = 'topics' + self.table_name = "topics" end topic = klass.allocate @@ -155,31 +174,32 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_respond_to topic, :title end - # IRB inspects the return value of "MyModel.allocate". - def test_allocated_object_can_be_inspected + # IRB inspects the return value of MyModel.allocate. + test "allocated objects can be inspected" do topic = Topic.allocate assert_equal "#<Topic not initialized>", topic.inspect end - def test_array_content + test "array content" do + content = %w( one two three ) topic = Topic.new - topic.content = %w( one two three ) + topic.content = content topic.save - assert_equal(%w( one two three ), Topic.find(topic.id).content) + assert_equal content, Topic.find(topic.id).content end - def test_read_attributes_before_type_cast - category = Category.new({:name=>"Test category", :type => nil}) - category_attrs = {"name"=>"Test category", "id" => nil, "type" => nil, "categorizations_count" => nil} - assert_equal category_attrs , category.attributes_before_type_cast + test "read attributes_before_type_cast" do + category = Category.new(name: "Test category", type: nil) + category_attrs = { "name" => "Test category", "id" => nil, "type" => nil, "categorizations_count" => nil } + assert_equal category_attrs, category.attributes_before_type_cast end if current_adapter?(:Mysql2Adapter) - def test_read_attributes_before_type_cast_on_boolean - bool = Boolean.create!({ "value" => false }) - if RUBY_PLATFORM =~ /java/ - # JRuby will return the value before typecast as string + test "read attributes_before_type_cast on a boolean" do + bool = Boolean.create!("value" => false) + if RUBY_PLATFORM.include?("java") + # JRuby will return the value before typecast as string. assert_equal "0", bool.reload.attributes_before_type_cast["value"] else assert_equal 0, bool.reload.attributes_before_type_cast["value"] @@ -187,7 +207,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_read_attributes_before_type_cast_on_datetime + test "read attributes_before_type_cast on a datetime" do in_time_zone "Pacific Time (US & Canada)" do record = @target.new @@ -202,7 +222,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_read_attributes_after_type_cast_on_datetime + test "read attributes_after_type_cast on a date" do tz = "Pacific Time (US & Canada)" in_time_zone tz do @@ -223,7 +243,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_hash_content + test "hash content" do topic = Topic.new topic.content = { "one" => 1, "two" => 2 } topic.save @@ -237,7 +257,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal 3, Topic.find(topic.id).content["three"] end - def test_update_array_content + test "update array content" do topic = Topic.new topic.content = %w( one two three ) @@ -251,25 +271,25 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal(%w( one two three four five ), topic.content) end - def test_case_sensitive_attributes_hash - # DB2 is not case-sensitive + test "case-sensitive attributes hash" do + # DB2 is not case-sensitive. return true if current_adapter?(:DB2Adapter) - assert_equal @loaded_fixtures['computers']['workstation'].to_hash, Computer.first.attributes + assert_equal @loaded_fixtures["computers"]["workstation"].to_hash, Computer.first.attributes end - def test_attributes_without_primary_key + test "attributes without primary key" do klass = Class.new(ActiveRecord::Base) do - self.table_name = 'developers_projects' + self.table_name = "developers_projects" end assert_equal klass.column_names, klass.new.attributes.keys - assert_not klass.new.has_attribute?('id') + assert_not klass.new.has_attribute?("id") end - def test_hashes_not_mangled - new_topic = { :title => "New Topic" } - new_topic_values = { :title => "AnotherTopic" } + test "hashes are not mangled" do + new_topic = { title: "New Topic" } + new_topic_values = { title: "AnotherTopic" } topic = Topic.new(new_topic) assert_equal new_topic[:title], topic.title @@ -278,13 +298,13 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal new_topic_values[:title], topic.title end - def test_create_through_factory - topic = Topic.create("title" => "New Topic") + test "create through factory" do + topic = Topic.create(title: "New Topic") topicReloaded = Topic.find(topic.id) assert_equal(topic, topicReloaded) end - def test_write_attribute + test "write_attribute" do topic = Topic.new topic.send(:write_attribute, :title, "Still another topic") assert_equal "Still another topic", topic.title @@ -299,7 +319,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal "Still another topic: part 4", topic.title end - def test_read_attribute + test "read_attribute" do topic = Topic.new topic.title = "Don't change the topic" assert_equal "Don't change the topic", topic.read_attribute("title") @@ -309,15 +329,15 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal "Don't change the topic", topic[:title] end - def test_read_attribute_raises_missing_attribute_error_when_not_exists - computer = Computer.select('id').first + test "read_attribute raises ActiveModel::MissingAttributeError when the attribute does not exist" do + computer = Computer.select("id").first assert_raises(ActiveModel::MissingAttributeError) { computer[:developer] } assert_raises(ActiveModel::MissingAttributeError) { computer[:extendedWarranty] } - assert_raises(ActiveModel::MissingAttributeError) { computer[:no_column_exists] = 'Hello!' } - assert_nothing_raised { computer[:developer] = 'Hello!' } + assert_raises(ActiveModel::MissingAttributeError) { computer[:no_column_exists] = "Hello!" } + assert_nothing_raised { computer[:developer] = "Hello!" } end - def test_read_attribute_when_false + test "read_attribute when false" do topic = topics(:first) topic.approved = false assert !topic.approved?, "approved should be false" @@ -325,7 +345,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert !topic.approved?, "approved should be false" end - def test_read_attribute_when_true + test "read_attribute when true" do topic = topics(:first) topic.approved = true assert topic.approved?, "approved should be true" @@ -333,7 +353,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert topic.approved?, "approved should be true" end - def test_read_write_boolean_attribute + test "boolean attributes writing and reading" do topic = Topic.new topic.approved = "false" assert !topic.approved?, "approved should be false" @@ -348,7 +368,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert topic.approved?, "approved should be true" end - def test_overridden_write_attribute + test "overridden write_attribute" do topic = Topic.new def topic.write_attribute(attr_name, value) super(attr_name, value.downcase) @@ -367,7 +387,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal "yet another topic: part 4", topic.title end - def test_overridden_read_attribute + test "overridden read_attribute" do topic = Topic.new topic.title = "Stop changing the topic" def topic.read_attribute(attr_name) @@ -381,40 +401,40 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal "STOP CHANGING THE TOPIC", topic[:title] end - def test_read_overridden_attribute - topic = Topic.new(:title => 'a') - def topic.title() 'b' end - assert_equal 'a', topic[:title] + test "read overridden attribute" do + topic = Topic.new(title: "a") + def topic.title() "b" end + assert_equal "a", topic[:title] end - def test_query_attribute_string + test "string attribute predicate" do [nil, "", " "].each do |value| - assert_equal false, Topic.new(:author_name => value).author_name? + assert_equal false, Topic.new(author_name: value).author_name? end - assert_equal true, Topic.new(:author_name => "Name").author_name? + assert_equal true, Topic.new(author_name: "Name").author_name? end - def test_query_attribute_number + test "number attribute predicate" do [nil, 0, "0"].each do |value| - assert_equal false, Developer.new(:salary => value).salary? + assert_equal false, Developer.new(salary: value).salary? end - assert_equal true, Developer.new(:salary => 1).salary? - assert_equal true, Developer.new(:salary => "1").salary? + assert_equal true, Developer.new(salary: 1).salary? + assert_equal true, Developer.new(salary: "1").salary? end - def test_query_attribute_boolean + test "boolean attribute predicate" do [nil, "", false, "false", "f", 0].each do |value| - assert_equal false, Topic.new(:approved => value).approved? + assert_equal false, Topic.new(approved: value).approved? end [true, "true", "1", 1].each do |value| - assert_equal true, Topic.new(:approved => value).approved? + assert_equal true, Topic.new(approved: value).approved? end end - def test_query_attribute_with_custom_fields + test "custom field attribute predicate" do object = Company.find_by_sql(<<-SQL).first SELECT c1.*, c2.type as string_value, c2.rating as int_value FROM companies c1, companies c2 @@ -435,95 +455,95 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert !object.int_value? end - def test_non_attribute_access_and_assignment + test "non-attribute read and write" do topic = Topic.new assert !topic.respond_to?("mumbo") assert_raise(NoMethodError) { topic.mumbo } assert_raise(NoMethodError) { topic.mumbo = 5 } end - def test_undeclared_attribute_method_does_not_affect_respond_to_and_method_missing - topic = @target.new(:title => 'Budget') - assert topic.respond_to?('title') - assert_equal 'Budget', topic.title - assert !topic.respond_to?('title_hello_world') + test "undeclared attribute method does not affect respond_to? and method_missing" do + topic = @target.new(title: "Budget") + assert topic.respond_to?("title") + assert_equal "Budget", topic.title + assert !topic.respond_to?("title_hello_world") assert_raise(NoMethodError) { topic.title_hello_world } end - def test_declared_prefixed_attribute_method_affects_respond_to_and_method_missing - topic = @target.new(:title => 'Budget') + test "declared prefixed attribute method affects respond_to? and method_missing" do + topic = @target.new(title: "Budget") %w(default_ title_).each do |prefix| @target.class_eval "def #{prefix}attribute(*args) args end" @target.attribute_method_prefix prefix meth = "#{prefix}title" assert topic.respond_to?(meth) - assert_equal ['title'], topic.send(meth) - assert_equal ['title', 'a'], topic.send(meth, 'a') - assert_equal ['title', 1, 2, 3], topic.send(meth, 1, 2, 3) + assert_equal ["title"], topic.send(meth) + assert_equal ["title", "a"], topic.send(meth, "a") + assert_equal ["title", 1, 2, 3], topic.send(meth, 1, 2, 3) end end - def test_declared_suffixed_attribute_method_affects_respond_to_and_method_missing + test "declared suffixed attribute method affects respond_to? and method_missing" do %w(_default _title_default _it! _candidate= able?).each do |suffix| @target.class_eval "def attribute#{suffix}(*args) args end" @target.attribute_method_suffix suffix - topic = @target.new(:title => 'Budget') + topic = @target.new(title: "Budget") meth = "title#{suffix}" assert topic.respond_to?(meth) - assert_equal ['title'], topic.send(meth) - assert_equal ['title', 'a'], topic.send(meth, 'a') - assert_equal ['title', 1, 2, 3], topic.send(meth, 1, 2, 3) + assert_equal ["title"], topic.send(meth) + assert_equal ["title", "a"], topic.send(meth, "a") + assert_equal ["title", 1, 2, 3], topic.send(meth, 1, 2, 3) end end - def test_declared_affixed_attribute_method_affects_respond_to_and_method_missing - [['mark_', '_for_update'], ['reset_', '!'], ['default_', '_value?']].each do |prefix, suffix| + test "declared affixed attribute method affects respond_to? and method_missing" do + [["mark_", "_for_update"], ["reset_", "!"], ["default_", "_value?"]].each do |prefix, suffix| @target.class_eval "def #{prefix}attribute#{suffix}(*args) args end" - @target.attribute_method_affix({ :prefix => prefix, :suffix => suffix }) - topic = @target.new(:title => 'Budget') + @target.attribute_method_affix(prefix: prefix, suffix: suffix) + topic = @target.new(title: "Budget") meth = "#{prefix}title#{suffix}" assert topic.respond_to?(meth) - assert_equal ['title'], topic.send(meth) - assert_equal ['title', 'a'], topic.send(meth, 'a') - assert_equal ['title', 1, 2, 3], topic.send(meth, 1, 2, 3) + assert_equal ["title"], topic.send(meth) + assert_equal ["title", "a"], topic.send(meth, "a") + assert_equal ["title", 1, 2, 3], topic.send(meth, 1, 2, 3) end end - def test_should_unserialize_attributes_for_frozen_records - myobj = {:value1 => :value2} - topic = Topic.create("content" => myobj) + test "should unserialize attributes for frozen records" do + myobj = { value1: :value2 } + topic = Topic.create(content: myobj) topic.freeze assert_equal myobj, topic.content end - def test_typecast_attribute_from_select_to_false - Topic.create(:title => 'Budget') - # Oracle does not support boolean expressions in SELECT + test "typecast attribute from select to false" do + Topic.create(title: "Budget") + # Oracle does not support boolean expressions in SELECT. if current_adapter?(:OracleAdapter, :FbAdapter) - topic = Topic.all.merge!(:select => "topics.*, 0 as is_test").first + topic = Topic.all.merge!(select: "topics.*, 0 as is_test").first else - topic = Topic.all.merge!(:select => "topics.*, 1=2 as is_test").first + topic = Topic.all.merge!(select: "topics.*, 1=2 as is_test").first end assert !topic.is_test? end - def test_typecast_attribute_from_select_to_true - Topic.create(:title => 'Budget') - # Oracle does not support boolean expressions in SELECT + test "typecast attribute from select to true" do + Topic.create(title: "Budget") + # Oracle does not support boolean expressions in SELECT. if current_adapter?(:OracleAdapter, :FbAdapter) - topic = Topic.all.merge!(:select => "topics.*, 1 as is_test").first + topic = Topic.all.merge!(select: "topics.*, 1 as is_test").first else - topic = Topic.all.merge!(:select => "topics.*, 2=2 as is_test").first + topic = Topic.all.merge!(select: "topics.*, 2=2 as is_test").first end assert topic.is_test? end - def test_raises_dangerous_attribute_error_when_defining_activerecord_method_in_model + test "raises ActiveRecord::DangerousAttributeError when defining an AR method in a model" do %w(save create_or_update).each do |method| - klass = Class.new ActiveRecord::Base + klass = Class.new(ActiveRecord::Base) klass.class_eval "def #{method}() 'defined #{method}' end" assert_raise ActiveRecord::DangerousAttributeError do klass.instance_method_already_implemented?(method) @@ -531,7 +551,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_converted_values_are_returned_after_assignment + test "converted values are returned after assignment" do developer = Developer.new(name: 1337, salary: "50000") assert_equal "50000", developer.salary_before_type_cast @@ -546,7 +566,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal "1337", developer.name end - def test_write_nil_to_time_attributes + test "write nil to time attribute" do in_time_zone "Pacific Time (US & Canada)" do record = @target.new record.written_on = nil @@ -554,7 +574,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_write_time_to_date_attributes + test "write time to date attribute" do in_time_zone "Pacific Time (US & Canada)" do record = @target.new record.last_read = Time.utc(2010, 1, 1, 10) @@ -562,7 +582,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_time_attributes_are_retrieved_in_current_time_zone + test "time attributes are retrieved in the current time zone" do in_time_zone "Pacific Time (US & Canada)" do utc_time = Time.utc(2008, 1, 1) record = @target.new @@ -574,7 +594,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_setting_time_zone_aware_attribute_to_utc + test "setting a time zone-aware attribute to UTC" do in_time_zone "Pacific Time (US & Canada)" do utc_time = Time.utc(2008, 1, 1) record = @target.new @@ -585,7 +605,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_setting_time_zone_aware_attribute_in_other_time_zone + test "setting time zone-aware attribute in other time zone" do utc_time = Time.utc(2008, 1, 1) cst_time = utc_time.in_time_zone("Central Time (US & Canada)") in_time_zone "Pacific Time (US & Canada)" do @@ -597,18 +617,18 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_setting_time_zone_aware_read_attribute + test "setting time zone-aware read attribute" do utc_time = Time.utc(2008, 1, 1) cst_time = utc_time.in_time_zone("Central Time (US & Canada)") in_time_zone "Pacific Time (US & Canada)" do - record = @target.create(:written_on => cst_time).reload + record = @target.create(written_on: cst_time).reload assert_equal utc_time, record[:written_on] assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record[:written_on].time_zone assert_equal Time.utc(2007, 12, 31, 16), record[:written_on].time end end - def test_setting_time_zone_aware_attribute_with_string + test "setting time zone-aware attribute with a string" do utc_time = Time.utc(2008, 1, 1) (-11..13).each do |timezone_offset| time_string = utc_time.in_time_zone(timezone_offset).to_s @@ -622,27 +642,27 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_time_zone_aware_attribute_saved + test "time zone-aware attribute saved" do in_time_zone 1 do - record = @target.create(:written_on => '2012-02-20 10:00') + record = @target.create(written_on: "2012-02-20 10:00") - record.written_on = '2012-02-20 09:00' + record.written_on = "2012-02-20 09:00" record.save assert_equal Time.zone.local(2012, 02, 20, 9), record.reload.written_on end end - def test_setting_time_zone_aware_attribute_to_blank_string_returns_nil + test "setting a time zone-aware attribute to a blank string returns nil" do in_time_zone "Pacific Time (US & Canada)" do record = @target.new - record.written_on = ' ' + record.written_on = " " assert_nil record.written_on assert_nil record[:written_on] end end - def test_setting_time_zone_aware_attribute_interprets_time_zone_unaware_string_in_time_zone - time_string = 'Tue Jan 01 00:00:00 2008' + test "setting a time zone-aware attribute interprets time zone-unaware string in time zone" do + time_string = "Tue Jan 01 00:00:00 2008" (-11..13).each do |timezone_offset| in_time_zone timezone_offset do record = @target.new @@ -654,7 +674,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_setting_time_zone_aware_datetime_in_current_time_zone + test "setting a time zone-aware datetime in the current time zone" do utc_time = Time.utc(2008, 1, 1) in_time_zone "Pacific Time (US & Canada)" do record = @target.new @@ -665,7 +685,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_yaml_dumping_record_with_time_zone_aware_attribute + test "YAML dumping a record with time zone-aware attribute" do in_time_zone "Pacific Time (US & Canada)" do record = Topic.new(id: 1) record.written_on = "Jan 01 00:00:00 2014" @@ -673,7 +693,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_setting_time_zone_aware_time_in_current_time_zone + test "setting a time zone-aware time in the current time zone" do in_time_zone "Pacific Time (US & Canada)" do record = @target.new time_string = "10:00:00" @@ -683,12 +703,12 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal expected_time, record.bonus_time assert_equal ActiveSupport::TimeZone["Pacific Time (US & Canada)"], record.bonus_time.time_zone - record.bonus_time = '' + record.bonus_time = "" assert_nil record.bonus_time end end - def test_setting_time_zone_aware_time_with_dst + test "setting a time zone-aware time with DST" do in_time_zone "Pacific Time (US & Canada)" do current_time = Time.zone.local(2014, 06, 15, 10) record = @target.new(bonus_time: current_time) @@ -702,7 +722,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_removing_time_zone_aware_types + test "removing time zone-aware types" do with_time_zone_aware_types(:datetime) do in_time_zone "Pacific Time (US & Canada)" do record = @target.new(bonus_time: "10:00:00") @@ -714,14 +734,14 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_time_zone_aware_attributes_dont_recurse_infinitely_on_invalid_values + test "time zone-aware attributes do not recurse infinitely on invalid values" do in_time_zone "Pacific Time (US & Canada)" do record = @target.new(bonus_time: []) assert_equal nil, record.bonus_time end end - def test_setting_time_zone_conversion_for_attributes_should_write_value_on_class_variable + test "setting a time_zone_conversion_for_attributes should write the value on a class variable" do Topic.skip_time_zone_conversion_for_attributes = [:field_a] Minimalistic.skip_time_zone_conversion_for_attributes = [:field_b] @@ -729,44 +749,44 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal [:field_b], Minimalistic.skip_time_zone_conversion_for_attributes end - def test_read_attributes_respect_access_control + test "attribute readers respect access control" do privatize("title") - topic = @target.new(:title => "The pros and cons of programming naked.") + topic = @target.new(title: "The pros and cons of programming naked.") assert !topic.respond_to?(:title) exception = assert_raise(NoMethodError) { topic.title } - assert exception.message.include?("private method") + assert_includes exception.message, "private method" assert_equal "I'm private", topic.send(:title) end - def test_write_attributes_respect_access_control + test "attribute writers respect access control" do privatize("title=(value)") topic = @target.new assert !topic.respond_to?(:title=) - exception = assert_raise(NoMethodError) { topic.title = "Pants"} - assert exception.message.include?("private method") + exception = assert_raise(NoMethodError) { topic.title = "Pants" } + assert_includes exception.message, "private method" topic.send(:title=, "Very large pants") end - def test_question_attributes_respect_access_control + test "attribute predicates respect access control" do privatize("title?") - topic = @target.new(:title => "Isaac Newton's pants") + topic = @target.new(title: "Isaac Newton's pants") assert !topic.respond_to?(:title?) exception = assert_raise(NoMethodError) { topic.title? } - assert exception.message.include?("private method") + assert_includes exception.message, "private method" assert topic.send(:title?) end - def test_bulk_update_respects_access_control + test "bulk updates respect access control" do privatize("title=(value)") - assert_raise(ActiveRecord::UnknownAttributeError) { @target.new(:title => "Rants about pants") } - assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { :title => "Ants in pants" } } + assert_raise(ActiveRecord::UnknownAttributeError) { @target.new(title: "Rants about pants") } + assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { title: "Ants in pants" } } end - def test_bulk_update_raise_unknown_attribute_error + test "bulk update raises ActiveRecord::UnknownAttributeError" do error = assert_raises(ActiveRecord::UnknownAttributeError) { Topic.new(hello: "world") } @@ -775,22 +795,22 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal "unknown attribute 'hello' for Topic.", error.message end - def test_methods_override_in_multi_level_subclass + test "method overrides in multi-level subclasses" do klass = Class.new(Developer) do def name "dev:#{read_attribute(:name)}" end end - 2.times { klass = Class.new klass } - dev = klass.new(name: 'arthurnn') + 2.times { klass = Class.new(klass) } + dev = klass.new(name: "arthurnn") dev.save! - assert_equal 'dev:arthurnn', dev.reload.name + assert_equal "dev:arthurnn", dev.reload.name end - def test_global_methods_are_overwritten + test "global methods are overwritten" do klass = Class.new(ActiveRecord::Base) do - self.table_name = 'computers' + self.table_name = "computers" end assert !klass.instance_method_already_implemented?(:system) @@ -798,11 +818,13 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_nil computer.system end - def test_global_methods_are_overwritten_when_subclassing - klass = Class.new(ActiveRecord::Base) { self.abstract_class = true } + test "global methods are overwritten when subclassing" do + klass = Class.new(ActiveRecord::Base) do + self.abstract_class = true + end subklass = Class.new(klass) do - self.table_name = 'computers' + self.table_name = "computers" end assert !klass.instance_method_already_implemented?(:system) @@ -811,7 +833,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_nil computer.system end - def test_instance_method_should_be_defined_on_the_base_class + test "instance methods should be defined on the base class" do subklass = Class.new(Topic) Topic.define_attribute_methods @@ -827,14 +849,14 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert subklass.method_defined?(:id), "subklass is missing id method" end - def test_read_attribute_with_nil_should_not_asplode - assert_equal nil, Topic.new.read_attribute(nil) + test "read_attribute with nil should not asplode" do + assert_nil Topic.new.read_attribute(nil) end # If B < A, and A defines an accessor for 'foo', we don't want to override # that by defining a 'foo' method in the generated methods module for B. # (That module will be inserted between the two, e.g. [B, <GeneratedAttributes>, A].) - def test_inherited_custom_accessors + test "inherited custom accessors" do klass = new_topic_like_ar_class do self.abstract_class = true def title; "omg"; end @@ -850,9 +872,9 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal "lol", topic.author_name end - def test_inherited_custom_accessors_with_reserved_names + test "inherited custom accessors with reserved names" do klass = Class.new(ActiveRecord::Base) do - self.table_name = 'computers' + self.table_name = "computers" self.abstract_class = true def system; "omg"; end def system=(val); self.developer = val; end @@ -868,18 +890,18 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal 99, computer.developer end - def test_on_the_fly_super_invokable_generated_attribute_methods_via_method_missing + test "on_the_fly_super_invokable_generated_attribute_methods_via_method_missing" do klass = new_topic_like_ar_class do def title - super + '!' + super + "!" end end real_topic = topics(:first) - assert_equal real_topic.title + '!', klass.find(real_topic.id).title + assert_equal real_topic.title + "!", klass.find(real_topic.id).title end - def test_on_the_fly_super_invokable_generated_predicate_attribute_methods_via_method_missing + test "on-the-fly super-invokable generated attribute predicates via method_missing" do klass = new_topic_like_ar_class do def title? !super @@ -890,7 +912,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert_equal !real_topic.title?, klass.find(real_topic.id).title? end - def test_calling_super_when_parent_does_not_define_method_raises_error + test "calling super when the parent does not define method raises NoMethodError" do klass = new_topic_like_ar_class do def some_method_that_is_not_on_super super @@ -902,38 +924,38 @@ class AttributeMethodsTest < ActiveRecord::TestCase end end - def test_attribute_method? + test "attribute_method?" do assert @target.attribute_method?(:title) assert @target.attribute_method?(:title=) assert_not @target.attribute_method?(:wibble) end - def test_attribute_method_returns_false_if_table_does_not_exist - @target.table_name = 'wibble' + test "attribute_method? returns false if the table does not exist" do + @target.table_name = "wibble" assert_not @target.attribute_method?(:title) end - def test_attribute_names_on_new_record + test "attribute_names on a new record" do model = @target.new assert_equal @target.column_names, model.attribute_names end - def test_attribute_names_on_queried_record + test "attribute_names on a queried record" do model = @target.last! assert_equal @target.column_names, model.attribute_names end - def test_attribute_names_with_custom_select - model = @target.select('id').last! + test "attribute_names with a custom select" do + model = @target.select("id").last! - assert_equal ['id'], model.attribute_names - # Sanity check, make sure other columns exist - assert_not_equal ['id'], @target.column_names + assert_equal ["id"], model.attribute_names + # Sanity check, make sure other columns exist. + assert_not_equal ["id"], @target.column_names end - def test_came_from_user + test "came_from_user?" do model = @target.first assert_not model.id_came_from_user? @@ -941,7 +963,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase assert model.id_came_from_user? end - def test_accessed_fields + test "accessed_fields" do model = @target.first assert_equal [], model.accessed_fields @@ -953,38 +975,38 @@ class AttributeMethodsTest < ActiveRecord::TestCase private - def new_topic_like_ar_class(&block) - klass = Class.new(ActiveRecord::Base) do - self.table_name = 'topics' - class_eval(&block) - end + def new_topic_like_ar_class(&block) + klass = Class.new(ActiveRecord::Base) do + self.table_name = "topics" + class_eval(&block) + end - assert_empty klass.generated_attribute_methods.instance_methods(false) - klass - end + assert_empty klass.generated_attribute_methods.instance_methods(false) + klass + end - def with_time_zone_aware_types(*types) - old_types = ActiveRecord::Base.time_zone_aware_types - ActiveRecord::Base.time_zone_aware_types = types - yield - ensure - ActiveRecord::Base.time_zone_aware_types = old_types - end + def with_time_zone_aware_types(*types) + old_types = ActiveRecord::Base.time_zone_aware_types + ActiveRecord::Base.time_zone_aware_types = types + yield + ensure + ActiveRecord::Base.time_zone_aware_types = old_types + end - def cached_columns - Topic.columns.map(&:name) - end + def cached_columns + Topic.columns.map(&:name) + end - def time_related_columns_on_topic - Topic.columns.select { |c| [:time, :date, :datetime, :timestamp].include?(c.type) } - end + def time_related_columns_on_topic + Topic.columns.select { |c| [:time, :date, :datetime, :timestamp].include?(c.type) } + end - def privatize(method_signature) - @target.class_eval(<<-private_method, __FILE__, __LINE__ + 1) - private - def #{method_signature} - "I'm private" - end - private_method - end + def privatize(method_signature) + @target.class_eval(<<-private_method, __FILE__, __LINE__ + 1) + private + def #{method_signature} + "I'm private" + end + private_method + end end diff --git a/activerecord/test/cases/attribute_set_test.rb b/activerecord/test/cases/attribute_set_test.rb index 7a24b85a36..059b5b2401 100644 --- a/activerecord/test/cases/attribute_set_test.rb +++ b/activerecord/test/cases/attribute_set_test.rb @@ -1,10 +1,10 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class AttributeSetTest < ActiveRecord::TestCase test "building a new set from raw attributes" do builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Float.new) - attributes = builder.build_from_database(foo: '1.1', bar: '2.2') + attributes = builder.build_from_database(foo: "1.1", bar: "2.2") assert_equal 1, attributes[:foo].value assert_equal 2.2, attributes[:bar].value @@ -14,7 +14,7 @@ module ActiveRecord test "building with custom types" do builder = AttributeSet::Builder.new(foo: Type::Float.new) - attributes = builder.build_from_database({ foo: '3.3', bar: '4.4' }, { bar: Type::Integer.new }) + attributes = builder.build_from_database({ foo: "3.3", bar: "4.4" }, bar: Type::Integer.new) assert_equal 3.3, attributes[:foo].value assert_equal 4, attributes[:bar].value @@ -22,16 +22,16 @@ module ActiveRecord test "[] returns a null object" do builder = AttributeSet::Builder.new(foo: Type::Float.new) - attributes = builder.build_from_database(foo: '3.3') + attributes = builder.build_from_database(foo: "3.3") - assert_equal '3.3', attributes[:foo].value_before_type_cast + assert_equal "3.3", attributes[:foo].value_before_type_cast assert_equal nil, attributes[:bar].value_before_type_cast assert_equal :bar, attributes[:bar].name end test "duping creates a new hash, but does not dup the attributes" do builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::String.new) - attributes = builder.build_from_database(foo: 1, bar: 'foo') + attributes = builder.build_from_database(foo: 1, bar: "foo") # Ensure the type cast value is cached attributes[:foo].value @@ -39,17 +39,17 @@ module ActiveRecord duped = attributes.dup duped.write_from_database(:foo, 2) - duped[:bar].value << 'bar' + duped[:bar].value << "bar" assert_equal 1, attributes[:foo].value assert_equal 2, duped[:foo].value - assert_equal 'foobar', attributes[:bar].value - assert_equal 'foobar', duped[:bar].value + assert_equal "foobar", attributes[:bar].value + assert_equal "foobar", duped[:bar].value end test "deep_duping creates a new hash and dups each attribute" do builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::String.new) - attributes = builder.build_from_database(foo: 1, bar: 'foo') + attributes = builder.build_from_database(foo: 1, bar: "foo") # Ensure the type cast value is cached attributes[:foo].value @@ -57,12 +57,12 @@ module ActiveRecord duped = attributes.deep_dup duped.write_from_database(:foo, 2) - duped[:bar].value << 'bar' + duped[:bar].value << "bar" assert_equal 1, attributes[:foo].value assert_equal 2, duped[:foo].value - assert_equal 'foo', attributes[:bar].value - assert_equal 'foobar', duped[:bar].value + assert_equal "foo", attributes[:bar].value + assert_equal "foobar", duped[:bar].value end test "freezing cloned set does not freeze original" do @@ -77,7 +77,7 @@ module ActiveRecord test "to_hash returns a hash of the type cast values" do builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Float.new) - attributes = builder.build_from_database(foo: '1.1', bar: '2.2') + attributes = builder.build_from_database(foo: "1.1", bar: "2.2") assert_equal({ foo: 1, bar: 2.2 }, attributes.to_hash) assert_equal({ foo: 1, bar: 2.2 }, attributes.to_h) @@ -85,7 +85,7 @@ module ActiveRecord test "to_hash maintains order" do builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Float.new) - attributes = builder.build_from_database(foo: '2.2', bar: '3.3') + attributes = builder.build_from_database(foo: "2.2", bar: "3.3") attributes[:bar] hash = attributes.to_h @@ -95,9 +95,9 @@ module ActiveRecord test "values_before_type_cast" do builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Integer.new) - attributes = builder.build_from_database(foo: '1.1', bar: '2.2') + attributes = builder.build_from_database(foo: "1.1", bar: "2.2") - assert_equal({ foo: '1.1', bar: '2.2' }, attributes.values_before_type_cast) + assert_equal({ foo: "1.1", bar: "2.2" }, attributes.values_before_type_cast) end test "known columns are built with uninitialized attributes" do @@ -129,7 +129,7 @@ module ActiveRecord test "fetch_value returns the value for the given initialized attribute" do builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Float.new) - attributes = builder.build_from_database(foo: '1.1', bar: '2.2') + attributes = builder.build_from_database(foo: "1.1", bar: "2.2") assert_equal 1, attributes.fetch_value(:foo) assert_equal 2.2, attributes.fetch_value(:bar) @@ -150,8 +150,8 @@ module ActiveRecord test "fetch_value uses the given block for uninitialized attributes" do attributes = attributes_with_uninitialized_key - value = attributes.fetch_value(:bar) { |n| n.to_s + '!' } - assert_equal 'bar!', value + value = attributes.fetch_value(:bar) { |n| n.to_s + "!" } + assert_equal "bar!", value end test "fetch_value returns nil for uninitialized attributes if no block is given" do @@ -207,7 +207,7 @@ module ActiveRecord def attributes_with_uninitialized_key builder = AttributeSet::Builder.new(foo: Type::Integer.new, bar: Type::Float.new) - builder.build_from_database(foo: '1.1') + builder.build_from_database(foo: "1.1") end test "freezing doesn't prevent the set from materializing" do diff --git a/activerecord/test/cases/attribute_test.rb b/activerecord/test/cases/attribute_test.rb index a24a4fc6a4..7cf6b498c9 100644 --- a/activerecord/test/cases/attribute_test.rb +++ b/activerecord/test/cases/attribute_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class AttributeTest < ActiveRecord::TestCase @@ -11,91 +11,91 @@ module ActiveRecord end test "from_database + read type casts from database" do - @type.expect(:deserialize, 'type cast from database', ['a value']) - attribute = Attribute.from_database(nil, 'a value', @type) + @type.expect(:deserialize, "type cast from database", ["a value"]) + attribute = Attribute.from_database(nil, "a value", @type) type_cast_value = attribute.value - assert_equal 'type cast from database', type_cast_value + assert_equal "type cast from database", type_cast_value end test "from_user + read type casts from user" do - @type.expect(:cast, 'type cast from user', ['a value']) - attribute = Attribute.from_user(nil, 'a value', @type) + @type.expect(:cast, "type cast from user", ["a value"]) + attribute = Attribute.from_user(nil, "a value", @type) type_cast_value = attribute.value - assert_equal 'type cast from user', type_cast_value + assert_equal "type cast from user", type_cast_value end test "reading memoizes the value" do - @type.expect(:deserialize, 'from the database', ['whatever']) - attribute = Attribute.from_database(nil, 'whatever', @type) + @type.expect(:deserialize, "from the database", ["whatever"]) + attribute = Attribute.from_database(nil, "whatever", @type) type_cast_value = attribute.value second_read = attribute.value - assert_equal 'from the database', type_cast_value + assert_equal "from the database", type_cast_value assert_same type_cast_value, second_read end test "reading memoizes falsy values" do - @type.expect(:deserialize, false, ['whatever']) - attribute = Attribute.from_database(nil, 'whatever', @type) + @type.expect(:deserialize, false, ["whatever"]) + attribute = Attribute.from_database(nil, "whatever", @type) attribute.value attribute.value end test "read_before_typecast returns the given value" do - attribute = Attribute.from_database(nil, 'raw value', @type) + attribute = Attribute.from_database(nil, "raw value", @type) raw_value = attribute.value_before_type_cast - assert_equal 'raw value', raw_value + assert_equal "raw value", raw_value end test "from_database + read_for_database type casts to and from database" do - @type.expect(:deserialize, 'read from database', ['whatever']) - @type.expect(:serialize, 'ready for database', ['read from database']) - attribute = Attribute.from_database(nil, 'whatever', @type) + @type.expect(:deserialize, "read from database", ["whatever"]) + @type.expect(:serialize, "ready for database", ["read from database"]) + attribute = Attribute.from_database(nil, "whatever", @type) serialize = attribute.value_for_database - assert_equal 'ready for database', serialize + assert_equal "ready for database", serialize end test "from_user + read_for_database type casts from the user to the database" do - @type.expect(:cast, 'read from user', ['whatever']) - @type.expect(:serialize, 'ready for database', ['read from user']) - attribute = Attribute.from_user(nil, 'whatever', @type) + @type.expect(:cast, "read from user", ["whatever"]) + @type.expect(:serialize, "ready for database", ["read from user"]) + attribute = Attribute.from_user(nil, "whatever", @type) serialize = attribute.value_for_database - assert_equal 'ready for database', serialize + assert_equal "ready for database", serialize end test "duping dups the value" do - @type.expect(:deserialize, 'type cast', ['a value']) - attribute = Attribute.from_database(nil, 'a value', @type) + @type.expect(:deserialize, "type cast", ["a value"]) + attribute = Attribute.from_database(nil, "a value", @type) value_from_orig = attribute.value value_from_clone = attribute.dup.value - value_from_orig << ' foo' + value_from_orig << " foo" - assert_equal 'type cast foo', value_from_orig - assert_equal 'type cast', value_from_clone + assert_equal "type cast foo", value_from_orig + assert_equal "type cast", value_from_clone end test "duping does not dup the value if it is not dupable" do - @type.expect(:deserialize, false, ['a value']) - attribute = Attribute.from_database(nil, 'a value', @type) + @type.expect(:deserialize, false, ["a value"]) + attribute = Attribute.from_database(nil, "a value", @type) assert_same attribute.value, attribute.dup.value end test "duping does not eagerly type cast if we have not yet type cast" do - attribute = Attribute.from_database(nil, 'a value', @type) + attribute = Attribute.from_database(nil, "a value", @type) attribute.dup end @@ -242,5 +242,12 @@ module ActiveRecord attribute.with_value_from_user(1) end end + + test "with_type preserves mutations" do + attribute = Attribute.from_database(:foo, "", Type::Value.new) + attribute.value << "1" + + assert_equal 1, attribute.with_type(Type::Integer.new).value + end end end diff --git a/activerecord/test/cases/attributes_test.rb b/activerecord/test/cases/attributes_test.rb index 2bebbfa205..f4620ae2da 100644 --- a/activerecord/test/cases/attributes_test.rb +++ b/activerecord/test/cases/attributes_test.rb @@ -1,10 +1,10 @@ -require 'cases/helper' +require "cases/helper" class OverloadedType < ActiveRecord::Base attribute :overloaded_float, :integer attribute :overloaded_string_with_limit, :string, limit: 50 attribute :non_existent_decimal, :decimal - attribute :string_with_default, :string, default: 'the overloaded default' + attribute :string_with_default, :string, default: "the overloaded default" end class ChildOfOverloadedType < OverloadedType @@ -15,7 +15,7 @@ class GrandchildOfOverloadedType < ChildOfOverloadedType end class UnoverloadedType < ActiveRecord::Base - self.table_name = 'overloaded_types' + self.table_name = "overloaded_types" end module ActiveRecord @@ -38,20 +38,20 @@ module ActiveRecord data.reload assert_equal 2, data.overloaded_float - assert_kind_of Fixnum, OverloadedType.last.overloaded_float + assert_kind_of Integer, OverloadedType.last.overloaded_float assert_equal 2.0, UnoverloadedType.last.overloaded_float assert_kind_of Float, UnoverloadedType.last.overloaded_float end test "properties assigned in constructor" do - data = OverloadedType.new(overloaded_float: '3.3') + data = OverloadedType.new(overloaded_float: "3.3") assert_equal 3, data.overloaded_float end test "overloaded properties with limit" do - assert_equal 50, OverloadedType.type_for_attribute('overloaded_string_with_limit').limit - assert_equal 255, UnoverloadedType.type_for_attribute('overloaded_string_with_limit').limit + assert_equal 50, OverloadedType.type_for_attribute("overloaded_string_with_limit").limit + assert_equal 255, UnoverloadedType.type_for_attribute("overloaded_string_with_limit").limit end test "nonexistent attribute" do @@ -63,26 +63,35 @@ module ActiveRecord end end + test "model with nonexistent attribute with default value can be saved" do + klass = Class.new(OverloadedType) do + attribute :non_existent_string_with_default, :string, default: "nonexistent" + end + + model = klass.new + assert model.save + end + test "changing defaults" do data = OverloadedType.new unoverloaded_data = UnoverloadedType.new - assert_equal 'the overloaded default', data.string_with_default - assert_equal 'the original default', unoverloaded_data.string_with_default + assert_equal "the overloaded default", data.string_with_default + assert_equal "the original default", unoverloaded_data.string_with_default end test "defaults are not touched on the columns" do - assert_equal 'the original default', OverloadedType.columns_hash['string_with_default'].default + assert_equal "the original default", OverloadedType.columns_hash["string_with_default"].default end test "children inherit custom properties" do - data = ChildOfOverloadedType.new(overloaded_float: '4.4') + data = ChildOfOverloadedType.new(overloaded_float: "4.4") assert_equal 4, data.overloaded_float end test "children can override parents" do - data = GrandchildOfOverloadedType.new(overloaded_float: '4.4') + data = GrandchildOfOverloadedType.new(overloaded_float: "4.4") assert_equal 4.4, data.overloaded_float end @@ -97,13 +106,13 @@ module ActiveRecord assert_equal 6, klass.attribute_types.length assert_equal 6, klass.column_defaults.length - assert_not klass.attribute_types.include?('wibble') + assert_not klass.attribute_types.include?("wibble") klass.attribute :wibble, Type::Value.new assert_equal 7, klass.attribute_types.length assert_equal 7, klass.column_defaults.length - assert klass.attribute_types.include?('wibble') + assert_includes klass.attribute_types, "wibble" end test "the given default value is cast from user" do @@ -196,5 +205,55 @@ module ActiveRecord assert_equal(:bar, child.new(foo: :bar).foo) end + + test "attributes not backed by database columns are not dirty when unchanged" do + refute OverloadedType.new.non_existent_decimal_changed? + end + + test "attributes not backed by database columns are always initialized" do + OverloadedType.create! + model = OverloadedType.first + + assert_nil model.non_existent_decimal + model.non_existent_decimal = "123" + assert_equal 123, model.non_existent_decimal + end + + test "attributes not backed by database columns return the default on models loaded from database" do + child = Class.new(OverloadedType) do + attribute :non_existent_decimal, :decimal, default: 123 + end + child.create! + model = child.first + + assert_equal 123, model.non_existent_decimal + end + + test "attributes not backed by database columns properly interact with mutation and dirty" do + child = Class.new(ActiveRecord::Base) do + self.table_name = "topics" + attribute :foo, :string, default: "lol" + end + child.create! + model = child.first + + assert_equal "lol", model.foo + + model.foo << "asdf" + assert_equal "lolasdf", model.foo + assert model.foo_changed? + + model.reload + assert_equal "lol", model.foo + + model.foo = "lol" + refute model.changed? + end + + test "attributes not backed by database columns appear in inspect" do + inspection = OverloadedType.new.inspect + + assert_includes inspection, "non_existent_decimal" + end end end diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 9e3266b7d6..c24d7b8835 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -1,55 +1,55 @@ -require 'cases/helper' -require 'models/bird' -require 'models/comment' -require 'models/company' -require 'models/customer' -require 'models/developer' -require 'models/computer' -require 'models/invoice' -require 'models/line_item' -require 'models/order' -require 'models/parrot' -require 'models/person' -require 'models/pirate' -require 'models/post' -require 'models/reader' -require 'models/ship' -require 'models/ship_part' -require 'models/tag' -require 'models/tagging' -require 'models/treasure' -require 'models/eye' -require 'models/electron' -require 'models/molecule' -require 'models/member' -require 'models/member_detail' -require 'models/organization' -require 'models/guitar' -require 'models/tuning_peg' +require "cases/helper" +require "models/bird" +require "models/post" +require "models/comment" +require "models/company" +require "models/customer" +require "models/developer" +require "models/computer" +require "models/invoice" +require "models/line_item" +require "models/order" +require "models/parrot" +require "models/person" +require "models/pirate" +require "models/reader" +require "models/ship" +require "models/ship_part" +require "models/tag" +require "models/tagging" +require "models/treasure" +require "models/eye" +require "models/electron" +require "models/molecule" +require "models/member" +require "models/member_detail" +require "models/organization" +require "models/guitar" +require "models/tuning_peg" class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase def test_autosave_validation person = Class.new(ActiveRecord::Base) { - self.table_name = 'people' - validate :should_be_cool, :on => :create - def self.name; 'Person'; end + self.table_name = "people" + validate :should_be_cool, on: :create + def self.name; "Person"; end private def should_be_cool - unless self.first_name == 'cool' + unless self.first_name == "cool" errors.add :first_name, "not cool" end end } reference = Class.new(ActiveRecord::Base) { self.table_name = "references" - def self.name; 'Reference'; end + def self.name; "Reference"; end belongs_to :person, autosave: true, anonymous_class: person } - u = person.create!(first_name: 'cool') - u.update_attributes!(first_name: 'nah') # still valid because validation only applies on 'create' + u = person.create!(first_name: "cool") + u.update_attributes!(first_name: "nah") # still valid because validation only applies on 'create' assert reference.create!(person: u).persisted? end @@ -79,25 +79,25 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase private - def assert_no_difference_when_adding_callbacks_twice_for(model, association_name) - reflection = model.reflect_on_association(association_name) - assert_no_difference "callbacks_for_model(#{model.name}).length" do - model.send(:add_autosave_association_callbacks, reflection) + def assert_no_difference_when_adding_callbacks_twice_for(model, association_name) + reflection = model.reflect_on_association(association_name) + assert_no_difference "callbacks_for_model(#{model.name}).length" do + model.send(:add_autosave_association_callbacks, reflection) + end end - end - def callbacks_for_model(model) - model.instance_variables.grep(/_callbacks$/).flat_map do |ivar| - model.instance_variable_get(ivar) + def callbacks_for_model(model) + model.instance_variables.grep(/_callbacks$/).flat_map do |ivar| + model.instance_variable_get(ivar) + end end - end end class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase fixtures :companies, :accounts def test_should_save_parent_but_not_invalid_child - firm = Firm.new(:name => 'GlobalMegaCorp') + firm = Firm.new(name: "GlobalMegaCorp") assert firm.valid? firm.build_account_using_primary_key @@ -178,8 +178,8 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas end def test_not_resaved_when_unchanged - firm = Firm.all.merge!(:includes => :account).first - firm.name += '-changed' + firm = Firm.all.merge!(includes: :account).first + firm.name += "-changed" assert_queries(1) { firm.save! } firm = Firm.first @@ -196,21 +196,21 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas end def test_callbacks_firing_order_on_create - eye = Eye.create(:iris_attributes => {:color => 'honey'}) + eye = Eye.create(iris_attributes: { color: "honey" }) assert_equal [true, false], eye.after_create_callbacks_stack end def test_callbacks_firing_order_on_update - eye = Eye.create(iris_attributes: {color: 'honey'}) - eye.update(iris_attributes: {color: 'green'}) + eye = Eye.create(iris_attributes: { color: "honey" }) + eye.update(iris_attributes: { color: "green" }) assert_equal [true, false], eye.after_update_callbacks_stack end def test_callbacks_firing_order_on_save - eye = Eye.create(iris_attributes: {color: 'honey'}) + eye = Eye.create(iris_attributes: { color: "honey" }) assert_equal [false, false], eye.after_save_callbacks_stack - eye.update(iris_attributes: {color: 'blue'}) + eye.update(iris_attributes: { color: "blue" }) assert_equal [false, false, false, false], eye.after_save_callbacks_stack end end @@ -219,7 +219,7 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test fixtures :companies, :posts, :tags, :taggings def test_should_save_parent_but_not_invalid_child - client = Client.new(:name => 'Joe (the Plumber)') + client = Client.new(name: "Joe (the Plumber)") assert client.valid? client.build_firm @@ -231,7 +231,7 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test def test_save_fails_for_invalid_belongs_to # Oracle saves empty string as NULL therefore :message changed to one space - assert log = AuditLog.create(:developer_id => 0, :message => " ") + assert log = AuditLog.create(developer_id: 0, message: " ") log.developer = Developer.new assert !log.developer.valid? @@ -242,7 +242,7 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test def test_save_succeeds_for_invalid_belongs_to_with_validate_false # Oracle saves empty string as NULL therefore :message changed to one space - assert log = AuditLog.create(:developer_id => 0, :message=> " ") + assert log = AuditLog.create(developer_id: 0, message: " ") log.unvalidated_developer = Developer.new assert !log.unvalidated_developer.valid? @@ -362,22 +362,22 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test def test_store_association_with_a_polymorphic_relationship num_tagging = Tagging.count - tags(:misc).create_tagging(:taggable => posts(:thinking)) + tags(:misc).create_tagging(taggable: posts(:thinking)) assert_equal num_tagging + 1, Tagging.count end def test_build_and_then_save_parent_should_not_reload_target client = Client.first - apple = client.build_firm(:name => "Apple") + apple = client.build_firm(name: "Apple") client.save! assert_no_queries { assert_equal apple, client.firm } end def test_validation_does_not_validate_stale_association_target - valid_developer = Developer.create!(:name => "Dude", :salary => 50_000) + valid_developer = Developer.create!(name: "Dude", salary: 50_000) invalid_developer = Developer.new() - auditlog = AuditLog.new(:message => "foo") + auditlog = AuditLog.new(message: "foo") auditlog.developer = invalid_developer auditlog.developer_id = valid_developer.id @@ -388,7 +388,7 @@ end class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase def test_invalid_adding_with_nested_attributes molecule = Molecule.new - valid_electron = Electron.new(name: 'electron') + valid_electron = Electron.new(name: "electron") invalid_electron = Electron.new molecule.electrons = [valid_electron, invalid_electron] @@ -396,7 +396,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib assert_not invalid_electron.valid? assert valid_electron.valid? - assert_not molecule.persisted?, 'Molecule should not be persisted when its electrons are invalid' + assert_not molecule.persisted?, "Molecule should not be persisted when its electrons are invalid" end def test_errors_should_be_indexed_when_passed_as_array @@ -419,7 +419,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib ActiveRecord::Base.index_nested_attribute_errors = true molecule = Molecule.new - valid_electron = Electron.new(name: 'electron') + valid_electron = Electron.new(name: "electron") invalid_electron = Electron.new molecule.electrons = [valid_electron, invalid_electron] @@ -435,7 +435,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib def test_errors_details_should_be_set molecule = Molecule.new - valid_electron = Electron.new(name: 'electron') + valid_electron = Electron.new(name: "electron") invalid_electron = Electron.new molecule.electrons = [valid_electron, invalid_electron] @@ -443,7 +443,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib assert_not invalid_electron.valid? assert valid_electron.valid? assert_not molecule.valid? - assert_equal [{error: :blank}], molecule.errors.details["electrons.name"] + assert_equal [{ error: :blank }], molecule.errors.details[:"electrons.name"] end def test_errors_details_should_be_indexed_when_passed_as_array @@ -457,8 +457,8 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib assert_not tuning_peg_invalid.valid? assert tuning_peg_valid.valid? assert_not guitar.valid? - assert_equal [{error: :not_a_number, value: nil}] , guitar.errors.details["tuning_pegs[1].pitch"] - assert_equal [], guitar.errors.details["tuning_pegs.pitch"] + assert_equal [{ error: :not_a_number, value: nil }], guitar.errors.details[:"tuning_pegs[1].pitch"] + assert_equal [], guitar.errors.details[:"tuning_pegs.pitch"] end def test_errors_details_should_be_indexed_when_global_flag_is_set @@ -466,7 +466,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib ActiveRecord::Base.index_nested_attribute_errors = true molecule = Molecule.new - valid_electron = Electron.new(name: 'electron') + valid_electron = Electron.new(name: "electron") invalid_electron = Electron.new molecule.electrons = [valid_electron, invalid_electron] @@ -474,15 +474,15 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttrib assert_not invalid_electron.valid? assert valid_electron.valid? assert_not molecule.valid? - assert_equal [{error: :blank}], molecule.errors.details["electrons[1].name"] - assert_equal [], molecule.errors.details["electrons.name"] + assert_equal [{ error: :blank }], molecule.errors.details[:"electrons[1].name"] + assert_equal [], molecule.errors.details[:"electrons.name"] ensure ActiveRecord::Base.index_nested_attribute_errors = old_attribute_config end def test_valid_adding_with_nested_attributes molecule = Molecule.new - valid_electron = Electron.new(name: 'electron') + valid_electron = Electron.new(name: "electron") molecule.electrons = [valid_electron] molecule.save @@ -585,16 +585,16 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa firm.save firm.reload assert_equal 2, firm.clients.length - assert firm.clients.include?(companies(:second_client)) + assert_includes firm.clients, companies(:second_client) end def test_assign_ids_for_through_a_belongs_to - post = Post.new(:title => "Assigning IDs works!", :body => "You heard it here first, folks!") + post = Post.new(title: "Assigning IDs works!", body: "You heard it here first, folks!") post.person_ids = [people(:david).id, people(:michael).id] post.save post.reload assert_equal 2, post.people.length - assert post.people.include?(people(:david)) + assert_includes post.people, people(:david) end def test_build_before_save @@ -602,7 +602,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build("name" => "Another Client") } assert !company.clients_of_firm.loaded? - company.name += '-changed' + company.name += "-changed" assert_queries(2) { assert company.save } assert new_client.persisted? assert_equal 3, company.clients_of_firm.reload.size @@ -610,19 +610,19 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa def test_build_many_before_save company = companies(:first_firm) - assert_no_queries(ignore_none: false) { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) } + assert_no_queries(ignore_none: false) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) } - company.name += '-changed' + company.name += "-changed" assert_queries(3) { assert company.save } assert_equal 4, company.clients_of_firm.reload.size end def test_build_via_block_before_save company = companies(:first_firm) - new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build {|client| client.name = "Another Client" } } + new_client = assert_no_queries(ignore_none: false) { company.clients_of_firm.build { |client| client.name = "Another Client" } } assert !company.clients_of_firm.loaded? - company.name += '-changed' + company.name += "-changed" assert_queries(2) { assert company.save } assert new_client.persisted? assert_equal 3, company.clients_of_firm.reload.size @@ -631,12 +631,12 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa def test_build_many_via_block_before_save company = companies(:first_firm) assert_no_queries(ignore_none: false) do - company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client| + company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) do |client| client.name = "changed" end end - company.name += '-changed' + company.name += "-changed" assert_queries(3) { assert company.save } assert_equal 4, company.clients_of_firm.reload.size end @@ -647,7 +647,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa assert firm.save firm.reload assert_equal 2, firm.clients.length - assert firm.clients.include?(Client.find_by_name("New Client")) + assert_includes firm.clients, Client.find_by_name("New Client") end end @@ -715,8 +715,8 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase end def test_autosave_new_record_with_after_create_callback - post = PostWithAfterCreateCallback.new(title: 'Captain Murphy', body: 'is back') - post.comments.build(body: 'foo') + post = PostWithAfterCreateCallback.new(title: "Captain Murphy", body: "is back") + post.comments.build(body: "foo") post.save! assert_not_nil post.author_id @@ -727,8 +727,8 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase self.use_transactional_tests = false setup do - @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @ship = @pirate.create_ship(:name => 'Nights Dirty Lightning') + @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") + @ship = @pirate.create_ship(name: "Nights Dirty Lightning") end teardown do @@ -764,12 +764,12 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_skip_validation_on_a_child_association_if_marked_for_destruction - @pirate.ship.name = '' + @pirate.ship.name = "" assert !@pirate.valid? @pirate.ship.mark_for_destruction @pirate.ship.expects(:valid?).never - assert_difference('Ship.count', -1) { @pirate.save! } + assert_difference("Ship.count", -1) { @pirate.save! } end def test_a_child_marked_for_destruction_should_not_be_destroyed_twice @@ -787,7 +787,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase def save(*args) super destroy - raise 'Oh noes!' + raise "Oh noes!" end end @@ -824,12 +824,12 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_skip_validation_on_a_parent_association_if_marked_for_destruction - @ship.pirate.catchphrase = '' + @ship.pirate.catchphrase = "" assert !@ship.valid? @ship.pirate.mark_for_destruction @ship.pirate.expects(:valid?).never - assert_difference('Pirate.count', -1) { @ship.save! } + assert_difference("Pirate.count", -1) { @ship.save! } end def test_a_parent_marked_for_destruction_should_not_be_destroyed_twice @@ -847,7 +847,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase def save(*args) super destroy - raise 'Oh noes!' + raise "Oh noes!" end end @@ -858,16 +858,16 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_save_changed_child_objects_if_parent_is_saved - @pirate = @ship.create_pirate(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @parrot = @pirate.parrots.create!(:name => 'Posideons Killer') + @pirate = @ship.create_pirate(catchphrase: "Don' botharrr talkin' like one, savvy?") + @parrot = @pirate.parrots.create!(name: "Posideons Killer") @parrot.name = "NewName" @ship.save - assert_equal 'NewName', @parrot.reload.name + assert_equal "NewName", @parrot.reload.name end def test_should_destroy_has_many_as_part_of_the_save_transaction_if_they_were_marked_for_destruction - 2.times { |i| @pirate.birds.create!(:name => "birds_#{i}") } + 2.times { |i| @pirate.birds.create!(name: "birds_#{i}") } assert !@pirate.birds.any?(&:marked_for_destruction?) @@ -891,9 +891,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_skip_validation_on_has_many_if_marked_for_destruction - 2.times { |i| @pirate.birds.create!(:name => "birds_#{i}") } + 2.times { |i| @pirate.birds.create!(name: "birds_#{i}") } - @pirate.birds.each { |bird| bird.name = '' } + @pirate.birds.each { |bird| bird.name = "" } assert !@pirate.valid? @pirate.birds.each do |bird| @@ -904,9 +904,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_skip_validation_on_has_many_if_destroyed - @pirate.birds.create!(:name => "birds_1") + @pirate.birds.create!(name: "birds_1") - @pirate.birds.each { |bird| bird.name = '' } + @pirate.birds.each { |bird| bird.name = "" } assert !@pirate.valid? @pirate.birds.each(&:destroy) @@ -914,7 +914,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_a_child_marked_for_destruction_should_not_be_destroyed_twice_while_saving_has_many - @pirate.birds.create!(:name => "birds_1") + @pirate.birds.create!(name: "birds_1") @pirate.birds.each(&:mark_for_destruction) assert @pirate.save @@ -924,14 +924,14 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_rollback_destructions_if_an_exception_occurred_while_saving_has_many - 2.times { |i| @pirate.birds.create!(:name => "birds_#{i}") } + 2.times { |i| @pirate.birds.create!(name: "birds_#{i}") } before = @pirate.birds.map { |c| c.mark_for_destruction ; c } # Stub the destroy method of the second child to raise an exception class << before.last def destroy(*args) super - raise 'Oh noes!' + raise "Oh noes!" end end @@ -940,9 +940,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_when_new_record_a_child_marked_for_destruction_should_not_affect_other_records_from_saving - @pirate = @ship.build_pirate(:catchphrase => "Arr' now I shall keep me eye on you matey!") # new record + @pirate = @ship.build_pirate(catchphrase: "Arr' now I shall keep me eye on you matey!") # new record - 3.times { |i| @pirate.birds.build(:name => "birds_#{i}") } + 3.times { |i| @pirate.birds.build(name: "birds_#{i}") } @pirate.birds[1].mark_for_destruction @pirate.save! @@ -968,8 +968,8 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase define_method("test_should_run_add_callback_#{callback_type}s_for_has_many") do association_name_with_callbacks = "birds_with_#{callback_type}_callbacks" - pirate = Pirate.new(:catchphrase => "Arr") - pirate.send(association_name_with_callbacks).build(:name => "Crowe the One-Eyed") + pirate = Pirate.new(catchphrase: "Arr") + pirate.send(association_name_with_callbacks).build(name: "Crowe the One-Eyed") expected = [ "before_adding_#{callback_type}_bird_<new>", @@ -982,7 +982,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase define_method("test_should_run_remove_callback_#{callback_type}s_for_has_many") do association_name_with_callbacks = "birds_with_#{callback_type}_callbacks" - @pirate.send(association_name_with_callbacks).create!(:name => "Crowe the One-Eyed") + @pirate.send(association_name_with_callbacks).create!(name: "Crowe the One-Eyed") @pirate.send(association_name_with_callbacks).each(&:mark_for_destruction) child_id = @pirate.send(association_name_with_callbacks).first.id @@ -999,7 +999,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_destroy_habtm_as_part_of_the_save_transaction_if_they_were_marked_for_destruction - 2.times { |i| @pirate.parrots.create!(:name => "parrots_#{i}") } + 2.times { |i| @pirate.parrots.create!(name: "parrots_#{i}") } assert !@pirate.parrots.any?(&:marked_for_destruction?) @pirate.parrots.each(&:mark_for_destruction) @@ -1015,9 +1015,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_skip_validation_on_habtm_if_marked_for_destruction - 2.times { |i| @pirate.parrots.create!(:name => "parrots_#{i}") } + 2.times { |i| @pirate.parrots.create!(name: "parrots_#{i}") } - @pirate.parrots.each { |parrot| parrot.name = '' } + @pirate.parrots.each { |parrot| parrot.name = "" } assert !@pirate.valid? @pirate.parrots.each do |parrot| @@ -1030,9 +1030,9 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_skip_validation_on_habtm_if_destroyed - @pirate.parrots.create!(:name => "parrots_1") + @pirate.parrots.create!(name: "parrots_1") - @pirate.parrots.each { |parrot| parrot.name = '' } + @pirate.parrots.each { |parrot| parrot.name = "" } assert !@pirate.valid? @pirate.parrots.each(&:destroy) @@ -1040,7 +1040,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_a_child_marked_for_destruction_should_not_be_destroyed_twice_while_saving_habtm - @pirate.parrots.create!(:name => "parrots_1") + @pirate.parrots.create!(name: "parrots_1") @pirate.parrots.each(&:mark_for_destruction) assert @pirate.save @@ -1053,13 +1053,13 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase end def test_should_rollback_destructions_if_an_exception_occurred_while_saving_habtm - 2.times { |i| @pirate.parrots.create!(:name => "parrots_#{i}") } + 2.times { |i| @pirate.parrots.create!(name: "parrots_#{i}") } before = @pirate.parrots.map { |c| c.mark_for_destruction ; c } class << @pirate.association(:parrots) def destroy(*args) super - raise 'Oh noes!' + raise "Oh noes!" end end @@ -1072,8 +1072,8 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase define_method("test_should_run_add_callback_#{callback_type}s_for_habtm") do association_name_with_callbacks = "parrots_with_#{callback_type}_callbacks" - pirate = Pirate.new(:catchphrase => "Arr") - pirate.send(association_name_with_callbacks).build(:name => "Crowe the One-Eyed") + pirate = Pirate.new(catchphrase: "Arr") + pirate.send(association_name_with_callbacks).build(name: "Crowe the One-Eyed") expected = [ "before_adding_#{callback_type}_parrot_<new>", @@ -1086,7 +1086,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase define_method("test_should_run_remove_callback_#{callback_type}s_for_habtm") do association_name_with_callbacks = "parrots_with_#{callback_type}_callbacks" - @pirate.send(association_name_with_callbacks).create!(:name => "Crowe the One-Eyed") + @pirate.send(association_name_with_callbacks).create!(name: "Crowe the One-Eyed") @pirate.send(association_name_with_callbacks).each(&:mark_for_destruction) child_id = @pirate.send(association_name_with_callbacks).first.id @@ -1108,21 +1108,21 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase def setup super - @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @ship = @pirate.create_ship(:name => 'Nights Dirty Lightning') + @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") + @ship = @pirate.create_ship(name: "Nights Dirty Lightning") end def test_should_still_work_without_an_associated_model @ship.destroy @pirate.reload.catchphrase = "Arr" @pirate.save - assert_equal 'Arr', @pirate.reload.catchphrase + assert_equal "Arr", @pirate.reload.catchphrase end def test_should_automatically_save_the_associated_model - @pirate.ship.name = 'The Vile Insanity' + @pirate.ship.name = "The Vile Insanity" @pirate.save - assert_equal 'The Vile Insanity', @pirate.reload.ship.name + assert_equal "The Vile Insanity", @pirate.reload.ship.name end def test_changed_for_autosave_should_handle_cycles @@ -1136,13 +1136,13 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_automatically_save_bang_the_associated_model - @pirate.ship.name = 'The Vile Insanity' + @pirate.ship.name = "The Vile Insanity" @pirate.save! - assert_equal 'The Vile Insanity', @pirate.reload.ship.name + assert_equal "The Vile Insanity", @pirate.reload.ship.name end def test_should_automatically_validate_the_associated_model - @pirate.ship.name = '' + @pirate.ship.name = "" assert @pirate.invalid? assert @pirate.errors[:"ship.name"].any? end @@ -1158,7 +1158,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase def test_should_not_ignore_different_error_messages_on_the_same_attribute old_validators = Ship._validators.deep_dup old_callbacks = Ship._validate_callbacks.deep_dup - Ship.validates_format_of :name, :with => /\w/ + Ship.validates_format_of :name, with: /\w/ @pirate.ship.name = "" @pirate.catchphrase = nil assert @pirate.invalid? @@ -1169,48 +1169,48 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_still_allow_to_bypass_validations_on_the_associated_model - @pirate.catchphrase = '' - @pirate.ship.name = '' - @pirate.save(:validate => false) + @pirate.catchphrase = "" + @pirate.ship.name = "" + @pirate.save(validate: false) # Oracle saves empty string as NULL if current_adapter?(:OracleAdapter) assert_equal [nil, nil], [@pirate.reload.catchphrase, @pirate.ship.name] else - assert_equal ['', ''], [@pirate.reload.catchphrase, @pirate.ship.name] + assert_equal ["", ""], [@pirate.reload.catchphrase, @pirate.ship.name] end end def test_should_allow_to_bypass_validations_on_associated_models_at_any_depth - 2.times { |i| @pirate.ship.parts.create!(:name => "part #{i}") } + 2.times { |i| @pirate.ship.parts.create!(name: "part #{i}") } - @pirate.catchphrase = '' - @pirate.ship.name = '' - @pirate.ship.parts.each { |part| part.name = '' } - @pirate.save(:validate => false) + @pirate.catchphrase = "" + @pirate.ship.name = "" + @pirate.ship.parts.each { |part| part.name = "" } + @pirate.save(validate: false) values = [@pirate.reload.catchphrase, @pirate.ship.name, *@pirate.ship.parts.map(&:name)] # Oracle saves empty string as NULL if current_adapter?(:OracleAdapter) assert_equal [nil, nil, nil, nil], values else - assert_equal ['', '', '', ''], values + assert_equal ["", "", "", ""], values end end def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that - @pirate.ship.name = '' + @pirate.ship.name = "" assert_raise(ActiveRecord::RecordInvalid) do @pirate.save! end end def test_should_not_save_and_return_false_if_a_callback_cancelled_saving - pirate = Pirate.new(:catchphrase => 'Arr') - ship = pirate.build_ship(:name => 'The Vile Insanity') + pirate = Pirate.new(catchphrase: "Arr") + ship = pirate.build_ship(name: "The Vile Insanity") ship.cancel_save_from_callback = true - assert_no_difference 'Pirate.count' do - assert_no_difference 'Ship.count' do + assert_no_difference "Pirate.count" do + assert_no_difference "Ship.count" do assert !pirate.save end end @@ -1219,14 +1219,14 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase def test_should_rollback_any_changes_if_an_exception_occurred_while_saving before = [@pirate.catchphrase, @pirate.ship.name] - @pirate.catchphrase = 'Arr' - @pirate.ship.name = 'The Vile Insanity' + @pirate.catchphrase = "Arr" + @pirate.ship.name = "The Vile Insanity" # Stub the save method of the @pirate.ship instance to raise an exception class << @pirate.ship def save(*args) super - raise 'Oh noes!' + raise "Oh noes!" end end @@ -1235,7 +1235,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_not_load_the_associated_model - assert_queries(1) { @pirate.catchphrase = 'Arr'; @pirate.save! } + assert_queries(1) { @pirate.catchphrase = "Arr"; @pirate.save! } end def test_mark_for_destruction_is_ignored_without_autosave_true @@ -1260,7 +1260,7 @@ class TestAutosaveAssociationOnAHasOneThroughAssociation < ActiveRecord::TestCas class << @member.organization def save(*args) super - raise 'Oh noes!' + raise "Oh noes!" end end assert_nothing_raised { @member.save } @@ -1272,31 +1272,31 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase def setup super - @ship = Ship.create(:name => 'Nights Dirty Lightning') - @pirate = @ship.create_pirate(:catchphrase => "Don' botharrr talkin' like one, savvy?") + @ship = Ship.create(name: "Nights Dirty Lightning") + @pirate = @ship.create_pirate(catchphrase: "Don' botharrr talkin' like one, savvy?") end def test_should_still_work_without_an_associated_model @pirate.destroy @ship.reload.name = "The Vile Insanity" @ship.save - assert_equal 'The Vile Insanity', @ship.reload.name + assert_equal "The Vile Insanity", @ship.reload.name end def test_should_automatically_save_the_associated_model - @ship.pirate.catchphrase = 'Arr' + @ship.pirate.catchphrase = "Arr" @ship.save - assert_equal 'Arr', @ship.reload.pirate.catchphrase + assert_equal "Arr", @ship.reload.pirate.catchphrase end def test_should_automatically_save_bang_the_associated_model - @ship.pirate.catchphrase = 'Arr' + @ship.pirate.catchphrase = "Arr" @ship.save! - assert_equal 'Arr', @ship.reload.pirate.catchphrase + assert_equal "Arr", @ship.reload.pirate.catchphrase end def test_should_automatically_validate_the_associated_model - @ship.pirate.catchphrase = '' + @ship.pirate.catchphrase = "" assert @ship.invalid? assert @ship.errors[:"pirate.catchphrase"].any? end @@ -1310,31 +1310,31 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase end def test_should_still_allow_to_bypass_validations_on_the_associated_model - @ship.pirate.catchphrase = '' - @ship.name = '' - @ship.save(:validate => false) + @ship.pirate.catchphrase = "" + @ship.name = "" + @ship.save(validate: false) # Oracle saves empty string as NULL if current_adapter?(:OracleAdapter) assert_equal [nil, nil], [@ship.reload.name, @ship.pirate.catchphrase] else - assert_equal ['', ''], [@ship.reload.name, @ship.pirate.catchphrase] + assert_equal ["", ""], [@ship.reload.name, @ship.pirate.catchphrase] end end def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that - @ship.pirate.catchphrase = '' + @ship.pirate.catchphrase = "" assert_raise(ActiveRecord::RecordInvalid) do @ship.save! end end def test_should_not_save_and_return_false_if_a_callback_cancelled_saving - ship = Ship.new(:name => 'The Vile Insanity') - pirate = ship.build_pirate(:catchphrase => 'Arr') + ship = Ship.new(name: "The Vile Insanity") + pirate = ship.build_pirate(catchphrase: "Arr") pirate.cancel_save_from_callback = true - assert_no_difference 'Ship.count' do - assert_no_difference 'Pirate.count' do + assert_no_difference "Ship.count" do + assert_no_difference "Pirate.count" do assert !ship.save end end @@ -1343,14 +1343,14 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase def test_should_rollback_any_changes_if_an_exception_occurred_while_saving before = [@ship.pirate.catchphrase, @ship.name] - @ship.pirate.catchphrase = 'Arr' - @ship.name = 'The Vile Insanity' + @ship.pirate.catchphrase = "Arr" + @ship.name = "The Vile Insanity" # Stub the save method of the @ship.pirate instance to raise an exception class << @ship.pirate def save(*args) super - raise 'Oh noes!' + raise "Oh noes!" end end @@ -1359,13 +1359,13 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase end def test_should_not_load_the_associated_model - assert_queries(1) { @ship.name = 'The Vile Insanity'; @ship.save! } + assert_queries(1) { @ship.name = "The Vile Insanity"; @ship.save! } end end module AutosaveAssociationOnACollectionAssociationTests def test_should_automatically_save_the_associated_models - new_names = ['Grace OMalley', 'Privateers Greed'] + new_names = ["Grace OMalley", "Privateers Greed"] @pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] } @pirate.save @@ -1373,7 +1373,7 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_automatically_save_bang_the_associated_models - new_names = ['Grace OMalley', 'Privateers Greed'] + new_names = ["Grace OMalley", "Privateers Greed"] @pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] } @pirate.save! @@ -1391,7 +1391,7 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_automatically_validate_the_associated_models - @pirate.send(@association_name).each { |child| child.name = '' } + @pirate.send(@association_name).each { |child| child.name = "" } assert !@pirate.valid? assert_equal ["can't be blank"], @pirate.errors["#{@association_name}.name"] @@ -1399,7 +1399,7 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_not_use_default_invalid_error_on_associated_models - @pirate.send(@association_name).build(:name => '') + @pirate.send(@association_name).build(name: "") assert !@pirate.valid? assert_equal ["can't be blank"], @pirate.errors["#{@association_name}.name"] @@ -1407,11 +1407,11 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_default_invalid_error_from_i18n - I18n.backend.store_translations(:en, activerecord: {errors: { models: + I18n.backend.store_translations(:en, activerecord: { errors: { models: { @associated_model_name.to_s.to_sym => { blank: "cannot be blank" } } - }}) + } }) - @pirate.send(@association_name).build(name: '') + @pirate.send(@association_name).build(name: "") assert !@pirate.valid? assert_equal ["cannot be blank"], @pirate.errors["#{@association_name}.name"] @@ -1422,7 +1422,7 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_merge_errors_on_the_associated_models_onto_the_parent_even_if_it_is_not_valid - @pirate.send(@association_name).each { |child| child.name = '' } + @pirate.send(@association_name).each { |child| child.name = "" } @pirate.catchphrase = nil assert !@pirate.valid? @@ -1431,10 +1431,10 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_allow_to_bypass_validations_on_the_associated_models_on_update - @pirate.catchphrase = '' - @pirate.send(@association_name).each { |child| child.name = '' } + @pirate.catchphrase = "" + @pirate.send(@association_name).each { |child| child.name = "" } - assert @pirate.save(:validate => false) + assert @pirate.save(validate: false) # Oracle saves empty string as NULL if current_adapter?(:OracleAdapter) assert_equal [nil, nil, nil], [ @@ -1443,7 +1443,7 @@ module AutosaveAssociationOnACollectionAssociationTests @pirate.send(@association_name).last.name ] else - assert_equal ['', '', ''], [ + assert_equal ["", "", ""], [ @pirate.reload.catchphrase, @pirate.send(@association_name).first.name, @pirate.send(@association_name).last.name @@ -1461,24 +1461,24 @@ module AutosaveAssociationOnACollectionAssociationTests def test_should_allow_to_bypass_validations_on_the_associated_models_on_create assert_difference("#{ @association_name == :birds ? 'Bird' : 'Parrot' }.count", 2) do 2.times { @pirate.send(@association_name).build } - @pirate.save(:validate => false) + @pirate.save(validate: false) end end def test_should_not_save_and_return_false_if_a_callback_cancelled_saving_in_either_create_or_update - @pirate.catchphrase = 'Changed' - @child_1.name = 'Changed' + @pirate.catchphrase = "Changed" + @child_1.name = "Changed" @child_1.cancel_save_from_callback = true assert !@pirate.save assert_equal "Don' botharrr talkin' like one, savvy?", @pirate.reload.catchphrase assert_equal "Posideons Killer", @child_1.reload.name - new_pirate = Pirate.new(:catchphrase => 'Arr') - new_child = new_pirate.send(@association_name).build(:name => 'Grace OMalley') + new_pirate = Pirate.new(catchphrase: "Arr") + new_child = new_pirate.send(@association_name).build(name: "Grace OMalley") new_child.cancel_save_from_callback = true - assert_no_difference 'Pirate.count' do + assert_no_difference "Pirate.count" do assert_no_difference "#{new_child.class.name}.count" do assert !new_pirate.save end @@ -1487,16 +1487,16 @@ module AutosaveAssociationOnACollectionAssociationTests def test_should_rollback_any_changes_if_an_exception_occurred_while_saving before = [@pirate.catchphrase, *@pirate.send(@association_name).map(&:name)] - new_names = ['Grace OMalley', 'Privateers Greed'] + new_names = ["Grace OMalley", "Privateers Greed"] - @pirate.catchphrase = 'Arr' + @pirate.catchphrase = "Arr" @pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] } # Stub the save method of the first child instance to raise an exception class << @pirate.send(@association_name).first def save(*args) super - raise 'Oh noes!' + raise "Oh noes!" end end @@ -1505,20 +1505,20 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_that - @pirate.send(@association_name).each { |child| child.name = '' } + @pirate.send(@association_name).each { |child| child.name = "" } assert_raise(ActiveRecord::RecordInvalid) do @pirate.save! end end def test_should_not_load_the_associated_models_if_they_were_not_loaded_yet - assert_queries(1) { @pirate.catchphrase = 'Arr'; @pirate.save! } + assert_queries(1) { @pirate.catchphrase = "Arr"; @pirate.save! } @pirate.send(@association_name).load_target assert_queries(3) do - @pirate.catchphrase = 'Yarr' - new_names = ['Grace OMalley', 'Privateers Greed'] + @pirate.catchphrase = "Yarr" + new_names = ["Grace OMalley", "Privateers Greed"] @pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] } @pirate.save! end @@ -1533,9 +1533,9 @@ class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase @association_name = :birds @associated_model_name = :bird - @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @child_1 = @pirate.birds.create(:name => 'Posideons Killer') - @child_2 = @pirate.birds.create(:name => 'Killer bandita Dionne') + @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") + @child_1 = @pirate.birds.create(name: "Posideons Killer") + @child_2 = @pirate.birds.create(name: "Killer bandita Dionne") end include AutosaveAssociationOnACollectionAssociationTests @@ -1551,8 +1551,8 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::T @habtm = true @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") - @child_1 = @pirate.parrots.create(name: 'Posideons Killer') - @child_2 = @pirate.parrots.create(name: 'Killer bandita Dionne') + @child_1 = @pirate.parrots.create(name: "Posideons Killer") + @child_2 = @pirate.parrots.create(name: "Killer bandita Dionne") end include AutosaveAssociationOnACollectionAssociationTests @@ -1568,8 +1568,8 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociationWithAcceptsNestedA @habtm = true @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") - @child_1 = @pirate.parrots.create(name: 'Posideons Killer') - @child_2 = @pirate.parrots.create(name: 'Killer bandita Dionne') + @child_1 = @pirate.parrots.create(name: "Posideons Killer") + @child_2 = @pirate.parrots.create(name: "Killer bandita Dionne") end include AutosaveAssociationOnACollectionAssociationTests @@ -1580,13 +1580,13 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te def setup super - @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @pirate.birds.create(:name => 'cookoo') + @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") + @pirate.birds.create(name: "cookoo") end test "should automatically validate associations" do assert @pirate.valid? - @pirate.birds.each { |bird| bird.name = '' } + @pirate.birds.each { |bird| bird.name = "" } assert !@pirate.valid? end @@ -1597,20 +1597,20 @@ class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::Tes def setup super - @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @pirate.create_ship(:name => 'titanic') + @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") + @pirate.create_ship(name: "titanic") super end test "should automatically validate associations with :validate => true" do assert @pirate.valid? - @pirate.ship.name = '' + @pirate.ship.name = "" assert !@pirate.valid? end test "should not automatically add validate associations without :validate => true" do assert @pirate.valid? - @pirate.non_validated_ship.name = '' + @pirate.non_validated_ship.name = "" assert @pirate.valid? end end @@ -1620,18 +1620,18 @@ class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord:: def setup super - @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") + @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") end test "should automatically validate associations with :validate => true" do assert @pirate.valid? - @pirate.parrot = Parrot.new(:name => '') + @pirate.parrot = Parrot.new(name: "") assert !@pirate.valid? end test "should not automatically validate associations without :validate => true" do assert @pirate.valid? - @pirate.non_validated_parrot = Parrot.new(:name => '') + @pirate.non_validated_parrot = Parrot.new(name: "") assert @pirate.valid? end end @@ -1641,20 +1641,20 @@ class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::Test def setup super - @pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?") + @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") end test "should automatically validate associations with :validate => true" do assert @pirate.valid? - @pirate.parrots = [ Parrot.new(:name => 'popuga') ] - @pirate.parrots.each { |parrot| parrot.name = '' } + @pirate.parrots = [ Parrot.new(name: "popuga") ] + @pirate.parrots.each { |parrot| parrot.name = "" } assert !@pirate.valid? end test "should not automatically validate associations without :validate => true" do assert @pirate.valid? - @pirate.non_validated_parrots = [ Parrot.new(:name => 'popuga') ] - @pirate.non_validated_parrots.each { |parrot| parrot.name = '' } + @pirate.non_validated_parrots = [ Parrot.new(name: "popuga") ] + @pirate.non_validated_parrots.each { |parrot| parrot.name = "" } assert @pirate.valid? end end @@ -1695,6 +1695,6 @@ end class TestAutosaveAssociationWithTouch < ActiveRecord::TestCase def test_autosave_with_touch_should_not_raise_system_stack_error invoice = Invoice.create - assert_nothing_raised { invoice.line_items.create(:amount => 10) } + assert_nothing_raised { invoice.line_items.create(amount: 10) } end end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index eef2d29d02..fafa144c6f 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1,32 +1,30 @@ require "cases/helper" -require 'models/post' -require 'models/author' -require 'models/topic' -require 'models/reply' -require 'models/category' -require 'models/company' -require 'models/customer' -require 'models/developer' -require 'models/computer' -require 'models/project' -require 'models/default' -require 'models/auto_id' -require 'models/boolean' -require 'models/column_name' -require 'models/subscriber' -require 'models/keyboard' -require 'models/comment' -require 'models/minimalistic' -require 'models/warehouse_thing' -require 'models/parrot' -require 'models/person' -require 'models/edge' -require 'models/joke' -require 'models/bird' -require 'models/car' -require 'models/bulb' -require 'rexml/document' -require 'concurrent/atomic/count_down_latch' +require "models/post" +require "models/author" +require "models/topic" +require "models/reply" +require "models/category" +require "models/company" +require "models/customer" +require "models/developer" +require "models/computer" +require "models/project" +require "models/default" +require "models/auto_id" +require "models/boolean" +require "models/column_name" +require "models/subscriber" +require "models/comment" +require "models/minimalistic" +require "models/warehouse_thing" +require "models/parrot" +require "models/person" +require "models/edge" +require "models/joke" +require "models/bird" +require "models/car" +require "models/bulb" +require "concurrent/atomic/count_down_latch" class FirstAbstractClass < ActiveRecord::Base self.abstract_class = true @@ -75,17 +73,17 @@ class LintTest < ActiveRecord::TestCase end class BasicsTest < ActiveRecord::TestCase - fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts + fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, "warehouse-things", :authors, :categorizations, :categories, :posts def test_column_names_are_escaped conn = ActiveRecord::Base.connection classname = conn.class.name[/[^:]*$/] badchar = { - 'SQLite3Adapter' => '"', - 'Mysql2Adapter' => '`', - 'PostgreSQLAdapter' => '"', - 'OracleAdapter' => '"', - 'FbAdapter' => '"' + "SQLite3Adapter" => '"', + "Mysql2Adapter" => "`", + "PostgreSQLAdapter" => '"', + "OracleAdapter" => '"', + "FbAdapter" => '"' }.fetch(classname) { raise "need a bad char for #{classname}" } @@ -102,7 +100,7 @@ class BasicsTest < ActiveRecord::TestCase def test_columns_should_obey_set_primary_key pk = Subscriber.columns_hash[Subscriber.primary_key] - assert_equal 'nick', pk.name, 'nick should be primary key' + assert_equal "nick", pk.name, "nick should be primary key" end def test_primary_key_with_no_id @@ -117,6 +115,13 @@ class BasicsTest < ActiveRecord::TestCase end end + def test_many_mutations + car = Car.new name: "<3<3<3" + car.engines_count = 0 + 20_000.times { car.engines_count += 1 } + assert car.save + end + def test_limit_without_comma assert_equal 1, Topic.limit("1").to_a.length assert_equal 1, Topic.limit(1).to_a.length @@ -166,17 +171,17 @@ class BasicsTest < ActiveRecord::TestCase def test_previously_changed topic = Topic.first - topic.title = '<3<3<3' + topic.title = "<3<3<3" assert_equal({}, topic.previous_changes) topic.save! expected = ["The First Topic", "<3<3<3"] - assert_equal(expected, topic.previous_changes['title']) + assert_equal(expected, topic.previous_changes["title"]) end def test_previously_changed_dup topic = Topic.first - topic.title = '<3<3<3' + topic.title = "<3<3<3" topic.save! t2 = topic.dup @@ -213,7 +218,7 @@ class BasicsTest < ActiveRecord::TestCase with_env_tz eastern_time_zone do with_timezone_config default: :utc do time = Time.local(2000) - topic = Topic.create('written_on' => time) + topic = Topic.create("written_on" => time) saved_time = Topic.find(topic.id).reload.written_on assert_equal time, saved_time assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "EST"], time.to_a @@ -225,9 +230,9 @@ class BasicsTest < ActiveRecord::TestCase def test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_utc with_env_tz eastern_time_zone do with_timezone_config default: :utc do - Time.use_zone 'Central Time (US & Canada)' do + Time.use_zone "Central Time (US & Canada)" do time = Time.zone.local(2000) - topic = Topic.create('written_on' => time) + topic = Topic.create("written_on" => time) saved_time = Topic.find(topic.id).reload.written_on assert_equal time, saved_time assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a @@ -241,7 +246,7 @@ class BasicsTest < ActiveRecord::TestCase with_env_tz eastern_time_zone do with_timezone_config default: :local do time = Time.utc(2000) - topic = Topic.create('written_on' => time) + topic = Topic.create("written_on" => time) saved_time = Topic.find(topic.id).reload.written_on assert_equal time, saved_time assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], time.to_a @@ -253,9 +258,9 @@ class BasicsTest < ActiveRecord::TestCase def test_preserving_time_objects_with_time_with_zone_conversion_to_default_timezone_local with_env_tz eastern_time_zone do with_timezone_config default: :local do - Time.use_zone 'Central Time (US & Canada)' do + Time.use_zone "Central Time (US & Canada)" do time = Time.zone.local(2000) - topic = Topic.create('written_on' => time) + topic = Topic.create("written_on" => time) saved_time = Topic.find(topic.id).reload.written_on assert_equal time, saved_time assert_equal [0, 0, 0, 1, 1, 2000, 6, 1, false, "CST"], time.to_a @@ -281,49 +286,48 @@ class BasicsTest < ActiveRecord::TestCase end def test_initialize_with_attributes - topic = Topic.new({ - "title" => "initialized from attributes", "written_on" => "2003-12-12 23:23" - }) + topic = Topic.new( + "title" => "initialized from attributes", "written_on" => "2003-12-12 23:23") assert_equal("initialized from attributes", topic.title) end def test_initialize_with_invalid_attribute - Topic.new({ "title" => "test", - "last_read(1i)" => "2005", "last_read(2i)" => "2", "last_read(3i)" => "31"}) + Topic.new("title" => "test", + "last_read(1i)" => "2005", "last_read(2i)" => "2", "last_read(3i)" => "31") rescue ActiveRecord::MultiparameterAssignmentErrors => ex assert_equal(1, ex.errors.size) assert_equal("last_read", ex.errors[0].attribute) end def test_create_after_initialize_without_block - cb = CustomBulb.create(:name => 'Dude') - assert_equal('Dude', cb.name) + cb = CustomBulb.create(name: "Dude") + assert_equal("Dude", cb.name) assert_equal(true, cb.frickinawesome) end def test_create_after_initialize_with_block - cb = CustomBulb.create {|c| c.name = 'Dude' } - assert_equal('Dude', cb.name) + cb = CustomBulb.create { |c| c.name = "Dude" } + assert_equal("Dude", cb.name) assert_equal(true, cb.frickinawesome) end def test_create_after_initialize_with_array_param - cbs = CustomBulb.create([{ name: 'Dude' }, { name: 'Bob' }]) - assert_equal 'Dude', cbs[0].name - assert_equal 'Bob', cbs[1].name + cbs = CustomBulb.create([{ name: "Dude" }, { name: "Bob" }]) + assert_equal "Dude", cbs[0].name + assert_equal "Bob", cbs[1].name assert cbs[0].frickinawesome assert !cbs[1].frickinawesome end def test_load - topics = Topic.all.merge!(:order => 'id').to_a + topics = Topic.all.merge!(order: "id").to_a assert_equal(5, topics.size) assert_equal(topics(:first).title, topics.first.title) end def test_load_with_condition - topics = Topic.all.merge!(:where => "author_name = 'Mary'").to_a + topics = Topic.all.merge!(where: "author_name = 'Mary'").to_a assert_equal(1, topics.size) assert_equal(topics(:second).title, topics.first.title) @@ -445,7 +449,7 @@ class BasicsTest < ActiveRecord::TestCase if current_adapter?(:Mysql2Adapter) def test_update_all_with_order_and_limit - assert_equal 1, Topic.limit(1).order('id DESC').update_all(:content => 'bulk updated!') + assert_equal 1, Topic.limit(1).order("id DESC").update_all(content: "bulk updated!") end end @@ -520,16 +524,16 @@ class BasicsTest < ActiveRecord::TestCase end def test_find_by_slug - assert_equal Topic.find('1-meowmeow'), Topic.find(1) + assert_equal Topic.find("1-meowmeow"), Topic.find(1) end def test_find_by_slug_with_array - assert_equal Topic.find([1, 2]), Topic.find(['1-meowmeow', '2-hello']) - assert_equal 'The Second Topic of the day', Topic.find(['2-hello', '1-meowmeow']).first.title + assert_equal Topic.find([1, 2]), Topic.find(["1-meowmeow", "2-hello"]) + assert_equal "The Second Topic of the day", Topic.find(["2-hello", "1-meowmeow"]).first.title end def test_find_by_slug_with_range - assert_equal Topic.where(id: '1-meowmeow'..'2-hello'), Topic.where(id: 1..2) + assert_equal Topic.where(id: "1-meowmeow".."2-hello"), Topic.where(id: 1..2) end def test_equality_of_new_records @@ -538,7 +542,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_equality_of_destroyed_records - topic_1 = Topic.new(:title => 'test_1') + topic_1 = Topic.new(title: "test_1") topic_1.save topic_2 = Topic.find(topic_1.id) topic_1.destroy @@ -547,8 +551,8 @@ class BasicsTest < ActiveRecord::TestCase end def test_equality_with_blank_ids - one = Subscriber.new(:id => '') - two = Subscriber.new(:id => '') + one = Subscriber.new(id: "") + two = Subscriber.new(id: "") assert_equal one, two end @@ -557,8 +561,8 @@ class BasicsTest < ActiveRecord::TestCase car.bulbs.build car.save - assert car.bulbs == Bulb.where(car_id: car.id), 'CollectionProxy should be comparable with Relation' - assert Bulb.where(car_id: car.id) == car.bulbs, 'Relation should be comparable with CollectionProxy' + assert car.bulbs == Bulb.where(car_id: car.id), "CollectionProxy should be comparable with Relation" + assert Bulb.where(car_id: car.id) == car.bulbs, "Relation should be comparable with CollectionProxy" end def test_equality_of_relation_and_array @@ -566,7 +570,7 @@ class BasicsTest < ActiveRecord::TestCase car.bulbs.build car.save - assert Bulb.where(car_id: car.id) == car.bulbs.to_a, 'Relation should be comparable with Array' + assert Bulb.where(car_id: car.id) == car.bulbs.to_a, "Relation should be comparable with Array" end def test_equality_of_relation_and_association_relation @@ -574,8 +578,8 @@ class BasicsTest < ActiveRecord::TestCase car.bulbs.build car.save - assert_equal Bulb.where(car_id: car.id), car.bulbs.includes(:car), 'Relation should be comparable with AssociationRelation' - assert_equal car.bulbs.includes(:car), Bulb.where(car_id: car.id), 'AssociationRelation should be comparable with Relation' + assert_equal Bulb.where(car_id: car.id), car.bulbs.includes(:car), "Relation should be comparable with AssociationRelation" + assert_equal car.bulbs.includes(:car), Bulb.where(car_id: car.id), "AssociationRelation should be comparable with Relation" end def test_equality_of_collection_proxy_and_association_relation @@ -583,8 +587,8 @@ class BasicsTest < ActiveRecord::TestCase car.bulbs.build car.save - assert_equal car.bulbs, car.bulbs.includes(:car), 'CollectionProxy should be comparable with AssociationRelation' - assert_equal car.bulbs.includes(:car), car.bulbs, 'AssociationRelation should be comparable with CollectionProxy' + assert_equal car.bulbs, car.bulbs.includes(:car), "CollectionProxy should be comparable with AssociationRelation" + assert_equal car.bulbs.includes(:car), car.bulbs, "AssociationRelation should be comparable with CollectionProxy" end def test_hashing @@ -606,14 +610,14 @@ class BasicsTest < ActiveRecord::TestCase def test_create_without_prepared_statement topic = Topic.connection.unprepared_statement do - Topic.create(:title => 'foo') + Topic.create(title: "foo") end assert_equal topic, Topic.find(topic.id) end def test_destroy_without_prepared_statement - topic = Topic.create(title: 'foo') + topic = Topic.create(title: "foo") Topic.connection.unprepared_statement do Topic.find(topic.id).destroy end @@ -623,7 +627,7 @@ class BasicsTest < ActiveRecord::TestCase def test_comparison_with_different_objects topic = Topic.create - category = Category.create(:name => "comparison") + category = Category.create(name: "comparison") assert_nil topic <=> category end @@ -635,9 +639,9 @@ class BasicsTest < ActiveRecord::TestCase end def test_readonly_attributes - assert_equal Set.new([ 'title' , 'comments_count' ]), ReadonlyTitlePost.readonly_attributes + assert_equal Set.new([ "title" , "comments_count" ]), ReadonlyTitlePost.readonly_attributes - post = ReadonlyTitlePost.create(:title => "cannot change this", :body => "changeable") + post = ReadonlyTitlePost.create(title: "cannot change this", body: "changeable") post.reload assert_equal "cannot change this", post.title @@ -649,8 +653,8 @@ class BasicsTest < ActiveRecord::TestCase def test_unicode_column_name Weird.reset_column_information - weird = Weird.create(:なまえ => 'たこ焼き仮面') - assert_equal 'たこ焼き仮面', weird.なまえ + weird = Weird.create(なまえ: "たこ焼き仮面") + assert_equal "たこ焼き仮面", weird.なまえ end unless current_adapter?(:PostgreSQLAdapter) @@ -660,7 +664,7 @@ class BasicsTest < ActiveRecord::TestCase Weird.reset_column_information - assert_equal ["EUC-JP"], Weird.columns.map {|c| c.name.encoding.name }.uniq + assert_equal ["EUC-JP"], Weird.columns.map { |c| c.name.encoding.name }.uniq ensure silence_warnings { Encoding.default_internal = old_default_internal } Weird.reset_column_information @@ -668,21 +672,21 @@ class BasicsTest < ActiveRecord::TestCase end def test_non_valid_identifier_column_name - weird = Weird.create('a$b' => 'value') + weird = Weird.create("a$b" => "value") weird.reload - assert_equal 'value', weird.send('a$b') - assert_equal 'value', weird.read_attribute('a$b') + assert_equal "value", weird.send("a$b") + assert_equal "value", weird.read_attribute("a$b") - weird.update_columns('a$b' => 'value2') + weird.update_columns("a$b" => "value2") weird.reload - assert_equal 'value2', weird.send('a$b') - assert_equal 'value2', weird.read_attribute('a$b') + assert_equal "value2", weird.send("a$b") + assert_equal "value2", weird.read_attribute("a$b") end def test_group_weirds_by_from - Weird.create('a$b' => 'value', :from => 'aaron') + Weird.create("a$b" => "value", :from => "aaron") count = Weird.group(Weird.arel_table[:from]).count - assert_equal 1, count['aaron'] + assert_equal 1, count["aaron"] end def test_attributes_on_dummy_time @@ -712,11 +716,11 @@ class BasicsTest < ActiveRecord::TestCase end def test_boolean - b_nil = Boolean.create({ "value" => nil }) + b_nil = Boolean.create("value" => nil) nil_id = b_nil.id - b_false = Boolean.create({ "value" => false }) + b_false = Boolean.create("value" => false) false_id = b_false.id - b_true = Boolean.create({ "value" => true }) + b_true = Boolean.create("value" => true) true_id = b_true.id b_nil = Boolean.find(nil_id) @@ -728,7 +732,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_boolean_without_questionmark - b_true = Boolean.create({ "value" => true }) + b_true = Boolean.create("value" => true) true_id = b_true.id subclass = Class.new(Boolean).find true_id @@ -738,11 +742,11 @@ class BasicsTest < ActiveRecord::TestCase end def test_boolean_cast_from_string - b_blank = Boolean.create({ "value" => "" }) + b_blank = Boolean.create("value" => "") blank_id = b_blank.id - b_false = Boolean.create({ "value" => "0" }) + b_false = Boolean.create("value" => "0") false_id = b_false.id - b_true = Boolean.create({ "value" => "1" }) + b_true = Boolean.create("value" => "1") true_id = b_true.id b_blank = Boolean.find(blank_id) @@ -791,8 +795,8 @@ class BasicsTest < ActiveRecord::TestCase DeveloperSalary = Struct.new(:amount) def test_dup_with_aggregate_of_same_name_as_attribute developer_with_aggregate = Class.new(ActiveRecord::Base) do - self.table_name = 'developers' - composed_of :salary, :class_name => 'BasicsTest::DeveloperSalary', :mapping => [%w(salary amount)] + self.table_name = "developers" + composed_of :salary, class_name: "BasicsTest::DeveloperSalary", mapping: [%w(salary amount)] end dev = developer_with_aggregate.find(1) @@ -839,7 +843,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_clone_of_new_object_marks_attributes_as_dirty - developer = Developer.new :name => 'Bjorn', :salary => 100000 + developer = Developer.new name: "Bjorn", salary: 100000 assert developer.name_changed? assert developer.salary_changed? @@ -849,7 +853,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_clone_of_new_object_marks_as_dirty_only_changed_attributes - developer = Developer.new :name => 'Bjorn' + developer = Developer.new name: "Bjorn" assert developer.name_changed? # obviously assert !developer.salary_changed? # attribute has non-nil default value, so treated as not changed @@ -859,7 +863,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_dup_of_saved_object_marks_attributes_as_dirty - developer = Developer.create! :name => 'Bjorn', :salary => 100000 + developer = Developer.create! name: "Bjorn", salary: 100000 assert !developer.name_changed? assert !developer.salary_changed? @@ -869,7 +873,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_dup_of_saved_object_marks_as_dirty_only_changed_attributes - developer = Developer.create! :name => 'Bjorn' + developer = Developer.create! name: "Bjorn" assert !developer.name_changed? # both attributes of saved object should be treated as not changed assert !developer.salary_changed? @@ -897,15 +901,15 @@ class BasicsTest < ActiveRecord::TestCase assert_equal Time.local(2004, 1,1,0,0,0,0), default.fixed_time # char types - assert_equal 'Y', default.char1 - assert_equal 'a varchar field', default.char2 - assert_equal 'a text field', default.char3 + assert_equal "Y", default.char1 + assert_equal "a varchar field", default.char2 + assert_equal "a text field", default.char3 end end end class NumericData < ActiveRecord::Base - self.table_name = 'numeric_data' + self.table_name = "numeric_data" attribute :my_house_population, :integer attribute :atoms_in_universe, :integer @@ -913,10 +917,10 @@ class BasicsTest < ActiveRecord::TestCase def test_big_decimal_conditions m = NumericData.new( - :bank_balance => 1586.43, - :big_bank_balance => BigDecimal("1000234000567.95"), - :world_population => 6000000000, - :my_house_population => 3 + bank_balance: 1586.43, + big_bank_balance: BigDecimal("1000234000567.95"), + world_population: 6000000000, + my_house_population: 3 ) assert m.save assert_equal 0, NumericData.where("bank_balance > ?", 2000.0).count @@ -924,10 +928,10 @@ class BasicsTest < ActiveRecord::TestCase def test_numeric_fields m = NumericData.new( - :bank_balance => 1586.43, - :big_bank_balance => BigDecimal("1000234000567.95"), - :world_population => 6000000000, - :my_house_population => 3 + bank_balance: 1586.43, + big_bank_balance: BigDecimal("1000234000567.95"), + world_population: 6000000000, + my_house_population: 3 ) assert m.save @@ -940,7 +944,7 @@ class BasicsTest < ActiveRecord::TestCase assert_kind_of Integer, m1.world_population assert_equal 6000000000, m1.world_population - assert_kind_of Fixnum, m1.my_house_population + assert_kind_of Integer, m1.my_house_population assert_equal 3, m1.my_house_population assert_kind_of BigDecimal, m1.bank_balance @@ -952,10 +956,10 @@ class BasicsTest < ActiveRecord::TestCase def test_numeric_fields_with_scale m = NumericData.new( - :bank_balance => 1586.43122334, - :big_bank_balance => BigDecimal("234000567.952344"), - :world_population => 6000000000, - :my_house_population => 3 + bank_balance: 1586.43122334, + big_bank_balance: BigDecimal("234000567.952344"), + world_population: 6000000000, + my_house_population: 3 ) assert m.save @@ -968,7 +972,7 @@ class BasicsTest < ActiveRecord::TestCase assert_kind_of Integer, m1.world_population assert_equal 6000000000, m1.world_population - assert_kind_of Fixnum, m1.my_house_population + assert_kind_of Integer, m1.my_house_population assert_equal 3, m1.my_house_population assert_kind_of BigDecimal, m1.bank_balance @@ -1001,16 +1005,16 @@ class BasicsTest < ActiveRecord::TestCase end def test_quoting_arrays - replies = Reply.all.merge!(:where => [ "id IN (?)", topics(:first).replies.collect(&:id) ]).to_a + replies = Reply.all.merge!(where: [ "id IN (?)", topics(:first).replies.collect(&:id) ]).to_a assert_equal topics(:first).replies.size, replies.size - replies = Reply.all.merge!(:where => [ "id IN (?)", [] ]).to_a + replies = Reply.all.merge!(where: [ "id IN (?)", [] ]).to_a assert_equal 0, replies.size end def test_quote author_name = "\\ \001 ' \n \\n \"" - topic = Topic.create('author_name' => author_name) + topic = Topic.create("author_name" => author_name) assert_equal author_name, Topic.find(topic.id).author_name end @@ -1034,12 +1038,6 @@ class BasicsTest < ActiveRecord::TestCase assert_equal t1.title, t2.title end - def test_reload_with_exclusive_scope - dev = DeveloperCalledDavid.first - dev.update!(name: "NotDavid" ) - assert_equal dev, dev.reload - end - def test_switching_between_table_name k = Class.new(Joke) @@ -1095,7 +1093,7 @@ class BasicsTest < ActiveRecord::TestCase def test_set_table_name_symbol_converted_to_string k = Class.new(Joke) k.table_name = :cold_jokes - assert_equal 'cold_jokes', k.table_name + assert_equal "cold_jokes", k.table_name end def test_quoted_table_name_after_set_table_name @@ -1157,17 +1155,17 @@ class BasicsTest < ActiveRecord::TestCase def test_no_limit_offset assert_nothing_raised do - Developer.all.merge!(:offset => 2).to_a + Developer.all.merge!(offset: 2).to_a end end def test_find_last last = Developer.last - assert_equal last, Developer.all.merge!(:order => 'id desc').first + assert_equal last, Developer.all.merge!(order: "id desc").first end def test_last - assert_equal Developer.all.merge!(:order => 'id desc').first, Developer.last + assert_equal Developer.all.merge!(order: "id desc").first, Developer.last end def test_all @@ -1177,37 +1175,37 @@ class BasicsTest < ActiveRecord::TestCase end def test_all_with_conditions - assert_equal Developer.all.merge!(:order => 'id desc').to_a, Developer.order('id desc').to_a + assert_equal Developer.all.merge!(order: "id desc").to_a, Developer.order("id desc").to_a end def test_find_ordered_last - last = Developer.all.merge!(:order => 'developers.salary ASC').last - assert_equal last, Developer.all.merge!(:order => 'developers.salary ASC').to_a.last + last = Developer.all.merge!(order: "developers.salary ASC").last + assert_equal last, Developer.all.merge!(order: "developers.salary ASC").to_a.last end def test_find_reverse_ordered_last - last = Developer.all.merge!(:order => 'developers.salary DESC').last - assert_equal last, Developer.all.merge!(:order => 'developers.salary DESC').to_a.last + last = Developer.all.merge!(order: "developers.salary DESC").last + assert_equal last, Developer.all.merge!(order: "developers.salary DESC").to_a.last end def test_find_multiple_ordered_last - last = Developer.all.merge!(:order => 'developers.name, developers.salary DESC').last - assert_equal last, Developer.all.merge!(:order => 'developers.name, developers.salary DESC').to_a.last + last = Developer.all.merge!(order: "developers.name, developers.salary DESC").last + assert_equal last, Developer.all.merge!(order: "developers.name, developers.salary DESC").to_a.last end def test_find_keeps_multiple_order_values - combined = Developer.all.merge!(:order => 'developers.name, developers.salary').to_a - assert_equal combined, Developer.all.merge!(:order => ['developers.name', 'developers.salary']).to_a + combined = Developer.all.merge!(order: "developers.name, developers.salary").to_a + assert_equal combined, Developer.all.merge!(order: ["developers.name", "developers.salary"]).to_a end def test_find_keeps_multiple_group_values - combined = Developer.all.merge!(:group => 'developers.name, developers.salary, developers.id, developers.created_at, developers.updated_at, developers.created_on, developers.updated_on').to_a - assert_equal combined, Developer.all.merge!(:group => ['developers.name', 'developers.salary', 'developers.id', 'developers.created_at', 'developers.updated_at', 'developers.created_on', 'developers.updated_on']).to_a + combined = Developer.all.merge!(group: "developers.name, developers.salary, developers.id, developers.created_at, developers.updated_at, developers.created_on, developers.updated_on").to_a + assert_equal combined, Developer.all.merge!(group: ["developers.name", "developers.salary", "developers.id", "developers.created_at", "developers.updated_at", "developers.created_on", "developers.updated_on"]).to_a end def test_find_symbol_ordered_last - last = Developer.all.merge!(:order => :salary).last - assert_equal last, Developer.all.merge!(:order => :salary).to_a.last + last = Developer.all.merge!(order: :salary).last + assert_equal last, Developer.all.merge!(order: :salary).to_a.last end def test_abstract_class_table_name @@ -1218,7 +1216,7 @@ class BasicsTest < ActiveRecord::TestCase old_class = LooseDescendant Object.send :remove_const, :LooseDescendant - descendant = old_class.create! :first_name => 'bob' + descendant = old_class.create! first_name: "bob" assert_not_nil LoosePerson.find(descendant.id), "Should have found instance of LooseDescendant when finding abstract LoosePerson: #{descendant.inspect}" ensure unless Object.const_defined?(:LooseDescendant) @@ -1227,7 +1225,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_assert_queries - query = lambda { ActiveRecord::Base.connection.execute 'select count(*) from developers' } + query = lambda { ActiveRecord::Base.connection.execute "select count(*) from developers" } assert_queries(2) { 2.times { query.call } } assert_queries 1, &query assert_no_queries { assert true } @@ -1238,9 +1236,9 @@ class BasicsTest < ActiveRecord::TestCase log = StringIO.new ActiveRecord::Base.logger = ActiveSupport::Logger.new(log) ActiveRecord::Base.logger.level = Logger::WARN - ActiveRecord::Base.benchmark("Debug Topic Count", :level => :debug) { Topic.count } - ActiveRecord::Base.benchmark("Warn Topic Count", :level => :warn) { Topic.count } - ActiveRecord::Base.benchmark("Error Topic Count", :level => :error) { Topic.count } + ActiveRecord::Base.benchmark("Debug Topic Count", level: :debug) { Topic.count } + ActiveRecord::Base.benchmark("Warn Topic Count", level: :warn) { Topic.count } + ActiveRecord::Base.benchmark("Error Topic Count", level: :error) { Topic.count } assert_no_match(/Debug Topic Count/, log.string) assert_match(/Warn Topic Count/, log.string) assert_match(/Error Topic Count/, log.string) @@ -1253,7 +1251,7 @@ class BasicsTest < ActiveRecord::TestCase log = StringIO.new ActiveRecord::Base.logger = ActiveSupport::Logger.new(log) ActiveRecord::Base.logger.level = Logger::DEBUG - ActiveRecord::Base.benchmark("Logging", :level => :debug, :silence => false) { ActiveRecord::Base.logger.debug "Quiet" } + ActiveRecord::Base.benchmark("Logging", level: :debug, silence: false) { ActiveRecord::Base.logger.debug "Quiet" } assert_match(/Quiet/, log.string) ensure ActiveRecord::Base.logger = original_logger @@ -1261,9 +1259,9 @@ class BasicsTest < ActiveRecord::TestCase def test_clear_cache! # preheat cache - c1 = Post.connection.schema_cache.columns('posts') + c1 = Post.connection.schema_cache.columns("posts") ActiveRecord::Base.clear_cache! - c2 = Post.connection.schema_cache.columns('posts') + c2 = Post.connection.schema_cache.columns("posts") c1.each_with_index do |v, i| assert_not_same v, c2[i] end @@ -1280,7 +1278,7 @@ class BasicsTest < ActiveRecord::TestCase ActiveSupport::Dependencies.remove_unloadable_constants! assert_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, klass) ensure - Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost) + Object.class_eval { remove_const :UnloadablePost } if defined?(UnloadablePost) end def test_marshal_round_trip @@ -1354,11 +1352,11 @@ class BasicsTest < ActiveRecord::TestCase end def test_has_attribute - assert Company.has_attribute?('id') - assert Company.has_attribute?('type') - assert Company.has_attribute?('name') - assert_not Company.has_attribute?('lastname') - assert_not Company.has_attribute?('age') + assert Company.has_attribute?("id") + assert Company.has_attribute?("type") + assert Company.has_attribute?("name") + assert_not Company.has_attribute?("lastname") + assert_not Company.has_attribute?("age") end def test_has_attribute_with_symbol @@ -1375,7 +1373,7 @@ class BasicsTest < ActiveRecord::TestCase end def test_touch_should_raise_error_on_a_new_object - company = Company.new(:rating => 1, :name => "37signals", :firm_name => "37signals") + company = Company.new(rating: 1, name: "37signals", firm_name: "37signals") assert_raises(ActiveRecord::ActiveRecordError) do company.touch :updated_at end @@ -1397,37 +1395,37 @@ class BasicsTest < ActiveRecord::TestCase def test_column_types_typecast topic = Topic.first - assert_not_equal 't.lo', topic.author_name + assert_not_equal "t.lo", topic.author_name attrs = topic.attributes.dup - attrs.delete 'id' + attrs.delete "id" typecast = Class.new(ActiveRecord::Type::Value) { - def cast value + def cast(value) "t.lo" end } - types = { 'author_name' => typecast.new } + types = { "author_name" => typecast.new } topic = Topic.instantiate(attrs, types) - assert_equal 't.lo', topic.author_name + assert_equal "t.lo", topic.author_name end def test_typecasting_aliases - assert_equal 10, Topic.select('10 as tenderlove').first.tenderlove + assert_equal 10, Topic.select("10 as tenderlove").first.tenderlove end def test_slice - company = Company.new(:rating => 1, :name => "37signals", :firm_name => "37signals") + company = Company.new(rating: 1, name: "37signals", firm_name: "37signals") hash = company.slice(:name, :rating, "arbitrary_method") assert_equal hash[:name], company.name - assert_equal hash['name'], company.name + assert_equal hash["name"], company.name assert_equal hash[:rating], company.rating - assert_equal hash['arbitrary_method'], company.arbitrary_method + assert_equal hash["arbitrary_method"], company.arbitrary_method assert_equal hash[:arbitrary_method], company.arbitrary_method assert_nil hash[:firm_name] - assert_nil hash['firm_name'] + assert_nil hash["firm_name"] end def test_default_values_are_deeply_dupped @@ -1438,7 +1436,7 @@ class BasicsTest < ActiveRecord::TestCase test "scoped can take a values hash" do klass = Class.new(ActiveRecord::Base) - assert_equal ['foo'], klass.all.merge!(select: 'foo').select_values + assert_equal ["foo"], klass.all.merge!(select: "foo").select_values end test "connection_handler can be overridden" do @@ -1504,6 +1502,10 @@ class BasicsTest < ActiveRecord::TestCase assert_not_equal Post.new.hash, Post.new.hash end + test "records of different classes have different hashes" do + assert_not_equal Post.new(id: 1).hash, Developer.new(id: 1).hash + end + test "resetting column information doesn't remove attribute methods" do topic = topics(:first) @@ -1516,8 +1518,8 @@ class BasicsTest < ActiveRecord::TestCase test "ignored columns are not present in columns_hash" do cache_columns = Developer.connection.schema_cache.columns_hash(Developer.table_name) - assert_includes cache_columns.keys, 'first_name' - refute_includes Developer.columns_hash.keys, 'first_name' + assert_includes cache_columns.keys, "first_name" + assert_not_includes Developer.columns_hash.keys, "first_name" end test "ignored columns have no attribute methods" do diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 91ff5146fd..f7e21faf0f 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -1,6 +1,6 @@ -require 'cases/helper' -require 'models/post' -require 'models/subscriber' +require "cases/helper" +require "models/post" +require "models/subscriber" class EachTest < ActiveRecord::TestCase fixtures :posts, :subscribers @@ -8,12 +8,12 @@ class EachTest < ActiveRecord::TestCase def setup @posts = Post.order("id asc") @total = Post.count - Post.count('id') # preheat arel's table cache + Post.count("id") # preheat arel's table cache end def test_each_should_execute_one_query_per_batch assert_queries(@total + 1) do - Post.find_each(:batch_size => 1) do |post| + Post.find_each(batch_size: 1) do |post| assert_kind_of Post, post end end @@ -21,14 +21,14 @@ class EachTest < ActiveRecord::TestCase def test_each_should_not_return_query_chain_and_execute_only_one_query assert_queries(1) do - result = Post.find_each(:batch_size => 100000){ } + result = Post.find_each(batch_size: 100000) {} assert_nil result end end def test_each_should_return_an_enumerator_if_no_block_is_present assert_queries(1) do - Post.find_each(:batch_size => 100000).with_index do |post, index| + Post.find_each(batch_size: 100000).with_index do |post, index| assert_kind_of Post, post assert_kind_of Integer, index end @@ -45,7 +45,7 @@ class EachTest < ActiveRecord::TestCase def test_each_enumerator_should_execute_one_query_per_batch assert_queries(@total + 1) do - Post.find_each(:batch_size => 1).with_index do |post, index| + Post.find_each(batch_size: 1).with_index do |post, index| assert_kind_of Post, post assert_kind_of Integer, index end @@ -62,16 +62,32 @@ class EachTest < ActiveRecord::TestCase def test_each_should_execute_if_id_is_in_select assert_queries(6) do - Post.select("id, title, type").find_each(:batch_size => 2) do |post| + Post.select("id, title, type").find_each(batch_size: 2) do |post| assert_kind_of Post, post end end end - def test_warn_if_limit_scope_is_set - assert_called(ActiveRecord::Base.logger, :warn) do - Post.limit(1).find_each { |post| post } + test "find_each should honor limit if passed a block" do + limit = @total - 1 + total = 0 + + Post.limit(limit).find_each do |post| + total += 1 + end + + assert_equal limit, total + end + + test "find_each should honor limit if no block is passed" do + limit = @total - 1 + total = 0 + + Post.limit(limit).find_each.each do |post| + total += 1 end + + assert_equal limit, total end def test_warn_if_order_scope_is_set @@ -84,7 +100,7 @@ class EachTest < ActiveRecord::TestCase previous_logger = ActiveRecord::Base.logger ActiveRecord::Base.logger = nil assert_nothing_raised do - Post.limit(1).find_each { |post| post } + Post.order("comments_count DESC").find_each { |post| post } end ensure ActiveRecord::Base.logger = previous_logger @@ -92,7 +108,7 @@ class EachTest < ActiveRecord::TestCase def test_find_in_batches_should_return_batches assert_queries(@total + 1) do - Post.find_in_batches(:batch_size => 1) do |batch| + Post.find_in_batches(batch_size: 1) do |batch| assert_kind_of Array, batch assert_kind_of Post, batch.first end @@ -119,18 +135,18 @@ class EachTest < ActiveRecord::TestCase def test_find_in_batches_shouldnt_execute_query_unless_needed assert_queries(2) do - Post.find_in_batches(:batch_size => @total) {|batch| assert_kind_of Array, batch } + Post.find_in_batches(batch_size: @total) { |batch| assert_kind_of Array, batch } end assert_queries(1) do - Post.find_in_batches(:batch_size => @total + 1) {|batch| assert_kind_of Array, batch } + Post.find_in_batches(batch_size: @total + 1) { |batch| assert_kind_of Array, batch } end end def test_find_in_batches_should_quote_batch_order c = Post.connection assert_sql(/ORDER BY #{c.quote_table_name('posts')}.#{c.quote_column_name('id')}/) do - Post.find_in_batches(:batch_size => 1) do |batch| + Post.find_in_batches(batch_size: 1) do |batch| assert_kind_of Array, batch assert_kind_of Post, batch.first end @@ -140,9 +156,9 @@ class EachTest < ActiveRecord::TestCase def test_find_in_batches_should_not_use_records_after_yielding_them_in_case_original_array_is_modified not_a_post = "not a post" def not_a_post.id; end - not_a_post.stub(:id, ->{ raise StandardError.new("not_a_post had #id called on it") }) do + not_a_post.stub(:id, -> { raise StandardError.new("not_a_post had #id called on it") }) do assert_nothing_raised do - Post.find_in_batches(:batch_size => 1) do |batch| + Post.find_in_batches(batch_size: 1) do |batch| assert_kind_of Array, batch assert_kind_of Post, batch.first @@ -166,37 +182,37 @@ class EachTest < ActiveRecord::TestCase def test_find_in_batches_should_error_on_ignore_the_order assert_raise(ArgumentError) do - PostWithDefaultScope.find_in_batches(error_on_ignore: true){} + PostWithDefaultScope.find_in_batches(error_on_ignore: true) {} end end - def test_find_in_batches_should_not_error_if_config_overriden - # Set the config option which will be overriden - prev = ActiveRecord::Base.error_on_ignored_order_or_limit - ActiveRecord::Base.error_on_ignored_order_or_limit = true + def test_find_in_batches_should_not_error_if_config_overridden + # Set the config option which will be overridden + prev = ActiveRecord::Base.error_on_ignored_order + ActiveRecord::Base.error_on_ignored_order = true assert_nothing_raised do - PostWithDefaultScope.find_in_batches(error_on_ignore: false){} + PostWithDefaultScope.find_in_batches(error_on_ignore: false) {} end ensure # Set back to default - ActiveRecord::Base.error_on_ignored_order_or_limit = prev + ActiveRecord::Base.error_on_ignored_order = prev end def test_find_in_batches_should_error_on_config_specified_to_error # Set the config option - prev = ActiveRecord::Base.error_on_ignored_order_or_limit - ActiveRecord::Base.error_on_ignored_order_or_limit = true + prev = ActiveRecord::Base.error_on_ignored_order + ActiveRecord::Base.error_on_ignored_order = true assert_raise(ArgumentError) do - PostWithDefaultScope.find_in_batches(){} + PostWithDefaultScope.find_in_batches() {} end ensure # Set back to default - ActiveRecord::Base.error_on_ignored_order_or_limit = prev + ActiveRecord::Base.error_on_ignored_order = prev end def test_find_in_batches_should_not_error_by_default assert_nothing_raised do - PostWithDefaultScope.find_in_batches(){} + PostWithDefaultScope.find_in_batches() {} end end @@ -211,12 +227,12 @@ class EachTest < ActiveRecord::TestCase def test_find_in_batches_should_not_modify_passed_options assert_nothing_raised do - Post.find_in_batches({ batch_size: 42, start: 1 }.freeze){} + Post.find_in_batches({ batch_size: 42, start: 1 }.freeze) {} end end def test_find_in_batches_should_use_any_column_as_primary_key - nick_order_subscribers = Subscriber.order('nick asc') + nick_order_subscribers = Subscriber.order("nick asc") start_nick = nick_order_subscribers.second.nick subscribers = [] @@ -239,7 +255,7 @@ class EachTest < ActiveRecord::TestCase def test_find_in_batches_should_return_an_enumerator enum = nil assert_no_queries do - enum = Post.find_in_batches(:batch_size => 1) + enum = Post.find_in_batches(batch_size: 1) end assert_queries(4) do enum.first(4) do |batch| @@ -249,6 +265,28 @@ class EachTest < ActiveRecord::TestCase end end + test "find_in_batches should honor limit if passed a block" do + limit = @total - 1 + total = 0 + + Post.limit(limit).find_in_batches do |batch| + total += batch.size + end + + assert_equal limit, total + end + + test "find_in_batches should honor limit if no block is passed" do + limit = @total - 1 + total = 0 + + Post.limit(limit).find_in_batches.each do |batch| + total += batch.size + end + + assert_equal limit, total + end + def test_in_batches_should_not_execute_any_query assert_no_queries do assert_kind_of ActiveRecord::Batches::BatchEnumerator, Post.in_batches(of: 2) @@ -290,7 +328,7 @@ class EachTest < ActiveRecord::TestCase end def test_in_batches_each_record_should_be_ordered_by_id - ids = Post.order('id ASC').pluck(:id) + ids = Post.order("id ASC").pluck(:id) assert_queries(6) do Post.in_batches(of: 2).each_record.with_index do |post, i| assert_equal ids[i], post.id @@ -306,9 +344,9 @@ class EachTest < ActiveRecord::TestCase end def test_in_batches_delete_all_should_not_delete_records_in_other_batches - not_deleted_count = Post.where('id <= 2').count - Post.where('id > 2').in_batches(of: 2).delete_all - assert_equal 0, Post.where('id > 2').count + not_deleted_count = Post.where("id <= 2").count + Post.where("id > 2").in_batches(of: 2).delete_all + assert_equal 0, Post.where("id > 2").count assert_equal not_deleted_count, Post.count end @@ -345,7 +383,7 @@ class EachTest < ActiveRecord::TestCase end def test_in_batches_should_start_from_the_start_option - post = Post.order('id ASC').where('id >= ?', 2).first + post = Post.order("id ASC").where("id >= ?", 2).first assert_queries(2) do relation = Post.in_batches(of: 1, start: 2).first assert_equal post, relation.first @@ -353,7 +391,7 @@ class EachTest < ActiveRecord::TestCase end def test_in_batches_should_end_at_the_finish_option - post = Post.order('id DESC').where('id <= ?', 5).first + post = Post.order("id DESC").where("id <= ?", 5).first assert_queries(7) do relation = Post.in_batches(of: 1, finish: 5, load: true).reverse_each.first assert_equal post, relation.last @@ -407,12 +445,12 @@ class EachTest < ActiveRecord::TestCase def test_in_batches_should_not_modify_passed_options assert_nothing_raised do - Post.in_batches({ of: 42, start: 1 }.freeze){} + Post.in_batches({ of: 42, start: 1 }.freeze) {} end end def test_in_batches_should_use_any_column_as_primary_key - nick_order_subscribers = Subscriber.order('nick asc') + nick_order_subscribers = Subscriber.order("nick asc") start_nick = nick_order_subscribers.second.nick subscribers = [] @@ -472,18 +510,108 @@ class EachTest < ActiveRecord::TestCase person.update_attributes(author_id: 1) Post.in_batches(of: 2) do |batch| - batch.where('author_id >= 1').update_all('author_id = author_id + 1') + batch.where("author_id >= 1").update_all("author_id = author_id + 1") end assert_equal 2, person.reload.author_id # incremented only once end if Enumerator.method_defined? :size def test_find_in_batches_should_return_a_sized_enumerator - assert_equal 11, Post.find_in_batches(:batch_size => 1).size - assert_equal 6, Post.find_in_batches(:batch_size => 2).size + assert_equal 11, Post.find_in_batches(batch_size: 1).size + assert_equal 6, Post.find_in_batches(batch_size: 2).size assert_equal 4, Post.find_in_batches(batch_size: 2, start: 4).size - assert_equal 4, Post.find_in_batches(:batch_size => 3).size - assert_equal 1, Post.find_in_batches(:batch_size => 10_000).size + assert_equal 4, Post.find_in_batches(batch_size: 3).size + assert_equal 1, Post.find_in_batches(batch_size: 10_000).size + end + end + + [true, false].each do |load| + test "in_batches should return limit records when limit is less than batch size and load is #{load}" do + limit = 3 + batch_size = 5 + total = 0 + + Post.limit(limit).in_batches(of: batch_size, load: load) do |batch| + total += batch.count + end + + assert_equal limit, total + end + + test "in_batches should return limit records when limit is greater than batch size and load is #{load}" do + limit = 5 + batch_size = 3 + total = 0 + + Post.limit(limit).in_batches(of: batch_size, load: load) do |batch| + total += batch.count + end + + assert_equal limit, total + end + + test "in_batches should return limit records when limit is a multiple of the batch size and load is #{load}" do + limit = 6 + batch_size = 3 + total = 0 + + Post.limit(limit).in_batches(of: batch_size, load: load) do |batch| + total += batch.count + end + + assert_equal limit, total + end + + test "in_batches should return no records if the limit is 0 and load is #{load}" do + limit = 0 + batch_size = 1 + total = 0 + + Post.limit(limit).in_batches(of: batch_size, load: load) do |batch| + total += batch.count + end + + assert_equal limit, total + end + + test "in_batches should return all if the limit is greater than the number of records when load is #{load}" do + limit = @total + 1 + batch_size = 1 + total = 0 + + Post.limit(limit).in_batches(of: batch_size, load: load) do |batch| + total += batch.count + end + + assert_equal @total, total + end + end + + test ".error_on_ignored_order_or_limit= is deprecated" do + begin + prev = ActiveRecord::Base.error_on_ignored_order + assert_deprecated "Please use error_on_ignored_order= instead." do + ActiveRecord::Base.error_on_ignored_order_or_limit = true + end + assert ActiveRecord::Base.error_on_ignored_order + ensure + ActiveRecord::Base.error_on_ignored_order = prev + end + end + + test ".error_on_ignored_order_or_limit is deprecated" do + expected = ActiveRecord::Base.error_on_ignored_order + actual = assert_deprecated "Please use error_on_ignored_order instead." do + ActiveRecord::Base.error_on_ignored_order_or_limit + end + assert_equal expected, actual + end + + test "#error_on_ignored_order_or_limit is deprecated" do + expected = ActiveRecord::Base.error_on_ignored_order + actual = assert_deprecated "Please use error_on_ignored_order instead." do + Post.new.error_on_ignored_order_or_limit end + assert_equal expected, actual end end diff --git a/activerecord/test/cases/binary_test.rb b/activerecord/test/cases/binary_test.rb index 9eb5352150..1fc30e24d2 100644 --- a/activerecord/test/cases/binary_test.rb +++ b/activerecord/test/cases/binary_test.rb @@ -4,23 +4,23 @@ require "cases/helper" # BLOB data with DB2, because the length of a statement # is limited to 32KB. unless current_adapter?(:DB2Adapter) - require 'models/binary' + require "models/binary" class BinaryTest < ActiveRecord::TestCase FIXTURES = %w(flowers.jpg example.log test.txt) def test_mixed_encoding str = "\x80" - str.force_encoding('ASCII-8BIT') + str.force_encoding("ASCII-8BIT") - binary = Binary.new :name => 'いただきます!', :data => str + binary = Binary.new name: "いただきます!", data: str binary.save! binary.reload assert_equal str, binary.data name = binary.name - assert_equal 'いただきます!', name + assert_equal "いただきます!", name end def test_load_save @@ -28,16 +28,16 @@ unless current_adapter?(:DB2Adapter) FIXTURES.each do |filename| data = File.read(ASSETS_ROOT + "/#{filename}") - data.force_encoding('ASCII-8BIT') + data.force_encoding("ASCII-8BIT") data.freeze - bin = Binary.new(:data => data) - assert_equal data, bin.data, 'Newly assigned data differs from original' + bin = Binary.new(data: data) + assert_equal data, bin.data, "Newly assigned data differs from original" bin.save! - assert_equal data, bin.data, 'Data differs from original after save' + assert_equal data, bin.data, "Data differs from original after save" - assert_equal data, bin.reload.data, 'Reloaded data differs from original' + assert_equal data, bin.reload.data, "Reloaded data differs from original" end end end diff --git a/activerecord/test/cases/bind_parameter_test.rb b/activerecord/test/cases/bind_parameter_test.rb index fa924fe4cb..98d202dd79 100644 --- a/activerecord/test/cases/bind_parameter_test.rb +++ b/activerecord/test/cases/bind_parameter_test.rb @@ -1,7 +1,7 @@ -require 'cases/helper' -require 'models/topic' -require 'models/author' -require 'models/post' +require "cases/helper" +require "models/topic" +require "models/author" +require "models/post" module ActiveRecord class BindParameterTest < ActiveRecord::TestCase @@ -24,7 +24,7 @@ module ActiveRecord @connection = ActiveRecord::Base.connection @subscriber = LogListener.new @pk = Topic.columns_hash[Topic.primary_key] - @subscription = ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber) + @subscription = ActiveSupport::Notifications.subscribe("sql.active_record", @subscriber) end teardown do @@ -34,8 +34,8 @@ module ActiveRecord if ActiveRecord::Base.connection.supports_statement_cache? && ActiveRecord::Base.connection.prepared_statements def test_bind_from_join_in_subquery - subquery = Author.joins(:thinking_posts).where(name: 'David') - scope = Author.from(subquery, 'authors').where(id: 1) + subquery = Author.joins(:thinking_posts).where(name: "David") + scope = Author.from(subquery, "authors").where(id: 1) assert_equal 1, scope.count end @@ -44,7 +44,7 @@ module ActiveRecord binds = [Relation::QueryAttribute.new("id", 1, Type::Value.new)] sql = "select * from topics where id = #{sub.to_sql}" - @connection.exec_query(sql, 'SQL', binds) + @connection.exec_query(sql, "SQL", binds) message = @subscriber.calls.find { |args| args[4][:sql] == sql } assert_equal binds, message[4][:binds] @@ -53,17 +53,20 @@ module ActiveRecord def test_find_one_uses_binds Topic.find(1) message = @subscriber.calls.find { |args| args[4][:binds].any? { |attr| attr.value == 1 } } - assert message, 'expected a message with binds' + assert message, "expected a message with binds" end def test_logs_bind_vars_after_type_cast + binds = [Relation::QueryAttribute.new("id", "10", Type::Integer.new)] + type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) } payload = { - :name => 'SQL', - :sql => 'select * from topics where id = ?', - :binds => [Relation::QueryAttribute.new("id", "10", Type::Integer.new)] + name: "SQL", + sql: "select * from topics where id = ?", + binds: binds, + type_casted_binds: type_casted_binds } event = ActiveSupport::Notifications::Event.new( - 'foo', + "foo", Time.now, Time.now, 123, @@ -76,7 +79,7 @@ module ActiveRecord @debugs = [] end - def debug str + def debug(str) @debugs << str end }.new @@ -84,6 +87,12 @@ module ActiveRecord logger.sql event assert_match([[@pk.name, 10]].inspect, logger.debugs.first) end + + private + + def type_cast(value) + ActiveRecord::Base.connection.type_cast(value) + end end end end diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 8f2682c781..db2871d383 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -1,23 +1,24 @@ require "cases/helper" -require 'models/club' -require 'models/company' +require "models/book" +require "models/club" +require "models/company" require "models/contract" -require 'models/edge' -require 'models/organization' -require 'models/possession' -require 'models/topic' -require 'models/reply' -require 'models/minivan' -require 'models/speedometer' -require 'models/ship_part' -require 'models/treasure' -require 'models/developer' -require 'models/comment' -require 'models/rating' -require 'models/post' +require "models/edge" +require "models/organization" +require "models/possession" +require "models/topic" +require "models/reply" +require "models/minivan" +require "models/speedometer" +require "models/ship_part" +require "models/treasure" +require "models/developer" +require "models/comment" +require "models/rating" +require "models/post" class NumericData < ActiveRecord::Base - self.table_name = 'numeric_data' + self.table_name = "numeric_data" attribute :world_population, :integer attribute :my_house_population, :integer @@ -25,7 +26,7 @@ class NumericData < ActiveRecord::Base end class CalculationsTest < ActiveRecord::TestCase - fixtures :companies, :accounts, :topics, :speedometers, :minivans + fixtures :companies, :accounts, :topics, :speedometers, :minivans, :books def test_should_sum_field assert_equal 318, Account.sum(:credit_limit) @@ -56,7 +57,7 @@ class CalculationsTest < ActiveRecord::TestCase def test_should_return_integer_average_if_db_returns_such ShipPart.delete_all - ShipPart.create!(:id => 3, :name => 'foo') + ShipPart.create!(id: 3, name: "foo") value = ShipPart.average(:id) assert_equal 3, value end @@ -92,24 +93,24 @@ class CalculationsTest < ActiveRecord::TestCase def test_should_group_by_field c = Account.group(:firm_id).sum(:credit_limit) [1,6,2].each do |firm_id| - assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}" + assert_includes c.keys, firm_id, "Group #{c.inspect} does not contain firm_id #{firm_id}" end end def test_should_group_by_arel_attribute c = Account.group(Account.arel_table[:firm_id]).sum(:credit_limit) [1,6,2].each do |firm_id| - assert c.keys.include?(firm_id), "Group #{c.inspect} does not contain firm_id #{firm_id}" + assert_includes c.keys, firm_id, "Group #{c.inspect} does not contain firm_id #{firm_id}" end end def test_should_group_by_multiple_fields - c = Account.group('firm_id', :credit_limit).count(:all) - [ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert c.keys.include?(firm_and_limit) } + c = Account.group("firm_id", :credit_limit).count(:all) + [ [nil, 50], [1, 50], [6, 50], [6, 55], [9, 53], [2, 60] ].each { |firm_and_limit| assert_includes c.keys, firm_and_limit } end def test_should_group_by_multiple_fields_having_functions - c = Topic.group(:author_name, 'COALESCE(type, title)').count(:all) + c = Topic.group(:author_name, "COALESCE(type, title)").count(:all) assert_equal 1, c[["Carl", "The Third Topic of the day"]] assert_equal 1, c[["Mary", "Reply"]] assert_equal 1, c[["David", "The First Topic"]] @@ -165,14 +166,14 @@ class CalculationsTest < ActiveRecord::TestCase end def test_limit_should_apply_before_count - accounts = Account.limit(3).where('firm_id IS NOT NULL') + accounts = Account.limit(3).where("firm_id IS NOT NULL") assert_equal 3, accounts.count(:firm_id) assert_equal 3, accounts.select(:firm_id).count end def test_limit_should_apply_before_count_arel_attribute - accounts = Account.limit(3).where('firm_id IS NOT NULL') + accounts = Account.limit(3).where("firm_id IS NOT NULL") firm_id_attribute = Account.arel_table[:firm_id] assert_equal 3, accounts.count(firm_id_attribute) @@ -227,7 +228,7 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_group_by_summed_field_having_condition - c = Account.group(:firm_id).having('sum(credit_limit) > 50').sum(:credit_limit) + c = Account.group(:firm_id).having("sum(credit_limit) > 50").sum(:credit_limit) assert_nil c[1] assert_equal 105, c[6] assert_equal 60, c[2] @@ -248,52 +249,52 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_sum_field_with_conditions - assert_equal 105, Account.where('firm_id = 6').sum(:credit_limit) + assert_equal 105, Account.where("firm_id = 6").sum(:credit_limit) end def test_should_return_zero_if_sum_conditions_return_nothing - assert_equal 0, Account.where('1 = 2').sum(:credit_limit) - assert_equal 0, companies(:rails_core).companies.where('1 = 2').sum(:id) + assert_equal 0, Account.where("1 = 2").sum(:credit_limit) + assert_equal 0, companies(:rails_core).companies.where("1 = 2").sum(:id) end def test_sum_should_return_valid_values_for_decimals - NumericData.create(:bank_balance => 19.83) + NumericData.create(bank_balance: 19.83) assert_equal 19.83, NumericData.sum(:bank_balance) end def test_should_return_type_casted_values_with_group_and_expression - assert_equal 0.5, Account.group(:firm_name).sum('0.01 * credit_limit')['37signals'] + assert_equal 0.5, Account.group(:firm_name).sum("0.01 * credit_limit")["37signals"] end def test_should_group_by_summed_field_with_conditions - c = Account.where('firm_id > 1').group(:firm_id).sum(:credit_limit) + c = Account.where("firm_id > 1").group(:firm_id).sum(:credit_limit) assert_nil c[1] assert_equal 105, c[6] assert_equal 60, c[2] end def test_should_group_by_summed_field_with_conditions_and_having - c = Account.where('firm_id > 1').group(:firm_id). - having('sum(credit_limit) > 60').sum(:credit_limit) + c = Account.where("firm_id > 1").group(:firm_id). + having("sum(credit_limit) > 60").sum(:credit_limit) assert_nil c[1] assert_equal 105, c[6] assert_nil c[2] end def test_should_group_by_fields_with_table_alias - c = Account.group('accounts.firm_id').sum(:credit_limit) + c = Account.group("accounts.firm_id").sum(:credit_limit) assert_equal 50, c[1] assert_equal 105, c[6] assert_equal 60, c[2] end def test_should_calculate_with_invalid_field - assert_equal 6, Account.calculate(:count, '*') + assert_equal 6, Account.calculate(:count, "*") assert_equal 6, Account.calculate(:count, :all) end def test_should_calculate_grouped_with_invalid_field - c = Account.group('accounts.firm_id').count(:all) + c = Account.group("accounts.firm_id").count(:all) assert_equal 1, c[1] assert_equal 2, c[6] assert_equal 1, c[2] @@ -307,8 +308,8 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_group_by_association_with_non_numeric_foreign_key - Speedometer.create! id: 'ABC' - Minivan.create! id: 'OMG', speedometer_id: 'ABC' + Speedometer.create! id: "ABC" + Minivan.create! id: "OMG", speedometer_id: "ABC" c = Minivan.group(:speedometer).count(:all) first_key = c.keys.first @@ -317,7 +318,7 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_calculate_grouped_association_with_foreign_key_option - Account.belongs_to :another_firm, :class_name => 'Firm', :foreign_key => 'firm_id' + Account.belongs_to :another_firm, class_name: "Firm", foreign_key: "firm_id" c = Account.group(:another_firm).count(:all) assert_equal 1, c[companies(:first_firm)] assert_equal 2, c[companies(:rails_core)] @@ -327,17 +328,17 @@ class CalculationsTest < ActiveRecord::TestCase def test_should_calculate_grouped_by_function c = Company.group("UPPER(#{QUOTED_TYPE})").count(:all) assert_equal 2, c[nil] - assert_equal 1, c['DEPENDENTFIRM'] - assert_equal 5, c['CLIENT'] - assert_equal 2, c['FIRM'] + assert_equal 1, c["DEPENDENTFIRM"] + assert_equal 5, c["CLIENT"] + assert_equal 2, c["FIRM"] end def test_should_calculate_grouped_by_function_with_table_alias c = Company.group("UPPER(companies.#{QUOTED_TYPE})").count(:all) assert_equal 2, c[nil] - assert_equal 1, c['DEPENDENTFIRM'] - assert_equal 5, c['CLIENT'] - assert_equal 2, c['FIRM'] + assert_equal 1, c["DEPENDENTFIRM"] + assert_equal 5, c["CLIENT"] + assert_equal 2, c["FIRM"] end def test_should_not_overshadow_enumerable_sum @@ -353,19 +354,19 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_sum_scoped_field_with_conditions - assert_equal 8, companies(:rails_core).companies.where('id > 7').sum(:id) + assert_equal 8, companies(:rails_core).companies.where("id > 7").sum(:id) end def test_should_group_by_scoped_field c = companies(:rails_core).companies.group(:name).sum(:id) - assert_equal 7, c['Leetsoft'] - assert_equal 8, c['Jadedpixel'] + assert_equal 7, c["Leetsoft"] + assert_equal 8, c["Jadedpixel"] end def test_should_group_by_summed_field_through_association_and_having - c = companies(:rails_core).companies.group(:name).having('sum(id) > 7').sum(:id) - assert_nil c['Leetsoft'] - assert_equal 8, c['Jadedpixel'] + c = companies(:rails_core).companies.group(:name).having("sum(id) > 7").sum(:id) + assert_nil c["Leetsoft"] + assert_equal 8, c["Jadedpixel"] end def test_should_count_selected_field_with_include @@ -380,7 +381,7 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_perform_joined_include_when_referencing_included_tables - joined_count = Account.includes(:firm).where(:companies => {:name => '37signals'}).count + joined_count = Account.includes(:firm).where(companies: { name: "37signals" }).count assert_equal 1, joined_count end @@ -391,10 +392,10 @@ class CalculationsTest < ActiveRecord::TestCase def test_should_count_scoped_select_with_options Account.update_all("credit_limit = NULL") - Account.last.update_columns('credit_limit' => 49) - Account.first.update_columns('credit_limit' => 51) + Account.last.update_columns("credit_limit" => 49) + Account.first.update_columns("credit_limit" => 51) - assert_equal 1, Account.select("credit_limit").where('credit_limit >= 50').count + assert_equal 1, Account.select("credit_limit").where("credit_limit >= 50").count end def test_should_count_manual_select_with_include @@ -435,8 +436,8 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_count_field_in_joined_table - assert_equal 5, Account.joins(:firm).count('companies.id') - assert_equal 4, Account.joins(:firm).distinct.count('companies.id') + assert_equal 5, Account.joins(:firm).count("companies.id") + assert_equal 4, Account.joins(:firm).distinct.count("companies.id") end def test_count_arel_attribute_in_joined_table_with @@ -450,14 +451,14 @@ class CalculationsTest < ActiveRecord::TestCase end def test_should_count_field_in_joined_table_with_group_by - c = Account.group('accounts.firm_id').joins(:firm).count('companies.id') + c = Account.group("accounts.firm_id").joins(:firm).count("companies.id") - [1,6,2,9].each { |firm_id| assert c.keys.include?(firm_id) } + [1,6,2,9].each { |firm_id| assert_includes c.keys, firm_id } end def test_should_count_field_of_root_table_with_conflicting_group_by_column assert_equal({ 1 => 1 }, Firm.joins(:accounts).group(:firm_id).count) - assert_equal({ 1 => 1 }, Firm.joins(:accounts).group('accounts.firm_id').count) + assert_equal({ 1 => 1 }, Firm.joins(:accounts).group("accounts.firm_id").count) end def test_count_with_no_parameters_isnt_deprecated @@ -477,9 +478,13 @@ class CalculationsTest < ActiveRecord::TestCase end def test_count_with_where_and_order - assert_equal 1, Account.where(firm_name: '37signals').count - assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).count - assert_equal 1, Account.where(firm_name: '37signals').order(:firm_name).reverse_order.count + assert_equal 1, Account.where(firm_name: "37signals").count + assert_equal 1, Account.where(firm_name: "37signals").order(:firm_name).count + assert_equal 1, Account.where(firm_name: "37signals").order(:firm_name).reverse_order.count + end + + def test_count_with_block + assert_equal 4, Account.count { |account| account.credit_limit.modulo(10).zero? } end def test_should_sum_expression @@ -492,69 +497,69 @@ class CalculationsTest < ActiveRecord::TestCase end def test_sum_expression_returns_zero_when_no_records_to_sum - assert_equal 0, Account.where('1 = 2').sum("2 * credit_limit") + assert_equal 0, Account.where("1 = 2").sum("2 * credit_limit") end def test_count_with_from_option - assert_equal Company.count(:all), Company.from('companies').count(:all) + assert_equal Company.count(:all), Company.from("companies").count(:all) assert_equal Account.where("credit_limit = 50").count(:all), - Account.from('accounts').where("credit_limit = 50").count(:all) - assert_equal Company.where(:type => "Firm").count(:type), - Company.where(:type => "Firm").from('companies').count(:type) + Account.from("accounts").where("credit_limit = 50").count(:all) + assert_equal Company.where(type: "Firm").count(:type), + Company.where(type: "Firm").from("companies").count(:type) end def test_sum_with_from_option - assert_equal Account.sum(:credit_limit), Account.from('accounts').sum(:credit_limit) + assert_equal Account.sum(:credit_limit), Account.from("accounts").sum(:credit_limit) assert_equal Account.where("credit_limit > 50").sum(:credit_limit), - Account.where("credit_limit > 50").from('accounts').sum(:credit_limit) + Account.where("credit_limit > 50").from("accounts").sum(:credit_limit) end def test_average_with_from_option - assert_equal Account.average(:credit_limit), Account.from('accounts').average(:credit_limit) + assert_equal Account.average(:credit_limit), Account.from("accounts").average(:credit_limit) assert_equal Account.where("credit_limit > 50").average(:credit_limit), - Account.where("credit_limit > 50").from('accounts').average(:credit_limit) + Account.where("credit_limit > 50").from("accounts").average(:credit_limit) end def test_minimum_with_from_option - assert_equal Account.minimum(:credit_limit), Account.from('accounts').minimum(:credit_limit) + assert_equal Account.minimum(:credit_limit), Account.from("accounts").minimum(:credit_limit) assert_equal Account.where("credit_limit > 50").minimum(:credit_limit), - Account.where("credit_limit > 50").from('accounts').minimum(:credit_limit) + Account.where("credit_limit > 50").from("accounts").minimum(:credit_limit) end def test_maximum_with_from_option - assert_equal Account.maximum(:credit_limit), Account.from('accounts').maximum(:credit_limit) + assert_equal Account.maximum(:credit_limit), Account.from("accounts").maximum(:credit_limit) assert_equal Account.where("credit_limit > 50").maximum(:credit_limit), - Account.where("credit_limit > 50").from('accounts').maximum(:credit_limit) + Account.where("credit_limit > 50").from("accounts").maximum(:credit_limit) end def test_maximum_with_not_auto_table_name_prefix_if_column_included - Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)]) + Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)]) assert_equal 7, Company.includes(:contracts).maximum(:developer_id) end def test_minimum_with_not_auto_table_name_prefix_if_column_included - Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)]) + Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)]) assert_equal 7, Company.includes(:contracts).minimum(:developer_id) end def test_sum_with_not_auto_table_name_prefix_if_column_included - Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)]) + Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)]) assert_equal 7, Company.includes(:contracts).sum(:developer_id) end if current_adapter?(:Mysql2Adapter) def test_from_option_with_specified_index - assert_equal Edge.count(:all), Edge.from('edges USE INDEX(unique_edge_index)').count(:all) - assert_equal Edge.where('sink_id < 5').count(:all), - Edge.from('edges USE INDEX(unique_edge_index)').where('sink_id < 5').count(:all) + assert_equal Edge.count(:all), Edge.from("edges USE INDEX(unique_edge_index)").count(:all) + assert_equal Edge.where("sink_id < 5").count(:all), + Edge.from("edges USE INDEX(unique_edge_index)").where("sink_id < 5").count(:all) end end def test_from_option_with_table_different_than_class - assert_equal Account.count(:all), Company.from('accounts').count(:all) + assert_equal Account.count(:all), Company.from("accounts").count(:all) end def test_distinct_is_honored_when_used_with_count_operation_after_group @@ -577,7 +582,7 @@ class CalculationsTest < ActiveRecord::TestCase def test_pluck_type_cast topic = topics(:first) - relation = Topic.where(:id => topic.id) + relation = Topic.where(id: topic.id) assert_equal [ topic.approved ], relation.pluck(:approved) assert_equal [ topic.last_read ], relation.pluck(:last_read) assert_equal [ topic.written_on ], relation.pluck(:written_on) @@ -594,12 +599,12 @@ class CalculationsTest < ActiveRecord::TestCase end def test_pluck_on_aliased_attribute - assert_equal 'The First Topic', Topic.order(:id).pluck(:heading).first + assert_equal "The First Topic", Topic.order(:id).pluck(:heading).first end def test_pluck_with_serialization - t = Topic.create!(:content => { :foo => :bar }) - assert_equal [{:foo => :bar}], Topic.where(:id => t.id).pluck(:content) + t = Topic.create!(content: { foo: :bar }) + assert_equal [{ foo: :bar }], Topic.where(id: t.id).pluck(:content) end def test_pluck_with_qualified_column_name @@ -607,29 +612,29 @@ class CalculationsTest < ActiveRecord::TestCase end def test_pluck_auto_table_name_prefix - c = Company.create!(:name => "test", :contracts => [Contract.new]) + c = Company.create!(name: "test", contracts: [Contract.new]) assert_equal [c.id], Company.joins(:contracts).pluck(:id) end def test_pluck_if_table_included - c = Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)]) + c = Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)]) assert_equal [c.id], Company.includes(:contracts).where("contracts.id" => c.contracts.first).pluck(:id) end def test_pluck_not_auto_table_name_prefix_if_column_joined - Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)]) + Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)]) assert_equal [7], Company.joins(:contracts).pluck(:developer_id) end def test_pluck_with_selection_clause - assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT credit_limit').sort - assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT accounts.credit_limit').sort - assert_equal [50, 53, 55, 60], Account.pluck('DISTINCT(credit_limit)').sort + assert_equal [50, 53, 55, 60], Account.pluck("DISTINCT credit_limit").sort + assert_equal [50, 53, 55, 60], Account.pluck("DISTINCT accounts.credit_limit").sort + assert_equal [50, 53, 55, 60], Account.pluck("DISTINCT(credit_limit)").sort # MySQL returns "SUM(DISTINCT(credit_limit))" as the column name unless # an alias is provided. Without the alias, the column cannot be found # and properly typecast. - assert_equal [50 + 53 + 55 + 60], Account.pluck('SUM(DISTINCT(credit_limit)) as credit_limit') + assert_equal [50 + 53 + 55 + 60], Account.pluck("SUM(DISTINCT(credit_limit)) as credit_limit") end def test_plucks_with_ids @@ -638,11 +643,11 @@ class CalculationsTest < ActiveRecord::TestCase def test_pluck_with_includes_limit_and_empty_result assert_equal [], Topic.includes(:replies).limit(0).pluck(:id) - assert_equal [], Topic.includes(:replies).limit(1).where('0 = 1').pluck(:id) + assert_equal [], Topic.includes(:replies).limit(1).where("0 = 1").pluck(:id) end def test_pluck_not_auto_table_name_prefix_if_column_included - Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)]) + Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)]) ids = Company.includes(:contracts).pluck(:developer_id) assert_equal Company.count, ids.length assert_equal [7], ids.compact @@ -663,12 +668,12 @@ class CalculationsTest < ActiveRecord::TestCase def test_pluck_with_multiple_columns_and_selection_clause assert_equal [[1, 50], [2, 50], [3, 50], [4, 60], [5, 55], [6, 53]], - Account.pluck('id, credit_limit') + Account.pluck("id, credit_limit") end def test_pluck_with_multiple_columns_and_includes - Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)]) - companies_and_developers = Company.order('companies.id').includes(:contracts).pluck(:name, :developer_id) + Company.create!(name: "test", contracts: [Contract.new(developer_id: 7)]) + companies_and_developers = Company.order("companies.id").includes(:contracts).pluck(:name, :developer_id) assert_equal Company.count, companies_and_developers.length assert_equal ["37signals", nil], companies_and_developers.first @@ -676,7 +681,7 @@ class CalculationsTest < ActiveRecord::TestCase end def test_pluck_with_reserved_words - Possession.create!(:where => "Over There") + Possession.create!(where: "Over There") assert_equal ["Over There"], Possession.pluck(:where) end @@ -690,7 +695,7 @@ class CalculationsTest < ActiveRecord::TestCase def test_pluck_columns_with_same_name expected = [["The First Topic", "The Second Topic of the day"], ["The Third Topic of the day", "The Fourth Topic of the day"]] actual = Topic.joins(:replies) - .pluck('topics.title', 'replies_topics.title') + .pluck("topics.title", "replies_topics.title") assert_equal expected, actual end @@ -711,21 +716,21 @@ class CalculationsTest < ActiveRecord::TestCase def test_pluck_loaded_relation companies = Company.order(:id).limit(3).load assert_no_queries do - assert_equal ['37signals', 'Summit', 'Microsoft'], companies.pluck(:name) + assert_equal ["37signals", "Summit", "Microsoft"], companies.pluck(:name) end end def test_pluck_loaded_relation_multiple_columns companies = Company.order(:id).limit(3).load assert_no_queries do - assert_equal [[1, '37signals'], [2, 'Summit'], [3, 'Microsoft']], companies.pluck(:id, :name) + assert_equal [[1, "37signals"], [2, "Summit"], [3, "Microsoft"]], companies.pluck(:id, :name) end end def test_pluck_loaded_relation_sql_fragment companies = Company.order(:name).limit(3).load assert_queries 1 do - assert_equal ['37signals', 'Apex', 'Ex Nihilo'], companies.pluck('DISTINCT name') + assert_equal ["37signals", "Apex", "Ex Nihilo"], companies.pluck("DISTINCT name") end end @@ -743,7 +748,7 @@ class CalculationsTest < ActiveRecord::TestCase def test_should_reference_correct_aliases_while_joining_tables_of_has_many_through_association assert_nothing_raised do - developer = Developer.create!(name: 'developer') + developer = Developer.create!(name: "developer") developer.ratings.includes(comment: :post).where(posts: { id: 1 }).count end end @@ -778,7 +783,7 @@ class CalculationsTest < ActiveRecord::TestCase end end - params = protected_params.new(credit_limit: '50') + params = protected_params.new(credit_limit: "50") assert_raises(ActiveModel::ForbiddenAttributesError) do Account.group(:id).having(params) @@ -789,4 +794,8 @@ class CalculationsTest < ActiveRecord::TestCase assert_equal 50, result[1].credit_limit assert_equal 50, result[2].credit_limit end + + def test_group_by_attribute_with_custom_type + assert_equal({ "proposed" => 2, "published" => 2 }, Book.group(:status).count) + end end diff --git a/activerecord/test/cases/callbacks_test.rb b/activerecord/test/cases/callbacks_test.rb index 4f70ae3a1d..4b517e9d70 100644 --- a/activerecord/test/cases/callbacks_test.rb +++ b/activerecord/test/cases/callbacks_test.rb @@ -1,9 +1,9 @@ require "cases/helper" -require 'models/developer' -require 'models/computer' +require "models/developer" +require "models/computer" class CallbackDeveloper < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" class << self def callback_string(callback_method) @@ -16,7 +16,7 @@ class CallbackDeveloper < ActiveRecord::Base def define_callback_method(callback_method) define_method(callback_method) do - self.history << [callback_method, :method] + history << [callback_method, :method] end send(callback_method, :"#{callback_method}") end @@ -31,7 +31,7 @@ class CallbackDeveloper < ActiveRecord::Base end ActiveRecord::Callbacks::CALLBACKS.each do |callback_method| - next if callback_method.to_s =~ /^around_/ + next if callback_method.to_s.start_with?("around_") define_callback_method(callback_method) ActiveSupport::Deprecation.silence { send(callback_method, callback_string(callback_method)) } send(callback_method, callback_proc(callback_method)) @@ -55,19 +55,18 @@ class CallbackDeveloperWithHaltedValidation < CallbackDeveloper end class ParentDeveloper < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" attr_accessor :after_save_called - before_validation {|record| record.after_save_called = true} + before_validation { |record| record.after_save_called = true } end class ChildDeveloper < ParentDeveloper - end class ImmutableDeveloper < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" - validates_inclusion_of :salary, :in => 50000..200000 + validates_inclusion_of :salary, in: 50000..200000 before_save :cancel before_destroy :cancel @@ -79,7 +78,7 @@ class ImmutableDeveloper < ActiveRecord::Base end class DeveloperWithCanceledCallbacks < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" validates_inclusion_of :salary, in: 50000..200000 @@ -93,19 +92,19 @@ class DeveloperWithCanceledCallbacks < ActiveRecord::Base end class OnCallbacksDeveloper < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" before_validation { history << :before_validation } - before_validation(:on => :create){ history << :before_validation_on_create } - before_validation(:on => :update){ history << :before_validation_on_update } + before_validation(on: :create) { history << :before_validation_on_create } + before_validation(on: :update) { history << :before_validation_on_update } validate do history << :validate end after_validation { history << :after_validation } - after_validation(:on => :create){ history << :after_validation_on_create } - after_validation(:on => :update){ history << :after_validation_on_update } + after_validation(on: :create) { history << :after_validation_on_create } + after_validation(on: :update) { history << :after_validation_on_update } def history @history ||= [] @@ -113,17 +112,17 @@ class OnCallbacksDeveloper < ActiveRecord::Base end class ContextualCallbacksDeveloper < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" before_validation { history << :before_validation } - before_validation :before_validation_on_create_and_update, :on => [ :create, :update ] + before_validation :before_validation_on_create_and_update, on: [ :create, :update ] validate do history << :validate end after_validation { history << :after_validation } - after_validation :after_validation_on_create_and_update, :on => [ :create, :update ] + after_validation :after_validation_on_create_and_update, on: [ :create, :update ] def before_validation_on_create_and_update history << "before_validation_on_#{self.validation_context}".to_sym @@ -139,12 +138,12 @@ class ContextualCallbacksDeveloper < ActiveRecord::Base end class CallbackCancellationDeveloper < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" attr_reader :after_save_called, :after_create_called, :after_update_called, :after_destroy_called attr_accessor :cancel_before_save, :cancel_before_create, :cancel_before_update, :cancel_before_destroy - before_save {defined?(@cancel_before_save) ? !@cancel_before_save : false} + before_save { defined?(@cancel_before_save) ? !@cancel_before_save : false } before_create { !@cancel_before_create } before_update { !@cancel_before_update } before_destroy { !@cancel_before_destroy } @@ -156,7 +155,7 @@ class CallbackCancellationDeveloper < ActiveRecord::Base end class CallbackHaltedDeveloper < ActiveRecord::Base - self.table_name = 'developers' + self.table_name = "developers" attr_reader :after_save_called, :after_create_called, :after_update_called, :after_destroy_called attr_accessor :cancel_before_save, :cancel_before_create, :cancel_before_update, :cancel_before_destroy @@ -252,7 +251,7 @@ class CallbacksTest < ActiveRecord::TestCase end def test_create - david = CallbackDeveloper.create('name' => 'David', 'salary' => 1000000) + david = CallbackDeveloper.create("name" => "David", "salary" => 1000000) assert_equal [ [ :after_initialize, :method ], [ :after_initialize, :string ], @@ -298,7 +297,7 @@ class CallbacksTest < ActiveRecord::TestCase end def test_validate_on_create - david = OnCallbacksDeveloper.create('name' => 'David', 'salary' => 1000000) + david = OnCallbacksDeveloper.create("name" => "David", "salary" => 1000000) assert_equal [ :before_validation, :before_validation_on_create, @@ -309,7 +308,7 @@ class CallbacksTest < ActiveRecord::TestCase end def test_validate_on_contextual_create - david = ContextualCallbacksDeveloper.create('name' => 'David', 'salary' => 1000000) + david = ContextualCallbacksDeveloper.create("name" => "David", "salary" => 1000000) assert_equal [ :before_validation, :before_validation_on_create, @@ -632,5 +631,4 @@ class CallbacksTest < ActiveRecord::TestCase child.save assert child.after_save_called end - end diff --git a/activerecord/test/cases/clone_test.rb b/activerecord/test/cases/clone_test.rb index 5e43082c33..b89294c094 100644 --- a/activerecord/test/cases/clone_test.rb +++ b/activerecord/test/cases/clone_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'models/topic' +require "models/topic" module ActiveRecord class CloneTest < ActiveRecord::TestCase @@ -8,9 +8,9 @@ module ActiveRecord def test_persisted topic = Topic.first cloned = topic.clone - assert topic.persisted?, 'topic persisted' - assert cloned.persisted?, 'topic persisted' - assert !cloned.new_record?, 'topic is not new' + assert topic.persisted?, "topic persisted" + assert cloned.persisted?, "topic persisted" + assert !cloned.new_record?, "topic is not new" end def test_stays_frozen @@ -18,16 +18,16 @@ module ActiveRecord topic.freeze cloned = topic.clone - assert cloned.persisted?, 'topic persisted' - assert !cloned.new_record?, 'topic is not new' - assert cloned.frozen?, 'topic should be frozen' + assert cloned.persisted?, "topic persisted" + assert !cloned.new_record?, "topic is not new" + assert cloned.frozen?, "topic should be frozen" end def test_shallow topic = Topic.first cloned = topic.clone - topic.author_name = 'Aaron' - assert_equal 'Aaron', cloned.author_name + topic.author_name = "Aaron" + assert_equal "Aaron", cloned.author_name end def test_freezing_a_cloned_model_does_not_freeze_clone diff --git a/activerecord/test/cases/coders/json_test.rb b/activerecord/test/cases/coders/json_test.rb new file mode 100644 index 0000000000..d22d93d129 --- /dev/null +++ b/activerecord/test/cases/coders/json_test.rb @@ -0,0 +1,15 @@ +require "cases/helper" + +module ActiveRecord + module Coders + class JSONTest < ActiveRecord::TestCase + def test_returns_nil_if_empty_string_given + assert_nil JSON.load("") + end + + def test_returns_nil_if_nil_given + assert_nil JSON.load(nil) + end + end + end +end diff --git a/activerecord/test/cases/coders/yaml_column_test.rb b/activerecord/test/cases/coders/yaml_column_test.rb index b72c54f97b..b9c6224425 100644 --- a/activerecord/test/cases/coders/yaml_column_test.rb +++ b/activerecord/test/cases/coders/yaml_column_test.rb @@ -35,7 +35,7 @@ module ActiveRecord def test_returns_string_unless_starts_with_dash coder = YAMLColumn.new - assert_equal 'foo', coder.load("foo") + assert_equal "foo", coder.load("foo") end def test_load_handles_other_classes @@ -45,7 +45,7 @@ module ActiveRecord def test_load_doesnt_swallow_yaml_exceptions coder = YAMLColumn.new - bad_yaml = '--- {' + bad_yaml = "--- {" assert_raises(Psych::SyntaxError) do coder.load(bad_yaml) end diff --git a/activerecord/test/cases/column_alias_test.rb b/activerecord/test/cases/column_alias_test.rb index 40707d9cb2..9893ba9580 100644 --- a/activerecord/test/cases/column_alias_test.rb +++ b/activerecord/test/cases/column_alias_test.rb @@ -1,17 +1,17 @@ require "cases/helper" -require 'models/topic' +require "models/topic" class TestColumnAlias < ActiveRecord::TestCase fixtures :topics - QUERY = if 'Oracle' == ActiveRecord::Base.connection.adapter_name - 'SELECT id AS pk FROM topics WHERE ROWNUM < 2' - else - 'SELECT id AS pk FROM topics' - end + QUERY = if "Oracle" == ActiveRecord::Base.connection.adapter_name + "SELECT id AS pk FROM topics WHERE ROWNUM < 2" + else + "SELECT id AS pk FROM topics" + end def test_column_alias records = Topic.connection.select_all(QUERY) - assert_equal 'pk', records[0].keys[0] + assert_equal "pk", records[0].keys[0] end end diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb index 81162b7e98..a65bb89052 100644 --- a/activerecord/test/cases/column_definition_test.rb +++ b/activerecord/test/cases/column_definition_test.rb @@ -6,7 +6,7 @@ module ActiveRecord def setup @adapter = AbstractAdapter.new(nil) def @adapter.native_database_types - {:string => "varchar"} + { string: "varchar" } end @viz = @adapter.schema_creation end @@ -18,7 +18,7 @@ module ActiveRecord column_def = ColumnDefinition.new( column.name, "string", column.limit, column.precision, column.scale, column.default, column.null) - assert_equal "title varchar(20)", @viz.accept(column_def) + assert_equal "title varchar(20)", @viz.accept(column_def) end def test_should_include_default_clause_when_default_is_present @@ -26,7 +26,7 @@ module ActiveRecord column_def = ColumnDefinition.new( column.name, "string", column.limit, column.precision, column.scale, column.default, column.null) - assert_equal %Q{title varchar(20) DEFAULT 'Hello'}, @viz.accept(column_def) + assert_equal "title varchar(20) DEFAULT 'Hello'", @viz.accept(column_def) end def test_should_specify_not_null_if_null_option_is_false @@ -35,7 +35,7 @@ module ActiveRecord column_def = ColumnDefinition.new( column.name, "string", column.limit, column.precision, column.scale, column.default, column.null) - assert_equal %Q{title varchar(20) DEFAULT 'Hello' NOT NULL}, @viz.accept(column_def) + assert_equal "title varchar(20) DEFAULT 'Hello' NOT NULL", @viz.accept(column_def) end if current_adapter?(:Mysql2Adapter) @@ -60,21 +60,13 @@ module ActiveRecord end def test_should_not_set_default_for_blob_and_text_data_types - assert_raise ArgumentError do - MySQL::Column.new("title", "a", SqlTypeMetadata.new(sql_type: "blob")) - end - - text_type = MySQL::TypeMetadata.new( - SqlTypeMetadata.new(type: :text)) - assert_raise ArgumentError do - MySQL::Column.new("title", "Hello", text_type) - end + 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/comment_test.rb b/activerecord/test/cases/comment_test.rb index 37d951ad88..262ad319be 100644 --- a/activerecord/test/cases/comment_test.rb +++ b/activerecord/test/cases/comment_test.rb @@ -1,130 +1,139 @@ -require 'cases/helper' -require 'support/schema_dumping_helper' +require "cases/helper" +require "support/schema_dumping_helper" if ActiveRecord::Base.connection.supports_comments? -class CommentTest < ActiveRecord::TestCase - include SchemaDumpingHelper - self.use_transactional_tests = false if current_adapter?(:Mysql2Adapter) + class CommentTest < ActiveRecord::TestCase + include SchemaDumpingHelper - class Commented < ActiveRecord::Base - self.table_name = 'commenteds' - end - - class BlankComment < ActiveRecord::Base - end - - setup do - @connection = ActiveRecord::Base.connection + class Commented < ActiveRecord::Base + self.table_name = "commenteds" + end - @connection.create_table('commenteds', comment: 'A table with comment', force: true) do |t| - t.string 'name', comment: 'Comment should help clarify the column purpose' - t.boolean 'obvious', comment: 'Question is: should you comment obviously named objects?' - t.string 'content' - t.index 'name', comment: %Q["Very important" index that powers all the performance.\nAnd it's fun!] + class BlankComment < ActiveRecord::Base end - @connection.create_table('blank_comments', comment: ' ', force: true) do |t| - t.string :space_comment, comment: ' ' - t.string :empty_comment, comment: '' - t.string :nil_comment, comment: nil - t.string :absent_comment + setup do + @connection = ActiveRecord::Base.connection + + @connection.create_table("commenteds", comment: "A table with comment", force: true) do |t| + t.string "name", comment: "Comment should help clarify the column purpose" + t.boolean "obvious", comment: "Question is: should you comment obviously named objects?" + t.string "content" + t.index "name", comment: %Q["Very important" index that powers all the performance.\nAnd it's fun!] + end + + @connection.create_table("blank_comments", comment: " ", force: true) do |t| + t.string :space_comment, comment: " " + t.string :empty_comment, comment: "" + t.string :nil_comment, comment: nil + t.string :absent_comment + t.index :space_comment, comment: " " + t.index :empty_comment, comment: "" + t.index :nil_comment, comment: nil + t.index :absent_comment + end + + Commented.reset_column_information + BlankComment.reset_column_information end - Commented.reset_column_information - BlankComment.reset_column_information - end + teardown do + @connection.drop_table "commenteds", if_exists: true + @connection.drop_table "blank_comments", if_exists: true + end - teardown do - @connection.drop_table 'commenteds', if_exists: true - @connection.drop_table 'blank_comments', if_exists: true - end + def test_column_created_in_block + column = Commented.columns_hash["name"] + assert_equal :string, column.type + assert_equal "Comment should help clarify the column purpose", column.comment + end - def test_column_created_in_block - column = Commented.columns_hash['name'] - assert_equal :string, column.type - assert_equal 'Comment should help clarify the column purpose', column.comment - end + def test_blank_columns_created_in_block + %w[ space_comment empty_comment nil_comment absent_comment ].each do |field| + column = BlankComment.columns_hash[field] + assert_equal :string, column.type + assert_nil column.comment + end + end - def test_blank_columns_created_in_block - %w[ space_comment empty_comment nil_comment absent_comment ].each do |field| - column = BlankComment.columns_hash[field] - assert_equal :string, column.type - assert_nil column.comment + def test_blank_indexes_created_in_block + @connection.indexes("blank_comments").each do |index| + assert_nil index.comment + end end - end - def test_add_column_with_comment_later - @connection.add_column :commenteds, :rating, :integer, comment: 'I am running out of imagination' - Commented.reset_column_information - column = Commented.columns_hash['rating'] + def test_add_column_with_comment_later + @connection.add_column :commenteds, :rating, :integer, comment: "I am running out of imagination" + Commented.reset_column_information + column = Commented.columns_hash["rating"] - assert_equal :integer, column.type - assert_equal 'I am running out of imagination', column.comment - end + assert_equal :integer, column.type + assert_equal "I am running out of imagination", column.comment + end - def test_add_index_with_comment_later - @connection.add_index :commenteds, :obvious, name: 'idx_obvious', comment: 'We need to see obvious comments' - index = @connection.indexes('commenteds').find { |idef| idef.name == 'idx_obvious' } - assert_equal 'We need to see obvious comments', index.comment - end + def test_add_index_with_comment_later + @connection.add_index :commenteds, :obvious, name: "idx_obvious", comment: "We need to see obvious comments" + index = @connection.indexes("commenteds").find { |idef| idef.name == "idx_obvious" } + assert_equal "We need to see obvious comments", index.comment + end - def test_add_comment_to_column - @connection.change_column :commenteds, :content, :string, comment: 'Whoa, content describes itself!' + def test_add_comment_to_column + @connection.change_column :commenteds, :content, :string, comment: "Whoa, content describes itself!" - Commented.reset_column_information - column = Commented.columns_hash['content'] + Commented.reset_column_information + column = Commented.columns_hash["content"] - assert_equal :string, column.type - assert_equal 'Whoa, content describes itself!', column.comment - end + assert_equal :string, column.type + assert_equal "Whoa, content describes itself!", column.comment + end - def test_remove_comment_from_column - @connection.change_column :commenteds, :obvious, :string, comment: nil + def test_remove_comment_from_column + @connection.change_column :commenteds, :obvious, :string, comment: nil - Commented.reset_column_information - column = Commented.columns_hash['obvious'] + Commented.reset_column_information + column = Commented.columns_hash["obvious"] - assert_equal :string, column.type - assert_nil column.comment - end + assert_equal :string, column.type + assert_nil column.comment + end - def test_schema_dump_with_comments - # Do all the stuff from other tests - @connection.add_column :commenteds, :rating, :integer, comment: 'I am running out of imagination' - @connection.change_column :commenteds, :content, :string, comment: 'Whoa, content describes itself!' - @connection.change_column :commenteds, :obvious, :string, comment: nil - @connection.add_index :commenteds, :obvious, name: 'idx_obvious', comment: 'We need to see obvious comments' - - # And check that these changes are reflected in dump - output = dump_table_schema 'commenteds' - assert_match %r[create_table "commenteds",.+\s+comment: "A table with comment"], output - assert_match %r[t\.string\s+"name",\s+comment: "Comment should help clarify the column purpose"], output - assert_match %r[t\.string\s+"obvious"\n], output - assert_match %r[t\.string\s+"content",\s+comment: "Whoa, content describes itself!"], output - assert_match %r[t\.integer\s+"rating",\s+comment: "I am running out of imagination"], output - assert_match %r[t\.index\s+.+\s+comment: "\\\"Very important\\\" index that powers all the performance.\\nAnd it's fun!"], output - assert_match %r[t\.index\s+.+\s+name: "idx_obvious",.+\s+comment: "We need to see obvious comments"], output - end + def test_schema_dump_with_comments + # Do all the stuff from other tests + @connection.add_column :commenteds, :rating, :integer, comment: "I am running out of imagination" + @connection.change_column :commenteds, :content, :string, comment: "Whoa, content describes itself!" + @connection.change_column :commenteds, :obvious, :string, comment: nil + @connection.add_index :commenteds, :obvious, name: "idx_obvious", comment: "We need to see obvious comments" + + # And check that these changes are reflected in dump + output = dump_table_schema "commenteds" + assert_match %r[create_table "commenteds",.+\s+comment: "A table with comment"], output + assert_match %r[t\.string\s+"name",\s+comment: "Comment should help clarify the column purpose"], output + assert_match %r[t\.string\s+"obvious"\n], output + assert_match %r[t\.string\s+"content",\s+comment: "Whoa, content describes itself!"], output + assert_match %r[t\.integer\s+"rating",\s+comment: "I am running out of imagination"], output + assert_match %r[t\.index\s+.+\s+comment: "\\\"Very important\\\" index that powers all the performance.\\nAnd it's fun!"], output + assert_match %r[t\.index\s+.+\s+name: "idx_obvious",.+\s+comment: "We need to see obvious comments"], output + end - def test_schema_dump_omits_blank_comments - output = dump_table_schema 'blank_comments' + def test_schema_dump_omits_blank_comments + output = dump_table_schema "blank_comments" - assert_match %r[create_table "blank_comments"], output - assert_no_match %r[create_table "blank_comments",.+comment:], output + assert_match %r[create_table "blank_comments"], output + assert_no_match %r[create_table "blank_comments",.+comment:], output - assert_match %r[t\.string\s+"space_comment"\n], output - assert_no_match %r[t\.string\s+"space_comment", comment:\n], output + assert_match %r[t\.string\s+"space_comment"\n], output + assert_no_match %r[t\.string\s+"space_comment", comment:\n], output - assert_match %r[t\.string\s+"empty_comment"\n], output - assert_no_match %r[t\.string\s+"empty_comment", comment:\n], output + assert_match %r[t\.string\s+"empty_comment"\n], output + assert_no_match %r[t\.string\s+"empty_comment", comment:\n], output - assert_match %r[t\.string\s+"nil_comment"\n], output - assert_no_match %r[t\.string\s+"nil_comment", comment:\n], output + assert_match %r[t\.string\s+"nil_comment"\n], output + assert_no_match %r[t\.string\s+"nil_comment", comment:\n], output - assert_match %r[t\.string\s+"absent_comment"\n], output - assert_no_match %r[t\.string\s+"absent_comment", comment:\n], output + assert_match %r[t\.string\s+"absent_comment"\n], output + assert_no_match %r[t\.string\s+"absent_comment", comment:\n], output + end end -end end diff --git a/activerecord/test/cases/connection_adapters/adapter_leasing_test.rb b/activerecord/test/cases/connection_adapters/adapter_leasing_test.rb index 580568c8ac..64189381cb 100644 --- a/activerecord/test/cases/connection_adapters/adapter_leasing_test.rb +++ b/activerecord/test/cases/connection_adapters/adapter_leasing_test.rb @@ -17,27 +17,27 @@ module ActiveRecord end def test_in_use? - assert_not @adapter.in_use?, 'adapter is not in use' - assert @adapter.lease, 'lease adapter' - assert @adapter.in_use?, 'adapter is in use' + assert_not @adapter.in_use?, "adapter is not in use" + assert @adapter.lease, "lease adapter" + assert @adapter.in_use?, "adapter is in use" end def test_lease_twice - assert @adapter.lease, 'should lease adapter' + assert @adapter.lease, "should lease adapter" assert_raises(ActiveRecordError) do @adapter.lease end end def test_expire_mutates_in_use - assert @adapter.lease, 'lease adapter' - assert @adapter.in_use?, 'adapter is in use' + assert @adapter.lease, "lease adapter" + assert @adapter.in_use?, "adapter is in use" @adapter.expire - assert_not @adapter.in_use?, 'adapter is in use' + assert_not @adapter.in_use?, "adapter is in use" end def test_close - pool = Pool.new(ConnectionSpecification.new({}, nil)) + pool = Pool.new(ConnectionSpecification.new("primary", {}, nil)) pool.insert_connection_for_test! @adapter @adapter.pool = pool diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb index 9b1865e8bb..d5d16e7568 100644 --- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb +++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb @@ -4,43 +4,40 @@ module ActiveRecord module ConnectionAdapters class ConnectionHandlerTest < ActiveRecord::TestCase def setup - @klass = Class.new(Base) { def self.name; 'klass'; end } - @subklass = Class.new(@klass) { def self.name; 'subklass'; end } - @handler = ConnectionHandler.new - @pool = @handler.establish_connection(@klass, Base.connection_pool.spec) + @spec_name = "primary" + @pool = @handler.establish_connection(ActiveRecord::Base.configurations["arunit"]) + end + + def test_establish_connection_uses_spec_name + config = { "readonly" => { "adapter" => "sqlite3" } } + resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(config) + spec = resolver.spec(:readonly) + @handler.establish_connection(spec.to_hash) + + assert_not_nil @handler.retrieve_connection_pool("readonly") + ensure + @handler.remove_connection("readonly") end def test_retrieve_connection - assert @handler.retrieve_connection(@klass) + assert @handler.retrieve_connection(@spec_name) end def test_active_connections? assert !@handler.active_connections? - assert @handler.retrieve_connection(@klass) + assert @handler.retrieve_connection(@spec_name) assert @handler.active_connections? @handler.clear_active_connections! assert !@handler.active_connections? end - def test_retrieve_connection_pool_with_ar_base - assert_nil @handler.retrieve_connection_pool(ActiveRecord::Base) - end - def test_retrieve_connection_pool - assert_not_nil @handler.retrieve_connection_pool(@klass) + assert_not_nil @handler.retrieve_connection_pool(@spec_name) end - def test_retrieve_connection_pool_uses_superclass_when_no_subclass_connection - assert_not_nil @handler.retrieve_connection_pool(@subklass) - end - - def test_retrieve_connection_pool_uses_superclass_pool_after_subclass_establish_and_remove - sub_pool = @handler.establish_connection(@subklass, Base.connection_pool.spec) - assert_same sub_pool, @handler.retrieve_connection_pool(@subklass) - - @handler.remove_connection @subklass - assert_same @pool, @handler.retrieve_connection_pool(@subklass) + def test_retrieve_connection_pool_with_invalid_id + assert_nil @handler.retrieve_connection_pool("foo") end def test_connection_pools @@ -71,7 +68,7 @@ module ActiveRecord def test_retrieve_connection_pool_copies_schema_cache_from_ancestor_pool @pool.schema_cache = @pool.connection.schema_cache - @pool.schema_cache.add('posts') + @pool.schema_cache.add("posts") rd, wr = IO.pipe rd.binmode @@ -79,7 +76,7 @@ module ActiveRecord pid = fork { rd.close - pool = @handler.retrieve_connection_pool(@klass) + pool = @handler.retrieve_connection_pool(@spec_name) wr.write Marshal.dump pool.schema_cache.size wr.close exit! @@ -91,6 +88,36 @@ module ActiveRecord assert_equal @pool.schema_cache.size, Marshal.load(rd.read) rd.close end + + def test_a_class_using_custom_pool_and_switching_back_to_primary + klass2 = Class.new(Base) { def self.name; "klass2"; end } + + assert_equal klass2.connection.object_id, ActiveRecord::Base.connection.object_id + + pool = klass2.establish_connection(ActiveRecord::Base.connection_pool.spec.config) + assert_equal klass2.connection.object_id, pool.connection.object_id + refute_equal klass2.connection.object_id, ActiveRecord::Base.connection.object_id + + klass2.remove_connection + + assert_equal klass2.connection.object_id, ActiveRecord::Base.connection.object_id + end + + def test_connection_specification_name_should_fallback_to_parent + klassA = Class.new(Base) + klassB = Class.new(klassA) + + assert_equal klassB.connection_specification_name, klassA.connection_specification_name + klassA.connection_specification_name = "readonly" + assert_equal "readonly", klassB.connection_specification_name + end + + def test_remove_connection_should_not_remove_parent + klass2 = Class.new(Base) { def self.name; "klass2"; end } + klass2.remove_connection + refute_nil ActiveRecord::Base.connection.object_id + assert_equal klass2.connection.object_id, ActiveRecord::Base.connection.object_id + end end end end diff --git a/activerecord/test/cases/connection_adapters/connection_specification_test.rb b/activerecord/test/cases/connection_adapters/connection_specification_test.rb index ea2196cda2..10a3521c79 100644 --- a/activerecord/test/cases/connection_adapters/connection_specification_test.rb +++ b/activerecord/test/cases/connection_adapters/connection_specification_test.rb @@ -4,7 +4,7 @@ module ActiveRecord module ConnectionAdapters class ConnectionSpecificationTest < ActiveRecord::TestCase def test_dup_deep_copy_config - spec = ConnectionSpecification.new({ :a => :b }, "bar") + spec = ConnectionSpecification.new("primary", { a: :b }, "bar") assert_not_equal(spec.config.object_id, spec.dup.config.object_id) end end diff --git a/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb b/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb index 9ee92a3cd2..4bb5c4f2e2 100644 --- a/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +++ b/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb @@ -24,43 +24,43 @@ module ActiveRecord end def test_resolver_with_database_uri_and_current_env_symbol_key - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } actual = resolve_spec(:default_env, config) - expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" } + expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost", "name"=>"default_env" } assert_equal expected, actual end def test_resolver_with_database_uri_and_current_env_symbol_key_and_rails_env - ENV['DATABASE_URL'] = "postgres://localhost/foo" - ENV['RAILS_ENV'] = "foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" + ENV["RAILS_ENV"] = "foo" config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } actual = resolve_spec(:foo, config) - expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" } + expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost","name"=>"foo" } assert_equal expected, actual end def test_resolver_with_database_uri_and_current_env_symbol_key_and_rack_env - ENV['DATABASE_URL'] = "postgres://localhost/foo" - ENV['RACK_ENV'] = "foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" + ENV["RACK_ENV"] = "foo" config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } actual = resolve_spec(:foo, config) - expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost" } + expected = { "adapter" => "postgresql", "database" => "foo", "host" => "localhost","name"=>"foo" } assert_equal expected, actual end def test_resolver_with_database_uri_and_known_key - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } } actual = resolve_spec(:production, config) - expected = { "adapter"=>"not_postgres", "database"=>"not_foo", "host"=>"localhost" } + expected = { "adapter"=>"not_postgres", "database"=>"not_foo", "host"=>"localhost", "name"=>"production" } assert_equal expected, actual end def test_resolver_with_database_uri_and_unknown_symbol_key - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } } assert_raises AdapterNotSpecified do resolve_spec(:production, config) @@ -68,7 +68,7 @@ module ActiveRecord end def test_resolver_with_database_uri_and_supplied_url - ENV['DATABASE_URL'] = "not-postgres://not-localhost/not_foo" + ENV["DATABASE_URL"] = "not-postgres://not-localhost/not_foo" config = { "production" => { "adapter" => "also_not_postgres", "database" => "also_not_foo" } } actual = resolve_spec("postgres://localhost/foo", config) expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" } @@ -82,7 +82,7 @@ module ActiveRecord end def test_environment_does_not_exist_in_config_url_does_exist - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" config = { "not_default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } } actual = resolve_config(config) expect_prod = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" } @@ -90,10 +90,10 @@ module ActiveRecord end def test_url_with_hyphenated_scheme - ENV['DATABASE_URL'] = "ibm-db://localhost/foo" + ENV["DATABASE_URL"] = "ibm-db://localhost/foo" config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } } actual = resolve_spec(:default_env, config) - expected = { "adapter"=>"ibm_db", "database"=>"foo", "host"=>"localhost" } + expected = { "adapter"=>"ibm_db", "database"=>"foo", "host"=>"localhost", "name"=>"default_env" } assert_equal expected, actual end @@ -134,7 +134,7 @@ module ActiveRecord end def test_blank_with_database_url - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" config = {} actual = resolve_config(config) @@ -152,8 +152,8 @@ module ActiveRecord end def test_blank_with_database_url_with_rails_env - ENV['RAILS_ENV'] = "not_production" - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["RAILS_ENV"] = "not_production" + ENV["DATABASE_URL"] = "postgres://localhost/foo" config = {} actual = resolve_config(config) @@ -174,8 +174,8 @@ module ActiveRecord end def test_blank_with_database_url_with_rack_env - ENV['RACK_ENV'] = "not_production" - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["RACK_ENV"] = "not_production" + ENV["DATABASE_URL"] = "postgres://localhost/foo" config = {} actual = resolve_config(config) @@ -196,7 +196,7 @@ module ActiveRecord end def test_database_url_with_ipv6_host_and_port - ENV['DATABASE_URL'] = "postgres://[::1]:5454/foo" + ENV["DATABASE_URL"] = "postgres://[::1]:5454/foo" config = {} actual = resolve_config(config) @@ -208,7 +208,7 @@ module ActiveRecord end def test_url_sub_key_with_database_url - ENV['DATABASE_URL'] = "NOT-POSTGRES://localhost/NOT_FOO" + ENV["DATABASE_URL"] = "NOT-POSTGRES://localhost/NOT_FOO" config = { "default_env" => { "url" => "postgres://localhost/foo" } } actual = resolve_config(config) @@ -222,9 +222,9 @@ module ActiveRecord end def test_merge_no_conflicts_with_database_url - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" - config = {"default_env" => { "pool" => "5" } } + config = { "default_env" => { "pool" => "5" } } actual = resolve_config(config) expected = { "default_env" => { "adapter" => "postgresql", @@ -237,9 +237,9 @@ module ActiveRecord end def test_merge_conflicts_with_database_url - ENV['DATABASE_URL'] = "postgres://localhost/foo" + ENV["DATABASE_URL"] = "postgres://localhost/foo" - config = {"default_env" => { "adapter" => "NOT-POSTGRES", "database" => "NOT-FOO", "pool" => "5" } } + config = { "default_env" => { "adapter" => "NOT-POSTGRES", "database" => "NOT-FOO", "pool" => "5" } } actual = resolve_config(config) expected = { "default_env" => { "adapter" => "postgresql", diff --git a/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb b/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb index f2b1d9e4e7..3657b8340d 100644 --- a/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb +++ b/activerecord/test/cases/connection_adapters/mysql_type_lookup_test.rb @@ -1,69 +1,69 @@ require "cases/helper" if current_adapter?(:Mysql2Adapter) -module ActiveRecord - module ConnectionAdapters - class MysqlTypeLookupTest < ActiveRecord::TestCase - setup do - @connection = ActiveRecord::Base.connection - end + module ActiveRecord + module ConnectionAdapters + class MysqlTypeLookupTest < ActiveRecord::TestCase + setup do + @connection = ActiveRecord::Base.connection + end - def test_boolean_types - emulate_booleans(true) do - assert_lookup_type :boolean, 'tinyint(1)' - assert_lookup_type :boolean, 'TINYINT(1)' + def test_boolean_types + emulate_booleans(true) do + assert_lookup_type :boolean, "tinyint(1)" + assert_lookup_type :boolean, "TINYINT(1)" + end end - end - def test_string_types - assert_lookup_type :string, "enum('one', 'two', 'three')" - assert_lookup_type :string, "ENUM('one', 'two', 'three')" - assert_lookup_type :string, "set('one', 'two', 'three')" - assert_lookup_type :string, "SET('one', 'two', 'three')" - end + def test_string_types + assert_lookup_type :string, "enum('one', 'two', 'three')" + assert_lookup_type :string, "ENUM('one', 'two', 'three')" + assert_lookup_type :string, "set('one', 'two', 'three')" + assert_lookup_type :string, "SET('one', 'two', 'three')" + end - def test_set_type_with_value_matching_other_type - assert_lookup_type :string, "SET('unicode', '8bit', 'none', 'time')" - end + def test_set_type_with_value_matching_other_type + assert_lookup_type :string, "SET('unicode', '8bit', 'none', 'time')" + end - def test_enum_type_with_value_matching_other_type - assert_lookup_type :string, "ENUM('unicode', '8bit', 'none')" - end + def test_enum_type_with_value_matching_other_type + assert_lookup_type :string, "ENUM('unicode', '8bit', 'none')" + end - def test_binary_types - assert_lookup_type :binary, 'bit' - assert_lookup_type :binary, 'BIT' - end + def test_binary_types + assert_lookup_type :binary, "bit" + assert_lookup_type :binary, "BIT" + end - def test_integer_types - emulate_booleans(false) do - assert_lookup_type :integer, 'tinyint(1)' - assert_lookup_type :integer, 'TINYINT(1)' - assert_lookup_type :integer, 'year' - assert_lookup_type :integer, 'YEAR' + def test_integer_types + emulate_booleans(false) do + assert_lookup_type :integer, "tinyint(1)" + assert_lookup_type :integer, "TINYINT(1)" + assert_lookup_type :integer, "year" + assert_lookup_type :integer, "YEAR" + end end - end - private + private - def assert_lookup_type(type, lookup) - cast_type = @connection.type_map.lookup(lookup) - assert_equal type, cast_type.type - end + def assert_lookup_type(type, lookup) + cast_type = @connection.type_map.lookup(lookup) + assert_equal type, cast_type.type + end - def emulate_booleans(value) - old_emulate_booleans = @connection.emulate_booleans - change_emulate_booleans(value) - yield - ensure - change_emulate_booleans(old_emulate_booleans) - end + def emulate_booleans(value) + old_emulate_booleans = @connection.emulate_booleans + change_emulate_booleans(value) + yield + ensure + change_emulate_booleans(old_emulate_booleans) + end - def change_emulate_booleans(value) - @connection.emulate_booleans = value - @connection.clear_cache! + def change_emulate_booleans(value) + @connection.emulate_booleans = value + @connection.clear_cache! + end end end end end -end diff --git a/activerecord/test/cases/connection_adapters/schema_cache_test.rb b/activerecord/test/cases/connection_adapters/schema_cache_test.rb index db832fe55d..d4459603af 100644 --- a/activerecord/test/cases/connection_adapters/schema_cache_test.rb +++ b/activerecord/test/cases/connection_adapters/schema_cache_test.rb @@ -9,28 +9,28 @@ module ActiveRecord end def test_primary_key - assert_equal 'id', @cache.primary_keys('posts') + assert_equal "id", @cache.primary_keys("posts") end def test_primary_key_for_non_existent_table - assert_nil @cache.primary_keys('omgponies') + assert_nil @cache.primary_keys("omgponies") end def test_caches_columns - columns = @cache.columns('posts') - assert_equal columns, @cache.columns('posts') + columns = @cache.columns("posts") + assert_equal columns, @cache.columns("posts") end def test_caches_columns_hash - columns_hash = @cache.columns_hash('posts') - assert_equal columns_hash, @cache.columns_hash('posts') + columns_hash = @cache.columns_hash("posts") + assert_equal columns_hash, @cache.columns_hash("posts") end def test_clearing - @cache.columns('posts') - @cache.columns_hash('posts') - @cache.data_sources('posts') - @cache.primary_keys('posts') + @cache.columns("posts") + @cache.columns_hash("posts") + @cache.data_sources("posts") + @cache.primary_keys("posts") @cache.clear! @@ -38,23 +38,23 @@ module ActiveRecord end def test_dump_and_load - @cache.columns('posts') - @cache.columns_hash('posts') - @cache.data_sources('posts') - @cache.primary_keys('posts') + @cache.columns("posts") + @cache.columns_hash("posts") + @cache.data_sources("posts") + @cache.primary_keys("posts") @cache = Marshal.load(Marshal.dump(@cache)) - assert_equal 11, @cache.columns('posts').size - assert_equal 11, @cache.columns_hash('posts').size - assert @cache.data_sources('posts') - assert_equal 'id', @cache.primary_keys('posts') + assert_equal 11, @cache.columns("posts").size + assert_equal 11, @cache.columns_hash("posts").size + assert @cache.data_sources("posts") + assert_equal "id", @cache.primary_keys("posts") end def test_table_methods_deprecation - assert_deprecated { assert @cache.table_exists?('posts') } - assert_deprecated { assert @cache.tables('posts') } - assert_deprecated { @cache.clear_table_cache!('posts') } + assert_deprecated { assert @cache.table_exists?("posts") } + assert_deprecated { assert @cache.tables("posts") } + assert_deprecated { @cache.clear_table_cache!("posts") } end end end diff --git a/activerecord/test/cases/connection_adapters/type_lookup_test.rb b/activerecord/test/cases/connection_adapters/type_lookup_test.rb index 7566863653..e2e5445a4e 100644 --- a/activerecord/test/cases/connection_adapters/type_lookup_test.rb +++ b/activerecord/test/cases/connection_adapters/type_lookup_test.rb @@ -1,110 +1,110 @@ require "cases/helper" -unless current_adapter?(:PostgreSQLAdapter) # PostgreSQL does not use type strigns for lookup -module ActiveRecord - module ConnectionAdapters - class TypeLookupTest < ActiveRecord::TestCase - setup do - @connection = ActiveRecord::Base.connection - end +unless current_adapter?(:PostgreSQLAdapter) # PostgreSQL does not use type strings for lookup + module ActiveRecord + module ConnectionAdapters + class TypeLookupTest < ActiveRecord::TestCase + setup do + @connection = ActiveRecord::Base.connection + end - def test_boolean_types - assert_lookup_type :boolean, 'boolean' - assert_lookup_type :boolean, 'BOOLEAN' - end + def test_boolean_types + assert_lookup_type :boolean, "boolean" + assert_lookup_type :boolean, "BOOLEAN" + end - def test_string_types - assert_lookup_type :string, 'char' - assert_lookup_type :string, 'varchar' - assert_lookup_type :string, 'VARCHAR' - assert_lookup_type :string, 'varchar(255)' - assert_lookup_type :string, 'character varying' - end + def test_string_types + assert_lookup_type :string, "char" + assert_lookup_type :string, "varchar" + assert_lookup_type :string, "VARCHAR" + assert_lookup_type :string, "varchar(255)" + assert_lookup_type :string, "character varying" + end - def test_binary_types - assert_lookup_type :binary, 'binary' - assert_lookup_type :binary, 'BINARY' - assert_lookup_type :binary, 'blob' - assert_lookup_type :binary, 'BLOB' - end + def test_binary_types + assert_lookup_type :binary, "binary" + assert_lookup_type :binary, "BINARY" + assert_lookup_type :binary, "blob" + assert_lookup_type :binary, "BLOB" + end - def test_text_types - assert_lookup_type :text, 'text' - assert_lookup_type :text, 'TEXT' - assert_lookup_type :text, 'clob' - assert_lookup_type :text, 'CLOB' - end + def test_text_types + assert_lookup_type :text, "text" + assert_lookup_type :text, "TEXT" + assert_lookup_type :text, "clob" + assert_lookup_type :text, "CLOB" + end - def test_date_types - assert_lookup_type :date, 'date' - assert_lookup_type :date, 'DATE' - end + def test_date_types + assert_lookup_type :date, "date" + assert_lookup_type :date, "DATE" + end - def test_time_types - assert_lookup_type :time, 'time' - assert_lookup_type :time, 'TIME' - end + def test_time_types + assert_lookup_type :time, "time" + assert_lookup_type :time, "TIME" + end - def test_datetime_types - assert_lookup_type :datetime, 'datetime' - assert_lookup_type :datetime, 'DATETIME' - assert_lookup_type :datetime, 'timestamp' - assert_lookup_type :datetime, 'TIMESTAMP' - end + def test_datetime_types + assert_lookup_type :datetime, "datetime" + assert_lookup_type :datetime, "DATETIME" + assert_lookup_type :datetime, "timestamp" + assert_lookup_type :datetime, "TIMESTAMP" + end - def test_decimal_types - assert_lookup_type :decimal, 'decimal' - assert_lookup_type :decimal, 'decimal(2,8)' - assert_lookup_type :decimal, 'DECIMAL' - assert_lookup_type :decimal, 'numeric' - assert_lookup_type :decimal, 'numeric(2,8)' - assert_lookup_type :decimal, 'NUMERIC' - assert_lookup_type :decimal, 'number' - assert_lookup_type :decimal, 'number(2,8)' - assert_lookup_type :decimal, 'NUMBER' - end + def test_decimal_types + assert_lookup_type :decimal, "decimal" + assert_lookup_type :decimal, "decimal(2,8)" + assert_lookup_type :decimal, "DECIMAL" + assert_lookup_type :decimal, "numeric" + assert_lookup_type :decimal, "numeric(2,8)" + assert_lookup_type :decimal, "NUMERIC" + assert_lookup_type :decimal, "number" + assert_lookup_type :decimal, "number(2,8)" + assert_lookup_type :decimal, "NUMBER" + end - def test_float_types - assert_lookup_type :float, 'float' - assert_lookup_type :float, 'FLOAT' - assert_lookup_type :float, 'double' - assert_lookup_type :float, 'DOUBLE' - end + def test_float_types + assert_lookup_type :float, "float" + assert_lookup_type :float, "FLOAT" + assert_lookup_type :float, "double" + assert_lookup_type :float, "DOUBLE" + end - def test_integer_types - assert_lookup_type :integer, 'integer' - assert_lookup_type :integer, 'INTEGER' - assert_lookup_type :integer, 'tinyint' - assert_lookup_type :integer, 'smallint' - assert_lookup_type :integer, 'bigint' - end + def test_integer_types + assert_lookup_type :integer, "integer" + assert_lookup_type :integer, "INTEGER" + assert_lookup_type :integer, "tinyint" + assert_lookup_type :integer, "smallint" + assert_lookup_type :integer, "bigint" + end - def test_bigint_limit - cast_type = @connection.type_map.lookup("bigint") - if current_adapter?(:OracleAdapter) - assert_equal 19, cast_type.limit - else - assert_equal 8, cast_type.limit + def test_bigint_limit + cast_type = @connection.type_map.lookup("bigint") + if current_adapter?(:OracleAdapter) + assert_equal 19, cast_type.limit + else + assert_equal 8, cast_type.limit + end end - end - def test_decimal_without_scale - types = %w{decimal(2) decimal(2,0) numeric(2) numeric(2,0) number(2) number(2,0)} - types.each do |type| - cast_type = @connection.type_map.lookup(type) + def test_decimal_without_scale + types = %w{decimal(2) decimal(2,0) numeric(2) numeric(2,0) number(2) number(2,0)} + types.each do |type| + cast_type = @connection.type_map.lookup(type) - assert_equal :decimal, cast_type.type - assert_equal 2, cast_type.cast(2.1) + assert_equal :decimal, cast_type.type + assert_equal 2, cast_type.cast(2.1) + end end - end - private + private - def assert_lookup_type(type, lookup) - cast_type = @connection.type_map.lookup(lookup) - assert_equal type, cast_type.type + def assert_lookup_type(type, lookup) + cast_type = @connection.type_map.lookup(lookup) + assert_equal type, cast_type.type + end end end end end -end diff --git a/activerecord/test/cases/connection_management_test.rb b/activerecord/test/cases/connection_management_test.rb index 1f9b6add7a..d1e946d401 100644 --- a/activerecord/test/cases/connection_management_test.rb +++ b/activerecord/test/cases/connection_management_test.rb @@ -14,7 +14,7 @@ module ActiveRecord def call(env) @calls << env - [200, {}, ['hi mom']] + [200, {}, ["hi mom"]] end end @@ -39,7 +39,7 @@ module ActiveRecord _, _, body = @management.call(@env) bits = [] body.each { |bit| bits << bit } - assert_equal ['hi mom'], bits + assert_equal ["hi mom"], bits end def test_connections_are_cleared_after_body_close @@ -88,10 +88,10 @@ module ActiveRecord end test "doesn't mutate the original response" do - original_response = [200, {}, 'hi'] + original_response = [200, {}, "hi"] app = lambda { |_| original_response } middleware(app).call(@env)[2] - assert_equal 'hi', original_response.last + assert_equal "hi", original_response.last end private @@ -104,7 +104,7 @@ module ActiveRecord def middleware(app) lambda do |env| a, b, c = executor.wrap { app.call(env) } - [a, b, Rack::BodyProxy.new(c) { }] + [a, b, Rack::BodyProxy.new(c) {}] end end end diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index efa3e0455e..d7ff9d6880 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'concurrent/atomic/count_down_latch' +require "concurrent/atomic/count_down_latch" module ActiveRecord module ConnectionAdapters @@ -151,7 +151,7 @@ module ActiveRecord assert_equal 1, active_connections(@pool).size ensure - @pool.connections.each(&:close) + @pool.connections.each { |conn| conn.close if conn.in_use? } end def test_remove_connection @@ -335,11 +335,22 @@ module ActiveRecord # is called with an anonymous class def test_anonymous_class_exception anonymous = Class.new(ActiveRecord::Base) - handler = ActiveRecord::Base.connection_handler - assert_raises(RuntimeError) { - handler.establish_connection anonymous, nil - } + assert_raises(RuntimeError) do + anonymous.establish_connection + end + end + + def test_connection_notification_is_called + payloads = [] + subscription = ActiveSupport::Notifications.subscribe("!connection.active_record") do |name, started, finished, unique_id, payload| + payloads << payload + end + ActiveRecord::Base.establish_connection :arunit + assert_equal [:config, :connection_id, :spec_name], payloads[0].keys.sort + assert_equal "primary", payloads[0][:spec_name] + ensure + ActiveSupport::Notifications.unsubscribe(subscription) if subscription end def test_pool_sets_connection_schema_cache @@ -384,8 +395,8 @@ module ActiveRecord all_threads_in_new_connection.wait end rescue Timeout::Error - flunk 'pool unable to establish connections concurrently or implementation has ' << - 'changed, this test then needs to patch a different :new_connection method' + flunk "pool unable to establish connections concurrently or implementation has " << + "changed, this test then needs to patch a different :new_connection method" ensure # clean up the threads all_go.count_down @@ -433,6 +444,9 @@ module ActiveRecord Thread.new { @pool.send(group_action_method) }.join # assert connection has been forcefully taken away from us assert_not @pool.active_connection? + + # make a new connection for with_connection to clean up + @pool.connection end end end @@ -505,7 +519,7 @@ module ActiveRecord pool.clear_reloadable_connections unless stuck_thread.join(2) - flunk 'clear_reloadable_connections must not let other connection waiting threads get stuck in queue' + flunk "clear_reloadable_connections must not let other connection waiting threads get stuck in queue" end assert_equal 0, pool.num_waiting_in_queue @@ -513,13 +527,13 @@ module ActiveRecord end private - def with_single_connection_pool - one_conn_spec = ActiveRecord::Base.connection_pool.spec.dup - one_conn_spec.config[:pool] = 1 # this is safe to do, because .dupped ConnectionSpecification also auto-dups its config - yield(pool = ConnectionPool.new(one_conn_spec)) - ensure - pool.disconnect! if pool - end + def with_single_connection_pool + one_conn_spec = ActiveRecord::Base.connection_pool.spec.dup + one_conn_spec.config[:pool] = 1 # this is safe to do, because .dupped ConnectionSpecification also auto-dups its config + yield(pool = ConnectionPool.new(one_conn_spec)) + ensure + pool.disconnect! if pool + end end end end diff --git a/activerecord/test/cases/connection_specification/resolver_test.rb b/activerecord/test/cases/connection_specification/resolver_test.rb index 358b6ad537..0f62c73f8f 100644 --- a/activerecord/test/cases/connection_specification/resolver_test.rb +++ b/activerecord/test/cases/connection_specification/resolver_test.rb @@ -14,7 +14,7 @@ module ActiveRecord def test_url_invalid_adapter error = assert_raises(LoadError) do - spec 'ridiculous://foo?encoding=utf8' + spec "ridiculous://foo?encoding=utf8" end assert_match "Could not load 'active_record/connection_adapters/ridiculous_adapter'", error.message @@ -24,33 +24,36 @@ module ActiveRecord # checks that the adapter file can be required in. def test_url_from_environment - spec = resolve :production, 'production' => 'abstract://foo?encoding=utf8' + spec = resolve :production, "production" => "abstract://foo?encoding=utf8" assert_equal({ "adapter" => "abstract", "host" => "foo", - "encoding" => "utf8" }, spec) + "encoding" => "utf8", + "name" => "production" }, spec) end def test_url_sub_key - spec = resolve :production, 'production' => {"url" => 'abstract://foo?encoding=utf8'} + spec = resolve :production, "production" => { "url" => "abstract://foo?encoding=utf8" } assert_equal({ "adapter" => "abstract", "host" => "foo", - "encoding" => "utf8" }, spec) + "encoding" => "utf8", + "name" => "production" }, spec) end def test_url_sub_key_merges_correctly - hash = {"url" => 'abstract://foo?encoding=utf8&', "adapter" => "sqlite3", "host" => "bar", "pool" => "3"} - spec = resolve :production, 'production' => hash + hash = { "url" => "abstract://foo?encoding=utf8&", "adapter" => "sqlite3", "host" => "bar", "pool" => "3" } + spec = resolve :production, "production" => hash assert_equal({ "adapter" => "abstract", "host" => "foo", "encoding" => "utf8", - "pool" => "3" }, spec) + "pool" => "3", + "name" => "production" }, spec) end def test_url_host_no_db - spec = resolve 'abstract://foo?encoding=utf8' + spec = resolve "abstract://foo?encoding=utf8" assert_equal({ "adapter" => "abstract", "host" => "foo", @@ -58,13 +61,13 @@ module ActiveRecord end def test_url_missing_scheme - spec = resolve 'foo' + spec = resolve "foo" assert_equal({ "database" => "foo" }, spec) end def test_url_host_db - spec = resolve 'abstract://foo/bar?encoding=utf8' + spec = resolve "abstract://foo/bar?encoding=utf8" assert_equal({ "adapter" => "abstract", "database" => "bar", @@ -73,7 +76,7 @@ module ActiveRecord end def test_url_port - spec = resolve 'abstract://foo:123?encoding=utf8' + spec = resolve "abstract://foo:123?encoding=utf8" assert_equal({ "adapter" => "abstract", "port" => 123, @@ -82,40 +85,50 @@ module ActiveRecord end def test_encoded_password - password = 'am@z1ng_p@ssw0rd#!' + password = "am@z1ng_p@ssw0rd#!" encoded_password = URI.encode_www_form_component(password) spec = resolve "abstract://foo:#{encoded_password}@localhost/bar" assert_equal password, spec["password"] end def test_url_with_authority_for_sqlite3 - spec = resolve 'sqlite3:///foo_test' - assert_equal('/foo_test', spec["database"]) + spec = resolve "sqlite3:///foo_test" + assert_equal("/foo_test", spec["database"]) end def test_url_absolute_path_for_sqlite3 - spec = resolve 'sqlite3:/foo_test' - assert_equal('/foo_test', spec["database"]) + spec = resolve "sqlite3:/foo_test" + assert_equal("/foo_test", spec["database"]) end def test_url_relative_path_for_sqlite3 - spec = resolve 'sqlite3:foo_test' - assert_equal('foo_test', spec["database"]) + spec = resolve "sqlite3:foo_test" + assert_equal("foo_test", spec["database"]) end def test_url_memory_db_for_sqlite3 - spec = resolve 'sqlite3::memory:' - assert_equal(':memory:', spec["database"]) + spec = resolve "sqlite3::memory:" + assert_equal(":memory:", spec["database"]) end def test_url_sub_key_for_sqlite3 - spec = resolve :production, 'production' => {"url" => 'sqlite3:foo?encoding=utf8'} + spec = resolve :production, "production" => { "url" => "sqlite3:foo?encoding=utf8" } assert_equal({ "adapter" => "sqlite3", "database" => "foo", - "encoding" => "utf8" }, spec) + "encoding" => "utf8", + "name" => "production" }, spec) + end + + def test_spec_name_on_key_lookup + spec = spec(:readonly, "readonly" => { "adapter" => "sqlite3" }) + assert_equal "readonly", spec.name end + def test_spec_name_with_inline_config + spec = spec("adapter" => "sqlite3") + assert_equal "primary", spec.name, "should default to primary id" + end end end end diff --git a/activerecord/test/cases/core_test.rb b/activerecord/test/cases/core_test.rb index 3cb98832c5..3735572898 100644 --- a/activerecord/test/cases/core_test.rb +++ b/activerecord/test/cases/core_test.rb @@ -1,8 +1,8 @@ -require 'cases/helper' -require 'models/person' -require 'models/topic' -require 'pp' -require 'active_support/core_ext/string/strip' +require "cases/helper" +require "models/person" +require "models/topic" +require "pp" +require "active_support/core_ext/string/strip" class NonExistentTable < ActiveRecord::Base; end @@ -10,8 +10,8 @@ class CoreTest < ActiveRecord::TestCase fixtures :topics def test_inspect_class - assert_equal 'ActiveRecord::Base', ActiveRecord::Base.inspect - assert_equal 'LoosePerson(abstract)', LoosePerson.inspect + assert_equal "ActiveRecord::Base", ActiveRecord::Base.inspect + assert_equal "LoosePerson(abstract)", LoosePerson.inspect assert_match(/^Topic\(id: integer, title: string/, Topic.inspect) end @@ -25,8 +25,8 @@ class CoreTest < ActiveRecord::TestCase end def test_inspect_limited_select_instance - assert_equal %(#<Topic id: 1>), Topic.all.merge!(:select => 'id', :where => 'id = 1').first.inspect - assert_equal %(#<Topic id: 1, title: "The First Topic">), Topic.all.merge!(:select => 'id, title', :where => 'id = 1').first.inspect + assert_equal %(#<Topic id: 1>), Topic.all.merge!(select: "id", where: "id = 1").first.inspect + assert_equal %(#<Topic id: 1, title: "The First Topic">), Topic.all.merge!(select: "id, title", where: "id = 1").first.inspect end def test_inspect_class_without_table @@ -35,7 +35,7 @@ class CoreTest < ActiveRecord::TestCase def test_pretty_print_new topic = Topic.new - actual = '' + actual = "" PP.pp(topic, StringIO.new(actual)) expected = <<-PRETTY.strip_heredoc #<Topic:0xXXXXXX @@ -58,13 +58,13 @@ class CoreTest < ActiveRecord::TestCase created_at: nil, updated_at: nil> PRETTY - assert actual.start_with?(expected.split('XXXXXX').first) - assert actual.end_with?(expected.split('XXXXXX').last) + assert actual.start_with?(expected.split("XXXXXX").first) + assert actual.end_with?(expected.split("XXXXXX").last) end def test_pretty_print_persisted topic = topics(:first) - actual = '' + actual = "" PP.pp(topic, StringIO.new(actual)) expected = <<-PRETTY.strip_heredoc #<Topic:0x\\w+ @@ -92,11 +92,11 @@ class CoreTest < ActiveRecord::TestCase def test_pretty_print_uninitialized topic = Topic.allocate - actual = '' + actual = "" PP.pp(topic, StringIO.new(actual)) expected = "#<Topic:XXXXXX not initialized>\n" - assert actual.start_with?(expected.split('XXXXXX').first) - assert actual.end_with?(expected.split('XXXXXX').last) + assert actual.start_with?(expected.split("XXXXXX").first) + assert actual.end_with?(expected.split("XXXXXX").last) end def test_pretty_print_overridden_by_inspect @@ -105,7 +105,7 @@ class CoreTest < ActiveRecord::TestCase "inspecting topic" end end - actual = '' + actual = "" PP.pp(subtopic.new, StringIO.new(actual)) assert_equal "inspecting topic\n", actual end diff --git a/activerecord/test/cases/counter_cache_test.rb b/activerecord/test/cases/counter_cache_test.rb index 66b4c3f1ff..84f2c3a465 100644 --- a/activerecord/test/cases/counter_cache_test.rb +++ b/activerecord/test/cases/counter_cache_test.rb @@ -1,30 +1,30 @@ -require 'cases/helper' -require 'models/topic' -require 'models/car' -require 'models/aircraft' -require 'models/wheel' -require 'models/engine' -require 'models/reply' -require 'models/category' -require 'models/categorization' -require 'models/dog' -require 'models/dog_lover' -require 'models/person' -require 'models/friendship' -require 'models/subscriber' -require 'models/subscription' -require 'models/book' +require "cases/helper" +require "models/topic" +require "models/car" +require "models/aircraft" +require "models/wheel" +require "models/engine" +require "models/reply" +require "models/category" +require "models/categorization" +require "models/dog" +require "models/dog_lover" +require "models/person" +require "models/friendship" +require "models/subscriber" +require "models/subscription" +require "models/book" class CounterCacheTest < ActiveRecord::TestCase fixtures :topics, :categories, :categorizations, :cars, :dogs, :dog_lovers, :people, :friendships, :subscribers, :subscriptions, :books class ::SpecialTopic < ::Topic - has_many :special_replies, :foreign_key => 'parent_id' - has_many :lightweight_special_replies, -> { select('topics.id, topics.title') }, :foreign_key => 'parent_id', :class_name => 'SpecialReply' + has_many :special_replies, foreign_key: "parent_id" + has_many :lightweight_special_replies, -> { select("topics.id, topics.title") }, foreign_key: "parent_id", class_name: "SpecialReply" end class ::SpecialReply < ::Reply - belongs_to :special_topic, :foreign_key => 'parent_id', :counter_cache => 'replies_count' + belongs_to :special_topic, foreign_key: "parent_id", counter_cache: "replies_count" end setup do @@ -32,13 +32,13 @@ class CounterCacheTest < ActiveRecord::TestCase end test "increment counter" do - assert_difference '@topic.reload.replies_count' do + assert_difference "@topic.reload.replies_count" do Topic.increment_counter(:replies_count, @topic.id) end end test "decrement counter" do - assert_difference '@topic.reload.replies_count', -1 do + assert_difference "@topic.reload.replies_count", -1 do Topic.decrement_counter(:replies_count, @topic.id) end end @@ -48,7 +48,7 @@ class CounterCacheTest < ActiveRecord::TestCase Topic.increment_counter(:replies_count, @topic.id) # check that it gets reset - assert_difference '@topic.reload.replies_count', -1 do + assert_difference "@topic.reload.replies_count", -1 do Topic.reset_counters(@topic.id, :replies) end end @@ -58,31 +58,31 @@ class CounterCacheTest < ActiveRecord::TestCase Topic.increment_counter(:replies_count, @topic.id) # check that it gets reset - assert_difference '@topic.reload.replies_count', -1 do + assert_difference "@topic.reload.replies_count", -1 do Topic.reset_counters(@topic.id, :replies_count) end end - test 'reset multiple counters' do + test "reset multiple counters" do Topic.update_counters @topic.id, replies_count: 1, unique_replies_count: 1 - assert_difference ['@topic.reload.replies_count', '@topic.reload.unique_replies_count'], -1 do + assert_difference ["@topic.reload.replies_count", "@topic.reload.unique_replies_count"], -1 do Topic.reset_counters(@topic.id, :replies, :unique_replies) end end test "reset counters with string argument" do - Topic.increment_counter('replies_count', @topic.id) + Topic.increment_counter("replies_count", @topic.id) - assert_difference '@topic.reload.replies_count', -1 do - Topic.reset_counters(@topic.id, 'replies') + assert_difference "@topic.reload.replies_count", -1 do + Topic.reset_counters(@topic.id, "replies") end end test "reset counters with modularized and camelized classnames" do - special = SpecialTopic.create!(:title => 'Special') + special = SpecialTopic.create!(title: "Special") SpecialTopic.increment_counter(:replies_count, special.id) - assert_difference 'special.reload.replies_count', -1 do + assert_difference "special.reload.replies_count", -1 do SpecialTopic.reset_counters(special.id, :special_replies) end end @@ -103,10 +103,10 @@ class CounterCacheTest < ActiveRecord::TestCase DogLover.increment_counter(:bred_dogs_count, david.id) DogLover.increment_counter(:trained_dogs_count, david.id) - assert_difference 'david.reload.bred_dogs_count', -1 do + assert_difference "david.reload.bred_dogs_count", -1 do DogLover.reset_counters(david.id, :bred_dogs) end - assert_difference 'david.reload.trained_dogs_count', -1 do + assert_difference "david.reload.trained_dogs_count", -1 do DogLover.reset_counters(david.id, :trained_dogs) end end @@ -116,26 +116,26 @@ class CounterCacheTest < ActiveRecord::TestCase assert_equal 2, category.categorizations.count assert_nil category.categorizations_count - Category.update_counters(category.id, :categorizations_count => category.categorizations.count) + Category.update_counters(category.id, categorizations_count: category.categorizations.count) assert_equal 2, category.reload.categorizations_count end test "update counter for decrement" do - assert_difference '@topic.reload.replies_count', -3 do - Topic.update_counters(@topic.id, :replies_count => -3) + assert_difference "@topic.reload.replies_count", -3 do + Topic.update_counters(@topic.id, replies_count: -3) end end test "update counters of multiple records" do t1, t2 = topics(:first, :second) - assert_difference ['t1.reload.replies_count', 't2.reload.replies_count'], 2 do - Topic.update_counters([t1.id, t2.id], :replies_count => 2) + assert_difference ["t1.reload.replies_count", "t2.reload.replies_count"], 2 do + Topic.update_counters([t1.id, t2.id], replies_count: 2) end end - test 'update multiple counters' do - assert_difference ['@topic.reload.replies_count', '@topic.reload.unique_replies_count'], 2 do + test "update multiple counters" do + assert_difference ["@topic.reload.replies_count", "@topic.reload.unique_replies_count"], 2 do Topic.update_counters @topic.id, replies_count: 2, unique_replies_count: 2 end end @@ -144,7 +144,7 @@ class CounterCacheTest < ActiveRecord::TestCase david, joanna = dog_lovers(:david, :joanna) joanna = joanna # squelch a warning - assert_difference 'joanna.reload.dogs_count', -1 do + assert_difference "joanna.reload.dogs_count", -1 do david.destroy end end @@ -157,12 +157,12 @@ class CounterCacheTest < ActiveRecord::TestCase end test "reset counter of has_many :through association" do - subscriber = subscribers('second') - Subscriber.reset_counters(subscriber.id, 'books') - Subscriber.increment_counter('books_count', subscriber.id) + subscriber = subscribers("second") + Subscriber.reset_counters(subscriber.id, "books") + Subscriber.increment_counter("books_count", subscriber.id) - assert_difference 'subscriber.reload.books_count', -1 do - Subscriber.reset_counters(subscriber.id, 'books') + assert_difference "subscriber.reload.books_count", -1 do + Subscriber.reset_counters(subscriber.id, "books") end end @@ -174,10 +174,10 @@ class CounterCacheTest < ActiveRecord::TestCase end test "reset counter works with select declared on association" do - special = SpecialTopic.create!(:title => 'Special') + special = SpecialTopic.create!(title: "Special") SpecialTopic.increment_counter(:replies_count, special.id) - assert_difference 'special.reload.replies_count', -1 do + assert_difference "special.reload.replies_count", -1 do SpecialTopic.reset_counters(special.id, :lightweight_special_replies) end end @@ -203,11 +203,11 @@ class CounterCacheTest < ActiveRecord::TestCase test "update counters in a polymorphic relationship" do aircraft = Aircraft.create! - assert_difference 'aircraft.reload.wheels_count' do + assert_difference "aircraft.reload.wheels_count" do aircraft.wheels << Wheel.create! end - assert_difference 'aircraft.reload.wheels_count', -1 do + assert_difference "aircraft.reload.wheels_count", -1 do aircraft.wheels.first.destroy end end diff --git a/activerecord/test/cases/custom_locking_test.rb b/activerecord/test/cases/custom_locking_test.rb index 26d015bf71..15c8b684e4 100644 --- a/activerecord/test/cases/custom_locking_test.rb +++ b/activerecord/test/cases/custom_locking_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'models/person' +require "models/person" module ActiveRecord class CustomLockingTest < ActiveRecord::TestCase @@ -7,9 +7,9 @@ module ActiveRecord def test_custom_lock if current_adapter?(:Mysql2Adapter) - assert_match 'SHARE MODE', Person.lock('LOCK IN SHARE MODE').to_sql + assert_match "SHARE MODE", Person.lock("LOCK IN SHARE MODE").to_sql assert_sql(/LOCK IN SHARE MODE/) do - Person.all.merge!(:lock => 'LOCK IN SHARE MODE').find(1) + Person.all.merge!(lock: "LOCK IN SHARE MODE").find(1) end end end diff --git a/activerecord/test/cases/database_statements_test.rb b/activerecord/test/cases/database_statements_test.rb index 3169408ac0..bb16076fd2 100644 --- a/activerecord/test/cases/database_statements_test.rb +++ b/activerecord/test/cases/database_statements_test.rb @@ -5,6 +5,13 @@ class DatabaseStatementsTest < ActiveRecord::TestCase @connection = ActiveRecord::Base.connection end + unless current_adapter?(:OracleAdapter) + def test_exec_insert + result = @connection.exec_insert("INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)", nil, []) + assert_not_nil @connection.send(:last_inserted_id, result) + end + end + def test_insert_should_return_the_inserted_id assert_not_nil return_the_inserted_id(method: :insert) end @@ -21,14 +28,14 @@ class DatabaseStatementsTest < ActiveRecord::TestCase private - def return_the_inserted_id(method:) - # Oracle adapter uses prefetched primary key values from sequence and passes them to connection adapter insert method - if current_adapter?(:OracleAdapter) - sequence_name = "accounts_seq" - id_value = @connection.next_sequence_value(sequence_name) - @connection.send(method, "INSERT INTO accounts (id, firm_id,credit_limit) VALUES (accounts_seq.nextval,42,5000)", nil, :id, id_value, sequence_name) - else - @connection.send(method, "INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)") + def return_the_inserted_id(method:) + # Oracle adapter uses prefetched primary key values from sequence and passes them to connection adapter insert method + if current_adapter?(:OracleAdapter) + sequence_name = "accounts_seq" + id_value = @connection.next_sequence_value(sequence_name) + @connection.send(method, "INSERT INTO accounts (id, firm_id,credit_limit) VALUES (accounts_seq.nextval,42,5000)", nil, :id, id_value, sequence_name) + else + @connection.send(method, "INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)") + end end - end end diff --git a/activerecord/test/cases/invalid_date_test.rb b/activerecord/test/cases/date_test.rb index 426a350379..2edc0415cd 100644 --- a/activerecord/test/cases/invalid_date_test.rb +++ b/activerecord/test/cases/date_test.rb @@ -1,7 +1,19 @@ -require 'cases/helper' -require 'models/topic' +require "cases/helper" +require "models/topic" + +class DateTest < ActiveRecord::TestCase + def test_date_with_time_value + time_value = Time.new(2016, 05, 11, 19, 0, 0) + topic = Topic.create(last_read: time_value) + assert_equal topic, Topic.find_by(last_read: time_value) + end + + def test_date_with_string_value + string_value = "2016-05-11 19:00:00" + topic = Topic.create(last_read: string_value) + assert_equal topic, Topic.find_by(last_read: string_value) + end -class InvalidDateTest < ActiveRecord::TestCase def test_assign_valid_dates valid_dates = [[2007, 11, 30], [1993, 2, 28], [2008, 2, 29]] @@ -19,7 +31,7 @@ class InvalidDateTest < ActiveRecord::TestCase invalid_dates.each do |date_src| assert_nothing_raised do - topic = Topic.new({"last_read(1i)" => date_src[0].to_s, "last_read(2i)" => date_src[1].to_s, "last_read(3i)" => date_src[2].to_s}) + topic = Topic.new("last_read(1i)" => date_src[0].to_s, "last_read(2i)" => date_src[1].to_s, "last_read(3i)" => date_src[2].to_s) # Oracle DATE columns are datetime columns and Oracle adapter returns Time value if current_adapter?(:OracleAdapter) assert_equal(topic.last_read.to_date, Time.local(*date_src).to_date, "The date should be modified according to the behavior of the Time object") diff --git a/activerecord/test/cases/date_time_precision_test.rb b/activerecord/test/cases/date_time_precision_test.rb index f8664d83bd..a1c3c5af9c 100644 --- a/activerecord/test/cases/date_time_precision_test.rb +++ b/activerecord/test/cases/date_time_precision_test.rb @@ -1,88 +1,87 @@ -require 'cases/helper' -require 'support/schema_dumping_helper' +require "cases/helper" +require "support/schema_dumping_helper" if subsecond_precision_supported? -class DateTimePrecisionTest < ActiveRecord::TestCase - include SchemaDumpingHelper - self.use_transactional_tests = false + class DateTimePrecisionTest < ActiveRecord::TestCase + include SchemaDumpingHelper + self.use_transactional_tests = false - class Foo < ActiveRecord::Base; end + class Foo < ActiveRecord::Base; end - setup do - @connection = ActiveRecord::Base.connection - Foo.reset_column_information - end - - teardown do - @connection.drop_table :foos, if_exists: true - end + setup do + @connection = ActiveRecord::Base.connection + Foo.reset_column_information + end - def test_datetime_data_type_with_precision - @connection.create_table(:foos, force: true) - @connection.add_column :foos, :created_at, :datetime, precision: 0 - @connection.add_column :foos, :updated_at, :datetime, precision: 5 - assert_equal 0, Foo.columns_hash['created_at'].precision - assert_equal 5, Foo.columns_hash['updated_at'].precision - end + teardown do + @connection.drop_table :foos, if_exists: true + end - def test_timestamps_helper_with_custom_precision - @connection.create_table(:foos, force: true) do |t| - t.timestamps precision: 4 + def test_datetime_data_type_with_precision + @connection.create_table(:foos, force: true) + @connection.add_column :foos, :created_at, :datetime, precision: 0 + @connection.add_column :foos, :updated_at, :datetime, precision: 5 + assert_equal 0, Foo.columns_hash["created_at"].precision + assert_equal 5, Foo.columns_hash["updated_at"].precision end - assert_equal 4, Foo.columns_hash['created_at'].precision - assert_equal 4, Foo.columns_hash['updated_at'].precision - end - def test_passing_precision_to_datetime_does_not_set_limit - @connection.create_table(:foos, force: true) do |t| - t.timestamps precision: 4 + def test_timestamps_helper_with_custom_precision + @connection.create_table(:foos, force: true) do |t| + t.timestamps precision: 4 + end + assert_equal 4, Foo.columns_hash["created_at"].precision + assert_equal 4, Foo.columns_hash["updated_at"].precision end - assert_nil Foo.columns_hash['created_at'].limit - assert_nil Foo.columns_hash['updated_at'].limit - end - def test_invalid_datetime_precision_raises_error - assert_raises ActiveRecord::ActiveRecordError do + def test_passing_precision_to_datetime_does_not_set_limit @connection.create_table(:foos, force: true) do |t| - t.timestamps precision: 7 + t.timestamps precision: 4 end + assert_nil Foo.columns_hash["created_at"].limit + assert_nil Foo.columns_hash["updated_at"].limit end - end - def test_formatting_datetime_according_to_precision - @connection.create_table(:foos, force: true) do |t| - t.datetime :created_at, precision: 0 - t.datetime :updated_at, precision: 4 + def test_invalid_datetime_precision_raises_error + assert_raises ActiveRecord::ActiveRecordError do + @connection.create_table(:foos, force: true) do |t| + t.timestamps precision: 7 + end + end end - date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999) - Foo.create!(created_at: date, updated_at: date) - assert foo = Foo.find_by(created_at: date) - assert_equal 1, Foo.where(updated_at: date).count - assert_equal date.to_s, foo.created_at.to_s - assert_equal date.to_s, foo.updated_at.to_s - assert_equal 000000, foo.created_at.usec - assert_equal 999900, foo.updated_at.usec - end - def test_schema_dump_includes_datetime_precision - @connection.create_table(:foos, force: true) do |t| - t.timestamps precision: 6 + def test_formatting_datetime_according_to_precision + @connection.create_table(:foos, force: true) do |t| + t.datetime :created_at, precision: 0 + t.datetime :updated_at, precision: 4 + end + date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999) + Foo.create!(created_at: date, updated_at: date) + assert foo = Foo.find_by(created_at: date) + assert_equal 1, Foo.where(updated_at: date).count + assert_equal date.to_s, foo.created_at.to_s + assert_equal date.to_s, foo.updated_at.to_s + assert_equal 000000, foo.created_at.usec + assert_equal 999900, foo.updated_at.usec end - output = dump_table_schema("foos") - assert_match %r{t\.datetime\s+"created_at",\s+precision: 6,\s+null: false$}, output - assert_match %r{t\.datetime\s+"updated_at",\s+precision: 6,\s+null: false$}, output - end - if current_adapter?(:PostgreSQLAdapter) - def test_datetime_precision_with_zero_should_be_dumped + def test_schema_dump_includes_datetime_precision @connection.create_table(:foos, force: true) do |t| - t.timestamps precision: 0 + t.timestamps precision: 6 end output = dump_table_schema("foos") - assert_match %r{t\.datetime\s+"created_at",\s+precision: 0,\s+null: false$}, output - assert_match %r{t\.datetime\s+"updated_at",\s+precision: 0,\s+null: false$}, output + assert_match %r{t\.datetime\s+"created_at",\s+precision: 6,\s+null: false$}, output + assert_match %r{t\.datetime\s+"updated_at",\s+precision: 6,\s+null: false$}, output end - end -end + if current_adapter?(:PostgreSQLAdapter) + def test_datetime_precision_with_zero_should_be_dumped + @connection.create_table(:foos, force: true) do |t| + t.timestamps precision: 0 + end + output = dump_table_schema("foos") + assert_match %r{t\.datetime\s+"created_at",\s+precision: 0,\s+null: false$}, output + assert_match %r{t\.datetime\s+"updated_at",\s+precision: 0,\s+null: false$}, output + end + end + end end diff --git a/activerecord/test/cases/date_time_test.rb b/activerecord/test/cases/date_time_test.rb index 4cbff564aa..3bc08f80ec 100644 --- a/activerecord/test/cases/date_time_test.rb +++ b/activerecord/test/cases/date_time_test.rb @@ -1,12 +1,12 @@ require "cases/helper" -require 'models/topic' -require 'models/task' +require "models/topic" +require "models/task" class DateTimeTest < ActiveRecord::TestCase include InTimeZone def test_saves_both_date_and_time - with_env_tz 'America/New_York' do + with_env_tz "America/New_York" do with_timezone_config default: :utc do time_values = [1807, 2, 10, 15, 30, 45] # create DateTime value with local time zone offset @@ -25,7 +25,7 @@ class DateTimeTest < ActiveRecord::TestCase def test_assign_empty_date_time task = Task.new - task.starting = '' + task.starting = "" task.ending = nil assert_nil task.starting assert_nil task.ending @@ -34,20 +34,20 @@ class DateTimeTest < ActiveRecord::TestCase def test_assign_bad_date_time_with_timezone in_time_zone "Pacific Time (US & Canada)" do task = Task.new - task.starting = '2014-07-01T24:59:59GMT' + task.starting = "2014-07-01T24:59:59GMT" assert_nil task.starting end end def test_assign_empty_date topic = Topic.new - topic.last_read = '' + topic.last_read = "" assert_nil topic.last_read end def test_assign_empty_time topic = Topic.new - topic.bonus_time = '' + topic.bonus_time = "" assert_nil topic.bonus_time end diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb index 067513e24c..fcaff38f82 100644 --- a/activerecord/test/cases/defaults_test.rb +++ b/activerecord/test/cases/defaults_test.rb @@ -1,7 +1,7 @@ require "cases/helper" -require 'support/schema_dumping_helper' -require 'models/default' -require 'models/entrant' +require "support/schema_dumping_helper" +require "models/default" +require "models/entrant" class DefaultTest < ActiveRecord::TestCase def test_nil_defaults_for_not_null_columns @@ -99,7 +99,7 @@ if current_adapter?(:Mysql2Adapter) class MysqlDefaultExpressionTest < ActiveRecord::TestCase include SchemaDumpingHelper - if ActiveRecord::Base.connection.version >= '5.6.0' + if ActiveRecord::Base.connection.version >= "5.6.0" test "schema dump includes default expression" do output = dump_table_schema("datetime_defaults") assert_match %r/t\.datetime\s+"modified_datetime",\s+default: -> { "CURRENT_TIMESTAMP" }/, output @@ -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 '', record.non_null_text - assert_equal '', record.non_null_blob - - assert_nil record.null_text - assert_nil record.null_blob + 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 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/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index a3f8d26100..09bd00291d 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -1,29 +1,12 @@ -require 'cases/helper' -require 'models/topic' # For booleans -require 'models/pirate' # For timestamps -require 'models/parrot' -require 'models/person' # For optimistic locking -require 'models/aircraft' - -class Pirate # Just reopening it, not defining it - attr_accessor :detected_changes_in_after_update # Boolean for if changes are detected - attr_accessor :changes_detected_in_after_update # Actual changes - - after_update :check_changes - -private - # after_save/update and the model itself - # can end up checking dirty status and acting on the results - def check_changes - if self.changed? - self.detected_changes_in_after_update = true - self.changes_detected_in_after_update = self.changes - end - end -end +require "cases/helper" +require "models/topic" # For booleans +require "models/pirate" # For timestamps +require "models/parrot" +require "models/person" # For optimistic locking +require "models/aircraft" class NumericData < ActiveRecord::Base - self.table_name = 'numeric_data' + self.table_name = "numeric_data" end class DirtyTest < ActiveRecord::TestCase @@ -31,7 +14,7 @@ class DirtyTest < ActiveRecord::TestCase # Dummy to force column loads so query counts are clean. def setup - Person.create :first_name => 'foo' + Person.create first_name: "foo" end def test_attribute_changes @@ -41,10 +24,10 @@ class DirtyTest < ActiveRecord::TestCase assert_equal false, pirate.non_validated_parrot_id_changed? # Change catchphrase. - pirate.catchphrase = 'arrr' + pirate.catchphrase = "arrr" assert pirate.catchphrase_changed? assert_nil pirate.catchphrase_was - assert_equal [nil, 'arrr'], pirate.catchphrase_change + assert_equal [nil, "arrr"], pirate.catchphrase_change # Saved - no changes. pirate.save! @@ -52,15 +35,15 @@ class DirtyTest < ActiveRecord::TestCase assert_nil pirate.catchphrase_change # Same value - no changes. - pirate.catchphrase = 'arrr' + pirate.catchphrase = "arrr" assert !pirate.catchphrase_changed? assert_nil pirate.catchphrase_change end def test_time_attributes_changes_with_time_zone - in_time_zone 'Paris' do + in_time_zone "Paris" do target = Class.new(ActiveRecord::Base) - target.table_name = 'pirates' + target.table_name = "pirates" # New record - no changes. pirate = target.new @@ -68,7 +51,7 @@ class DirtyTest < ActiveRecord::TestCase assert_nil pirate.created_on_change # Saved - no changes. - pirate.catchphrase = 'arrrr, time zone!!' + pirate.catchphrase = "arrrr, time zone!!" pirate.save! assert !pirate.created_on_changed? assert_nil pirate.created_on_change @@ -85,9 +68,9 @@ class DirtyTest < ActiveRecord::TestCase end def test_setting_time_attributes_with_time_zone_field_to_itself_should_not_be_marked_as_a_change - in_time_zone 'Paris' do + in_time_zone "Paris" do target = Class.new(ActiveRecord::Base) - target.table_name = 'pirates' + target.table_name = "pirates" pirate = target.create! pirate.created_on = pirate.created_on @@ -96,9 +79,9 @@ class DirtyTest < ActiveRecord::TestCase end def test_time_attributes_changes_without_time_zone_by_skip - in_time_zone 'Paris' do + in_time_zone "Paris" do target = Class.new(ActiveRecord::Base) - target.table_name = 'pirates' + target.table_name = "pirates" target.skip_time_zone_conversion_for_attributes = [:created_on] @@ -108,7 +91,7 @@ class DirtyTest < ActiveRecord::TestCase assert_nil pirate.created_on_change # Saved - no changes. - pirate.catchphrase = 'arrrr, time zone!!' + pirate.catchphrase = "arrrr, time zone!!" pirate.save! assert !pirate.created_on_changed? assert_nil pirate.created_on_change @@ -127,7 +110,7 @@ class DirtyTest < ActiveRecord::TestCase def test_time_attributes_changes_without_time_zone with_timezone_config aware_attributes: false do target = Class.new(ActiveRecord::Base) - target.table_name = 'pirates' + target.table_name = "pirates" # New record - no changes. pirate = target.new @@ -135,7 +118,7 @@ class DirtyTest < ActiveRecord::TestCase assert_nil pirate.created_on_change # Saved - no changes. - pirate.catchphrase = 'arrrr, time zone!!' + pirate.catchphrase = "arrrr, time zone!!" pirate.save! assert !pirate.created_on_changed? assert_nil pirate.created_on_change @@ -151,7 +134,6 @@ class DirtyTest < ActiveRecord::TestCase end end - def test_aliased_attribute_changes # the actual attribute here is name, title is an # alias setup via alias_attribute @@ -159,15 +141,15 @@ class DirtyTest < ActiveRecord::TestCase assert !parrot.title_changed? assert_nil parrot.title_change - parrot.name = 'Sam' + parrot.name = "Sam" assert parrot.title_changed? assert_nil parrot.title_was assert_equal parrot.name_change, parrot.title_change end def test_restore_attribute! - pirate = Pirate.create!(:catchphrase => 'Yar!') - pirate.catchphrase = 'Ahoy!' + pirate = Pirate.create!(catchphrase: "Yar!") + pirate.catchphrase = "Ahoy!" pirate.restore_catchphrase! assert_equal "Yar!", pirate.catchphrase @@ -206,9 +188,9 @@ class DirtyTest < ActiveRecord::TestCase end def test_nullable_datetime_not_marked_as_changed_if_new_value_is_blank - in_time_zone 'Edinburgh' do + in_time_zone "Edinburgh" do target = Class.new(ActiveRecord::Base) - target.table_name = 'topics' + target.table_name = "topics" topic = target.create assert_nil topic.written_on @@ -224,19 +206,19 @@ class DirtyTest < ActiveRecord::TestCase def test_integer_zero_to_string_zero_not_marked_as_changed pirate = Pirate.new pirate.parrot_id = 0 - pirate.catchphrase = 'arrr' + pirate.catchphrase = "arrr" assert pirate.save! assert !pirate.changed? - pirate.parrot_id = '0' + pirate.parrot_id = "0" assert !pirate.changed? end def test_integer_zero_to_integer_zero_not_marked_as_changed pirate = Pirate.new pirate.parrot_id = 0 - pirate.catchphrase = 'arrr' + pirate.catchphrase = "arrr" assert pirate.save! assert !pirate.changed? @@ -246,18 +228,18 @@ class DirtyTest < ActiveRecord::TestCase end def test_float_zero_to_string_zero_not_marked_as_changed - data = NumericData.new :temperature => 0.0 + data = NumericData.new temperature: 0.0 data.save! assert_not data.changed? - data.temperature = '0' + data.temperature = "0" assert_empty data.changes - data.temperature = '0.0' + data.temperature = "0.0" assert_empty data.changes - data.temperature = '0.00' + data.temperature = "0.00" assert_empty data.changes end @@ -269,7 +251,7 @@ class DirtyTest < ActiveRecord::TestCase # check the change from 1 to '' pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties") - pirate.parrot_id = '' + pirate.parrot_id = "" assert pirate.parrot_id_changed? assert_equal([1, nil], pirate.parrot_id_change) pirate.save @@ -283,7 +265,7 @@ class DirtyTest < ActiveRecord::TestCase # check the change from 0 to '' pirate = Pirate.find_by_catchphrase("Yarrrr, me hearties") - pirate.parrot_id = '' + pirate.parrot_id = "" assert pirate.parrot_id_changed? assert_equal([0, nil], pirate.parrot_id_change) end @@ -294,11 +276,11 @@ class DirtyTest < ActiveRecord::TestCase assert_equal [], pirate.changed assert_equal Hash.new, pirate.changes - pirate.catchphrase = 'arrr' + pirate.catchphrase = "arrr" assert pirate.changed? assert_nil pirate.catchphrase_was assert_equal %w(catchphrase), pirate.changed - assert_equal({'catchphrase' => [nil, 'arrr']}, pirate.changes) + assert_equal({ "catchphrase" => [nil, "arrr"] }, pirate.changes) pirate.save assert !pirate.changed? @@ -307,21 +289,21 @@ class DirtyTest < ActiveRecord::TestCase end def test_attribute_will_change! - pirate = Pirate.create!(:catchphrase => 'arr') + pirate = Pirate.create!(catchphrase: "arr") assert !pirate.catchphrase_changed? assert pirate.catchphrase_will_change! assert pirate.catchphrase_changed? - assert_equal ['arr', 'arr'], pirate.catchphrase_change + assert_equal ["arr", "arr"], pirate.catchphrase_change - pirate.catchphrase << ' matey!' + pirate.catchphrase << " matey!" assert pirate.catchphrase_changed? - assert_equal ['arr', 'arr matey!'], pirate.catchphrase_change + assert_equal ["arr", "arr matey!"], pirate.catchphrase_change end def test_association_assignment_changes_foreign_key - pirate = Pirate.create!(:catchphrase => 'jarl') - pirate.parrot = Parrot.create!(:name => 'Lorre') + pirate = Pirate.create!(catchphrase: "jarl") + pirate.parrot = Parrot.create!(name: "Lorre") assert pirate.changed? assert_equal %w(parrot_id), pirate.changed end @@ -332,7 +314,7 @@ class DirtyTest < ActiveRecord::TestCase assert !topic.approved_changed? # Coming from web form. - params = {:topic => {:approved => 1}} + params = { topic: { approved: 1 } } # In the controller. topic.attributes = params[:topic] assert topic.approved? @@ -340,37 +322,37 @@ class DirtyTest < ActiveRecord::TestCase end def test_partial_update - pirate = Pirate.new(:catchphrase => 'foo') + pirate = Pirate.new(catchphrase: "foo") old_updated_on = 1.hour.ago.beginning_of_day with_partial_writes Pirate, false do assert_queries(2) { 2.times { pirate.save! } } - Pirate.where(id: pirate.id).update_all(:updated_on => old_updated_on) + Pirate.where(id: pirate.id).update_all(updated_on: old_updated_on) end with_partial_writes Pirate, true do assert_queries(0) { 2.times { pirate.save! } } assert_equal old_updated_on, pirate.reload.updated_on - assert_queries(1) { pirate.catchphrase = 'bar'; pirate.save! } + assert_queries(1) { pirate.catchphrase = "bar"; pirate.save! } assert_not_equal old_updated_on, pirate.reload.updated_on end end def test_partial_update_with_optimistic_locking - person = Person.new(:first_name => 'foo') + person = Person.new(first_name: "foo") old_lock_version = 1 with_partial_writes Person, false do assert_queries(2) { 2.times { person.save! } } - Person.where(id: person.id).update_all(:first_name => 'baz') + Person.where(id: person.id).update_all(first_name: "baz") end with_partial_writes Person, true do assert_queries(0) { 2.times { person.save! } } assert_equal old_lock_version, person.reload.lock_version - assert_queries(1) { person.first_name = 'bar'; person.save! } + assert_queries(1) { person.first_name = "bar"; person.save! } assert_not_equal old_lock_version, person.reload.lock_version end end @@ -388,7 +370,7 @@ class DirtyTest < ActiveRecord::TestCase end def test_reload_should_clear_changed_attributes - pirate = Pirate.create!(:catchphrase => "shiver me timbers") + pirate = Pirate.create!(catchphrase: "shiver me timbers") pirate.catchphrase = "*hic*" assert pirate.changed? pirate.reload @@ -396,7 +378,7 @@ class DirtyTest < ActiveRecord::TestCase end def test_dup_objects_should_not_copy_dirty_flag_from_creator - pirate = Pirate.create!(:catchphrase => "shiver me timbers") + pirate = Pirate.create!(catchphrase: "shiver me timbers") pirate_dup = pirate.dup pirate_dup.restore_catchphrase! pirate.catchphrase = "I love Rum" @@ -406,7 +388,7 @@ class DirtyTest < ActiveRecord::TestCase def test_reverted_changes_are_not_dirty phrase = "shiver me timbers" - pirate = Pirate.create!(:catchphrase => phrase) + pirate = Pirate.create!(catchphrase: phrase) pirate.catchphrase = "*hic*" assert pirate.changed? pirate.catchphrase = phrase @@ -415,7 +397,7 @@ class DirtyTest < ActiveRecord::TestCase def test_reverted_changes_are_not_dirty_after_multiple_changes phrase = "shiver me timbers" - pirate = Pirate.create!(:catchphrase => phrase) + pirate = Pirate.create!(catchphrase: phrase) 10.times do |i| pirate.catchphrase = "*hic*" * i assert pirate.changed? @@ -425,9 +407,8 @@ class DirtyTest < ActiveRecord::TestCase assert !pirate.changed? end - def test_reverted_changes_are_not_dirty_going_from_nil_to_value_and_back - pirate = Pirate.create!(:catchphrase => "Yar!") + pirate = Pirate.create!(catchphrase: "Yar!") pirate.parrot_id = 1 assert pirate.changed? @@ -442,7 +423,7 @@ class DirtyTest < ActiveRecord::TestCase def test_save_should_store_serialized_attributes_even_with_partial_writes with_partial_writes(Topic) do - topic = Topic.create!(:content => {:a => "a"}) + topic = Topic.create!(content: { a: "a" }) assert_not topic.changed? @@ -463,25 +444,25 @@ class DirtyTest < ActiveRecord::TestCase def test_save_always_should_update_timestamps_when_serialized_attributes_are_present with_partial_writes(Topic) do - topic = Topic.create!(:content => {:a => "a"}) + topic = Topic.create!(content: { a: "a" }) topic.save! updated_at = topic.updated_at travel(1.second) do - topic.content[:hello] = 'world' + topic.content[:hello] = "world" topic.save! end assert_not_equal updated_at, topic.updated_at - assert_equal 'world', topic.content[:hello] + assert_equal "world", topic.content[:hello] end end def test_save_should_not_save_serialized_attribute_with_partial_writes_if_not_present with_partial_writes(Topic) do - Topic.create!(:author_name => 'Bill', :content => {:a => "a"}) - topic = Topic.select('id, author_name').first - topic.update_columns author_name: 'John' + Topic.create!(author_name: "Bill", content: { a: "a" }) + topic = Topic.select("id, author_name").first + topic.update_columns author_name: "John" topic = Topic.first assert_not_nil topic.content end @@ -496,13 +477,13 @@ class DirtyTest < ActiveRecord::TestCase pirate.save! assert_equal 4, pirate.previous_changes.size - assert_equal [nil, "arrr"], pirate.previous_changes['catchphrase'] - assert_equal [nil, pirate.id], pirate.previous_changes['id'] - assert_nil pirate.previous_changes['updated_on'][0] - assert_not_nil pirate.previous_changes['updated_on'][1] - assert_nil pirate.previous_changes['created_on'][0] - assert_not_nil pirate.previous_changes['created_on'][1] - assert !pirate.previous_changes.key?('parrot_id') + assert_equal [nil, "arrr"], pirate.previous_changes["catchphrase"] + assert_equal [nil, pirate.id], pirate.previous_changes["id"] + assert_nil pirate.previous_changes["updated_on"][0] + assert_not_nil pirate.previous_changes["updated_on"][1] + assert_nil pirate.previous_changes["created_on"][0] + assert_not_nil pirate.previous_changes["created_on"][1] + assert !pirate.previous_changes.key?("parrot_id") # original values should be in previous_changes pirate = Pirate.new @@ -512,11 +493,11 @@ class DirtyTest < ActiveRecord::TestCase pirate.save assert_equal 4, pirate.previous_changes.size - assert_equal [nil, "arrr"], pirate.previous_changes['catchphrase'] - assert_equal [nil, pirate.id], pirate.previous_changes['id'] - assert pirate.previous_changes.include?('updated_on') - assert pirate.previous_changes.include?('created_on') - assert !pirate.previous_changes.key?('parrot_id') + assert_equal [nil, "arrr"], pirate.previous_changes["catchphrase"] + assert_equal [nil, pirate.id], pirate.previous_changes["id"] + assert_includes pirate.previous_changes, "updated_on" + assert_includes pirate.previous_changes, "created_on" + assert !pirate.previous_changes.key?("parrot_id") pirate.catchphrase = "Yar!!" pirate.reload @@ -530,11 +511,11 @@ class DirtyTest < ActiveRecord::TestCase pirate.save! assert_equal 2, pirate.previous_changes.size - assert_equal ["arrr", "Me Maties!"], pirate.previous_changes['catchphrase'] - assert_not_nil pirate.previous_changes['updated_on'][0] - assert_not_nil pirate.previous_changes['updated_on'][1] - assert !pirate.previous_changes.key?('parrot_id') - assert !pirate.previous_changes.key?('created_on') + assert_equal ["arrr", "Me Maties!"], pirate.previous_changes["catchphrase"] + assert_not_nil pirate.previous_changes["updated_on"][0] + assert_not_nil pirate.previous_changes["updated_on"][1] + assert !pirate.previous_changes.key?("parrot_id") + assert !pirate.previous_changes.key?("created_on") pirate = Pirate.find_by_catchphrase("Me Maties!") @@ -544,11 +525,11 @@ class DirtyTest < ActiveRecord::TestCase pirate.save assert_equal 2, pirate.previous_changes.size - assert_equal ["Me Maties!", "Thar She Blows!"], pirate.previous_changes['catchphrase'] - assert_not_nil pirate.previous_changes['updated_on'][0] - assert_not_nil pirate.previous_changes['updated_on'][1] - assert !pirate.previous_changes.key?('parrot_id') - assert !pirate.previous_changes.key?('created_on') + assert_equal ["Me Maties!", "Thar She Blows!"], pirate.previous_changes["catchphrase"] + assert_not_nil pirate.previous_changes["updated_on"][0] + assert_not_nil pirate.previous_changes["updated_on"][1] + assert !pirate.previous_changes.key?("parrot_id") + assert !pirate.previous_changes.key?("created_on") travel(1.second) @@ -556,11 +537,11 @@ class DirtyTest < ActiveRecord::TestCase pirate.update(catchphrase: "Ahoy!") assert_equal 2, pirate.previous_changes.size - assert_equal ["Thar She Blows!", "Ahoy!"], pirate.previous_changes['catchphrase'] - assert_not_nil pirate.previous_changes['updated_on'][0] - assert_not_nil pirate.previous_changes['updated_on'][1] - assert !pirate.previous_changes.key?('parrot_id') - assert !pirate.previous_changes.key?('created_on') + assert_equal ["Thar She Blows!", "Ahoy!"], pirate.previous_changes["catchphrase"] + assert_not_nil pirate.previous_changes["updated_on"][0] + assert_not_nil pirate.previous_changes["updated_on"][1] + assert !pirate.previous_changes.key?("parrot_id") + assert !pirate.previous_changes.key?("created_on") travel(1.second) @@ -568,11 +549,11 @@ class DirtyTest < ActiveRecord::TestCase pirate.update_attribute(:catchphrase, "Ninjas suck!") assert_equal 2, pirate.previous_changes.size - assert_equal ["Ahoy!", "Ninjas suck!"], pirate.previous_changes['catchphrase'] - assert_not_nil pirate.previous_changes['updated_on'][0] - assert_not_nil pirate.previous_changes['updated_on'][1] - assert !pirate.previous_changes.key?('parrot_id') - assert !pirate.previous_changes.key?('created_on') + assert_equal ["Ahoy!", "Ninjas suck!"], pirate.previous_changes["catchphrase"] + assert_not_nil pirate.previous_changes["updated_on"][0] + assert_not_nil pirate.previous_changes["updated_on"][1] + assert !pirate.previous_changes.key?("parrot_id") + assert !pirate.previous_changes.key?("created_on") ensure travel_back end @@ -593,24 +574,24 @@ class DirtyTest < ActiveRecord::TestCase def test_datetime_attribute_can_be_updated_with_fractional_seconds skip "Fractional seconds are not supported" unless subsecond_precision_supported? - in_time_zone 'Paris' do + in_time_zone "Paris" do target = Class.new(ActiveRecord::Base) - target.table_name = 'topics' + target.table_name = "topics" - written_on = Time.utc(2012, 12, 1, 12, 0, 0).in_time_zone('Paris') + written_on = Time.utc(2012, 12, 1, 12, 0, 0).in_time_zone("Paris") - topic = target.create(:written_on => written_on) + topic = target.create(written_on: written_on) topic.written_on += 0.3 - assert topic.written_on_changed?, 'Fractional second update not detected' + assert topic.written_on_changed?, "Fractional second update not detected" end end def test_datetime_attribute_doesnt_change_if_zone_is_modified_in_string - time_in_paris = Time.utc(2014, 1, 1, 12, 0, 0).in_time_zone('Paris') - pirate = Pirate.create!(:catchphrase => 'rrrr', :created_on => time_in_paris) + time_in_paris = Time.utc(2014, 1, 1, 12, 0, 0).in_time_zone("Paris") + pirate = Pirate.create!(catchphrase: "rrrr", created_on: time_in_paris) - pirate.created_on = pirate.created_on.in_time_zone('Tokyo').to_s + pirate.created_on = pirate.created_on.in_time_zone("Tokyo").to_s assert !pirate.created_on_changed? end @@ -618,13 +599,13 @@ class DirtyTest < ActiveRecord::TestCase with_partial_writes Person do jon = nil assert_sql(/first_name/i) do - jon = Person.create! first_name: 'Jon' + jon = Person.create! first_name: "Jon" end - assert ActiveRecord::SQLCounter.log_all.none? { |sql| sql =~ /followers_count/ } + assert ActiveRecord::SQLCounter.log_all.none? { |sql| sql.include?("followers_count") } jon.reload - assert_equal 'Jon', jon.first_name + assert_equal "Jon", jon.first_name assert_equal 0, jon.followers_count assert_not_nil jon.id end @@ -650,7 +631,7 @@ class DirtyTest < ActiveRecord::TestCase assert_equal("arrrr", pirate.catchphrase_was) assert pirate.catchphrase_changed?(from: "arrrr") assert_not pirate.catchphrase_changed?(from: "anything else") - assert pirate.changed_attributes.include?(:catchphrase) + assert_includes pirate.changed_attributes, :catchphrase pirate.save! pirate.reload @@ -689,7 +670,7 @@ class DirtyTest < ActiveRecord::TestCase end end klass = Class.new(ActiveRecord::Base) do - self.table_name = 'people' + self.table_name = "people" attribute :foo, test_type_class.new end @@ -699,7 +680,7 @@ class DirtyTest < ActiveRecord::TestCase test "attribute_will_change! doesn't try to save non-persistable attributes" do klass = Class.new(ActiveRecord::Base) do - self.table_name = 'people' + self.table_name = "people" attribute :non_persisted_attribute, :string end @@ -734,6 +715,17 @@ class DirtyTest < ActiveRecord::TestCase assert_equal "arr", pirate.catchphrase end + test "attributes assigned but not selected are dirty" do + person = Person.select(:id).first + refute person.changed? + + person.first_name = "Sean" + assert person.changed? + + person.first_name = nil + assert person.changed? + end + private def with_partial_writes(klass, on = true) old = klass.partial_writes? diff --git a/activerecord/test/cases/dup_test.rb b/activerecord/test/cases/dup_test.rb index 638cffe0e6..3821e0c949 100644 --- a/activerecord/test/cases/dup_test.rb +++ b/activerecord/test/cases/dup_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'models/reply' -require 'models/topic' +require "models/reply" +require "models/topic" module ActiveRecord class DupTest < ActiveRecord::TestCase @@ -14,7 +14,7 @@ module ActiveRecord topic = Topic.first duped = topic.dup - assert !duped.readonly?, 'should not be readonly' + assert !duped.readonly?, "should not be readonly" end def test_is_readonly @@ -22,15 +22,15 @@ module ActiveRecord topic.readonly! duped = topic.dup - assert duped.readonly?, 'should be readonly' + assert duped.readonly?, "should be readonly" end def test_dup_not_persisted topic = Topic.first duped = topic.dup - assert !duped.persisted?, 'topic not persisted' - assert duped.new_record?, 'topic is new' + assert !duped.persisted?, "topic not persisted" + assert duped.new_record?, "topic is new" end def test_dup_not_destroyed @@ -49,9 +49,9 @@ module ActiveRecord def test_dup_with_modified_attributes topic = Topic.first - topic.author_name = 'Aaron' + topic.author_name = "Aaron" duped = topic.dup - assert_equal 'Aaron', duped.author_name + assert_equal "Aaron", duped.author_name end def test_dup_with_changes @@ -71,10 +71,10 @@ module ActiveRecord def test_dup_topics_are_independent topic = Topic.first - topic.author_name = 'Aaron' + topic.author_name = "Aaron" duped = topic.dup - duped.author_name = 'meow' + duped.author_name = "meow" assert_not_equal topic.changes, duped.changes end @@ -83,11 +83,11 @@ module ActiveRecord topic = Topic.first duped = topic.dup - duped.author_name = 'meow' - topic.author_name = 'Aaron' + duped.author_name = "meow" + topic.author_name = "Aaron" - assert_equal 'Aaron', topic.author_name - assert_equal 'meow', duped.author_name + assert_equal "Aaron", topic.author_name + assert_equal "meow", duped.author_name end def test_dup_timestamps_are_cleared @@ -127,7 +127,7 @@ module ActiveRecord assert duped.invalid? topic.title = nil - duped.title = 'Mathematics' + duped.title = "Mathematics" assert topic.invalid? assert duped.valid? end @@ -135,8 +135,8 @@ module ActiveRecord def test_dup_with_default_scope prev_default_scopes = Topic.default_scopes - Topic.default_scopes = [proc { Topic.where(:approved => true) }] - topic = Topic.new(:approved => false) + Topic.default_scopes = [proc { Topic.where(approved: true) }] + topic = Topic.new(approved: false) assert !topic.dup.approved?, "should not be overridden by default scopes" ensure Topic.default_scopes = prev_default_scopes @@ -144,7 +144,7 @@ module ActiveRecord def test_dup_without_primary_key klass = Class.new(ActiveRecord::Base) do - self.table_name = 'parrots_pirates' + self.table_name = "parrots_pirates" end record = klass.create! diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index babacd1ee9..b7641fcf32 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -1,5 +1,5 @@ -require 'cases/helper' -require 'models/book' +require "cases/helper" +require "models/book" class EnumTest < ActiveRecord::TestCase fixtures :books @@ -18,6 +18,7 @@ class EnumTest < ActiveRecord::TestCase assert @book.author_visibility_visible? assert @book.illustrator_visibility_visible? assert @book.with_medium_font_size? + assert @book.medium_to_read? end test "query state with strings" do @@ -26,6 +27,7 @@ class EnumTest < ActiveRecord::TestCase assert_equal "english", @book.language assert_equal "visible", @book.author_visibility assert_equal "visible", @book.illustrator_visibility + assert_equal "medium", @book.difficulty end test "find via scope" do @@ -34,6 +36,7 @@ class EnumTest < ActiveRecord::TestCase assert_equal @book, Book.in_english.first assert_equal @book, Book.author_visibility_visible.first assert_equal @book, Book.illustrator_visibility_visible.first + assert_equal @book, Book.medium_to_read.first end test "find via where with values" do @@ -122,8 +125,8 @@ class EnumTest < ActiveRecord::TestCase old_language = @book.language @book.status = :proposed @book.language = :spanish - assert_equal [old_status, 'proposed'], @book.changes[:status] - assert_equal [old_language, 'spanish'], @book.changes[:language] + assert_equal [old_status, "proposed"], @book.changes[:status] + assert_equal [old_language, "spanish"], @book.changes[:language] end test "enum attribute was" do @@ -145,8 +148,8 @@ class EnumTest < ActiveRecord::TestCase test "enum attribute changed to" do @book.status = :proposed @book.language = :french - assert @book.attribute_changed?(:status, to: 'proposed') - assert @book.attribute_changed?(:language, to: 'french') + assert @book.attribute_changed?(:status, to: "proposed") + assert @book.attribute_changed?(:language, to: "french") end test "enum attribute changed from" do @@ -163,8 +166,8 @@ class EnumTest < ActiveRecord::TestCase old_language = @book.language @book.status = :proposed @book.language = :french - assert @book.attribute_changed?(:status, from: old_status, to: 'proposed') - assert @book.attribute_changed?(:language, from: old_language, to: 'french') + assert @book.attribute_changed?(:status, from: old_status, to: "proposed") + assert @book.attribute_changed?(:language, from: old_language, to: "french") end test "enum didn't change" do @@ -216,12 +219,12 @@ class EnumTest < ActiveRecord::TestCase end test "assign empty string value" do - @book.status = '' + @book.status = "" assert_nil @book.status end test "assign long empty string value" do - @book.status = ' ' + @book.status = " " assert_nil @book.status end @@ -318,7 +321,7 @@ class EnumTest < ActiveRecord::TestCase test "validate uniqueness" do klass = Class.new(ActiveRecord::Base) do - def self.name; 'Book'; end + def self.name; "Book"; end enum status: [:proposed, :written] validates_uniqueness_of :status end @@ -332,7 +335,7 @@ class EnumTest < ActiveRecord::TestCase test "validate inclusion of value in array" do klass = Class.new(ActiveRecord::Base) do - def self.name; 'Book'; end + def self.name; "Book"; end enum status: [:proposed, :written] validates_inclusion_of :status, in: ["written"] end @@ -356,11 +359,11 @@ class EnumTest < ActiveRecord::TestCase book1 = klass1.proposed.create! book1.status = :written - assert_equal ['proposed', 'written'], book1.status_change + assert_equal ["proposed", "written"], book1.status_change book2 = klass2.drafted.create! book2.status = :uploaded - assert_equal ['drafted', 'uploaded'], book2.status_change + assert_equal ["drafted", "uploaded"], book2.status_change end test "enums are inheritable" do @@ -372,11 +375,11 @@ class EnumTest < ActiveRecord::TestCase book1 = subklass1.proposed.create! book1.status = :written - assert_equal ['proposed', 'written'], book1.status_change + assert_equal ["proposed", "written"], book1.status_change book2 = subklass2.drafted.create! book2.status = :uploaded - assert_equal ['drafted', 'uploaded'], book2.status_change + assert_equal ["drafted", "uploaded"], book2.status_change end test "declare multiple enums at a time" do @@ -393,6 +396,22 @@ class EnumTest < ActiveRecord::TestCase assert book2.single? end + test "enum with alias_attribute" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = "books" + alias_attribute :aliased_status, :status + enum aliased_status: [:proposed, :written, :published] + end + + book = klass.proposed.create! + assert book.proposed? + assert_equal "proposed", book.aliased_status + + book = klass.find(book.id) + assert book.proposed? + assert_equal "proposed", book.aliased_status + end + test "query state by predicate with prefix" do assert @book.author_visibility_visible? assert_not @book.author_visibility_invisible? @@ -406,6 +425,43 @@ class EnumTest < ActiveRecord::TestCase assert_not @book.in_french? end + test "query state by predicate with custom suffix" do + assert @book.medium_to_read? + assert_not @book.easy_to_read? + assert_not @book.hard_to_read? + end + + test "enum methods with custom suffix defined" do + assert @book.class.respond_to?(:easy_to_read) + assert @book.class.respond_to?(:medium_to_read) + assert @book.class.respond_to?(:hard_to_read) + + assert @book.respond_to?(:easy_to_read?) + assert @book.respond_to?(:medium_to_read?) + assert @book.respond_to?(:hard_to_read?) + + assert @book.respond_to?(:easy_to_read!) + assert @book.respond_to?(:medium_to_read!) + assert @book.respond_to?(:hard_to_read!) + end + + test "update enum attributes with custom suffix" do + @book.medium_to_read! + assert_not @book.easy_to_read? + assert @book.medium_to_read? + assert_not @book.hard_to_read? + + @book.easy_to_read! + assert @book.easy_to_read? + assert_not @book.medium_to_read? + assert_not @book.hard_to_read? + + @book.hard_to_read! + assert_not @book.easy_to_read? + assert_not @book.medium_to_read? + assert @book.hard_to_read? + end + test "uses default status when no status is provided in fixtures" do book = books(:tlg) assert book.proposed?, "expected fixture to default to proposed status" @@ -421,4 +477,8 @@ class EnumTest < ActiveRecord::TestCase book = Book.new assert book.hard? end + + test "data type of Enum type" do + assert_equal :integer, Book.type_for_attribute("status").type + end end diff --git a/activerecord/test/cases/explain_subscriber_test.rb b/activerecord/test/cases/explain_subscriber_test.rb index 2dee8a26a5..ca87e04012 100644 --- a/activerecord/test/cases/explain_subscriber_test.rb +++ b/activerecord/test/cases/explain_subscriber_test.rb @@ -1,6 +1,6 @@ -require 'cases/helper' -require 'active_record/explain_subscriber' -require 'active_record/explain_registry' +require "cases/helper" +require "active_record/explain_subscriber" +require "active_record/explain_registry" if ActiveRecord::Base.connection.supports_explain? class ExplainSubscriberTest < ActiveRecord::TestCase @@ -25,31 +25,31 @@ if ActiveRecord::Base.connection.supports_explain? def test_collects_nothing_if_collect_is_false ActiveRecord::ExplainRegistry.collect = false - SUBSCRIBER.finish(nil, nil, name: 'SQL', sql: 'select 1 from users', binds: [1, 2]) + SUBSCRIBER.finish(nil, nil, name: "SQL", sql: "select 1 from users", binds: [1, 2]) assert queries.empty? end def test_collects_pairs_of_queries_and_binds - sql = 'select 1 from users' + sql = "select 1 from users" binds = [1, 2] - SUBSCRIBER.finish(nil, nil, name: 'SQL', sql: sql, binds: binds) + SUBSCRIBER.finish(nil, nil, name: "SQL", sql: sql, binds: binds) assert_equal 1, queries.size assert_equal sql, queries[0][0] assert_equal binds, queries[0][1] end def test_collects_nothing_if_the_statement_is_not_whitelisted - SUBSCRIBER.finish(nil, nil, name: 'SQL', sql: 'SHOW max_identifier_length') + SUBSCRIBER.finish(nil, nil, name: "SQL", sql: "SHOW max_identifier_length") assert queries.empty? end def test_collects_nothing_if_the_statement_is_only_partially_matched - SUBSCRIBER.finish(nil, nil, name: 'SQL', sql: 'select_db yo_mama') + SUBSCRIBER.finish(nil, nil, name: "SQL", sql: "select_db yo_mama") assert queries.empty? end def test_collects_cte_queries - SUBSCRIBER.finish(nil, nil, name: 'SQL', sql: 'with s as (values(3)) select 1 from s') + SUBSCRIBER.finish(nil, nil, name: "SQL", sql: "with s as (values(3)) select 1 from s") assert_equal 1, queries.size end diff --git a/activerecord/test/cases/explain_test.rb b/activerecord/test/cases/explain_test.rb index 64dfd86ce2..86fe90ae51 100644 --- a/activerecord/test/cases/explain_test.rb +++ b/activerecord/test/cases/explain_test.rb @@ -1,6 +1,6 @@ -require 'cases/helper' -require 'models/car' -require 'active_support/core_ext/string/strip' +require "cases/helper" +require "models/car" +require "active_support/core_ext/string/strip" if ActiveRecord::Base.connection.supports_explain? class ExplainTest < ActiveRecord::TestCase @@ -15,13 +15,13 @@ if ActiveRecord::Base.connection.supports_explain? end def test_relation_explain - message = Car.where(:name => 'honda').explain + message = Car.where(name: "honda").explain assert_match(/^EXPLAIN for:/, message) end def test_collecting_queries_for_explain queries = ActiveRecord::Base.collecting_queries_for_explain do - Car.where(:name => 'honda').to_a + Car.where(name: "honda").to_a end sql, binds = queries[0] @@ -30,7 +30,7 @@ if ActiveRecord::Base.connection.supports_explain? assert_equal 1, binds.length assert_equal "honda", binds.last.value else - assert_match 'honda', sql + assert_match "honda", sql end end @@ -40,17 +40,14 @@ if ActiveRecord::Base.connection.supports_explain? queries = sqls.zip(binds) stub_explain_for_query_plans do - expected = sqls.map {|sql| "EXPLAIN for: #{sql}\nquery plan #{sql}"}.join("\n") + expected = sqls.map { |sql| "EXPLAIN for: #{sql}\nquery plan #{sql}" }.join("\n") assert_equal expected, base.exec_explain(queries) end end def test_exec_explain_with_binds - object = Struct.new(:name) - cols = [object.new('wadus'), object.new('chaflan')] - sqls = %w(foo bar) - binds = [[[cols[0], 1]], [[cols[1], 2]]] + binds = [[bind_param("wadus", 1)], [bind_param("chaflan", 2)]] queries = sqls.zip(binds) stub_explain_for_query_plans(["query plan foo\n", "query plan bar\n"]) do @@ -68,20 +65,23 @@ if ActiveRecord::Base.connection.supports_explain? def test_unsupported_connection_adapter connection.stub(:supports_explain?, false) do assert_not_called(base.logger, :warn) do - Car.where(:name => 'honda').to_a + Car.where(name: "honda").to_a end end end private - def stub_explain_for_query_plans(query_plans = ['query plan foo', 'query plan bar']) + def stub_explain_for_query_plans(query_plans = ["query plan foo", "query plan bar"]) explain_called = 0 - connection.stub(:explain, proc{ explain_called += 1; query_plans[explain_called - 1] }) do + connection.stub(:explain, proc { explain_called += 1; query_plans[explain_called - 1] }) do yield end end + def bind_param(name, value) + ActiveRecord::Relation::QueryAttribute.new(name, value, ActiveRecord::Type::Value.new) + end end end diff --git a/activerecord/test/cases/finder_respond_to_test.rb b/activerecord/test/cases/finder_respond_to_test.rb index 6ab2657c44..3eaa993d45 100644 --- a/activerecord/test/cases/finder_respond_to_test.rb +++ b/activerecord/test/cases/finder_respond_to_test.rb @@ -1,8 +1,7 @@ require "cases/helper" -require 'models/topic' +require "models/topic" class FinderRespondToTest < ActiveRecord::TestCase - fixtures :topics def test_should_preserve_normal_respond_to_behaviour_on_base @@ -11,7 +10,7 @@ class FinderRespondToTest < ActiveRecord::TestCase end def test_should_preserve_normal_respond_to_behaviour_and_respond_to_newly_added_method - class << Topic; self; end.send(:define_method, :method_added_for_finder_respond_to_test) { } + class << Topic; self; end.send(:define_method, :method_added_for_finder_respond_to_test) {} assert_respond_to Topic, :method_added_for_finder_respond_to_test ensure class << Topic; self; end.send(:remove_method, :method_added_for_finder_respond_to_test) @@ -54,7 +53,7 @@ class FinderRespondToTest < ActiveRecord::TestCase private - def ensure_topic_method_is_not_cached(method_id) - class << Topic; self; end.send(:remove_method, method_id) if Topic.public_methods.include? method_id - end + def ensure_topic_method_is_not_cached(method_id) + class << Topic; self; end.send(:remove_method, method_id) if Topic.public_methods.include? method_id + end end diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index f03df2d99e..51563b347c 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -1,35 +1,35 @@ require "cases/helper" -require 'models/post' -require 'models/author' -require 'models/categorization' -require 'models/comment' -require 'models/company' -require 'models/tagging' -require 'models/topic' -require 'models/reply' -require 'models/entrant' -require 'models/project' -require 'models/developer' -require 'models/computer' -require 'models/customer' -require 'models/toy' -require 'models/matey' -require 'models/dog' -require 'models/car' -require 'models/tyre' +require "models/post" +require "models/author" +require "models/categorization" +require "models/comment" +require "models/company" +require "models/tagging" +require "models/topic" +require "models/reply" +require "models/entrant" +require "models/project" +require "models/developer" +require "models/computer" +require "models/customer" +require "models/toy" +require "models/matey" +require "models/dog" +require "models/car" +require "models/tyre" class FinderTest < ActiveRecord::TestCase fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :author_addresses, :customers, :categories, :categorizations, :cars def test_find_by_id_with_hash - assert_raises(ActiveRecord::StatementInvalid) do - Post.find_by_id(:limit => 1) + assert_nothing_raised do + Post.find_by_id(limit: 1) end end def test_find_by_title_and_id_with_hash - assert_raises(ActiveRecord::StatementInvalid) do - Post.find_by_title_and_id('foo', :limit => 1) + assert_nothing_raised do + Post.find_by_title_and_id("foo", limit: 1) end end @@ -50,53 +50,53 @@ class FinderTest < ActiveRecord::TestCase def test_find_with_ids_returning_ordered records = Topic.find([4,2,5]) - assert_equal 'The Fourth Topic of the day', records[0].title - assert_equal 'The Second Topic of the day', records[1].title - assert_equal 'The Fifth Topic of the day', records[2].title + assert_equal "The Fourth Topic of the day", records[0].title + assert_equal "The Second Topic of the day", records[1].title + assert_equal "The Fifth Topic of the day", records[2].title records = Topic.find(4,2,5) - assert_equal 'The Fourth Topic of the day', records[0].title - assert_equal 'The Second Topic of the day', records[1].title - assert_equal 'The Fifth Topic of the day', records[2].title + assert_equal "The Fourth Topic of the day", records[0].title + assert_equal "The Second Topic of the day", records[1].title + assert_equal "The Fifth Topic of the day", records[2].title - records = Topic.find(['4','2','5']) - assert_equal 'The Fourth Topic of the day', records[0].title - assert_equal 'The Second Topic of the day', records[1].title - assert_equal 'The Fifth Topic of the day', records[2].title + records = Topic.find(["4","2","5"]) + assert_equal "The Fourth Topic of the day", records[0].title + assert_equal "The Second Topic of the day", records[1].title + assert_equal "The Fifth Topic of the day", records[2].title - records = Topic.find('4','2','5') - assert_equal 'The Fourth Topic of the day', records[0].title - assert_equal 'The Second Topic of the day', records[1].title - assert_equal 'The Fifth Topic of the day', records[2].title + records = Topic.find("4","2","5") + assert_equal "The Fourth Topic of the day", records[0].title + assert_equal "The Second Topic of the day", records[1].title + assert_equal "The Fifth Topic of the day", records[2].title end def test_find_with_ids_and_order_clause # The order clause takes precedence over the informed ids records = Topic.order(:author_name).find([5,3,1]) - assert_equal 'The Third Topic of the day', records[0].title - assert_equal 'The First Topic', records[1].title - assert_equal 'The Fifth Topic of the day', records[2].title + assert_equal "The Third Topic of the day", records[0].title + assert_equal "The First Topic", records[1].title + assert_equal "The Fifth Topic of the day", records[2].title records = Topic.order(:id).find([5,3,1]) - assert_equal 'The First Topic', records[0].title - assert_equal 'The Third Topic of the day', records[1].title - assert_equal 'The Fifth Topic of the day', records[2].title + assert_equal "The First Topic", records[0].title + assert_equal "The Third Topic of the day", records[1].title + assert_equal "The Fifth Topic of the day", records[2].title end def test_find_with_ids_with_limit_and_order_clause # The order clause takes precedence over the informed ids records = Topic.limit(2).order(:id).find([5,3,1]) assert_equal 2, records.size - assert_equal 'The First Topic', records[0].title - assert_equal 'The Third Topic of the day', records[1].title + assert_equal "The First Topic", records[0].title + assert_equal "The Third Topic of the day", records[1].title end def test_find_with_ids_and_limit records = Topic.limit(3).find([3,2,5,1,4]) assert_equal 3, records.size - assert_equal 'The Third Topic of the day', records[0].title - assert_equal 'The Second Topic of the day', records[1].title - assert_equal 'The Fifth Topic of the day', records[2].title + assert_equal "The Third Topic of the day", records[0].title + assert_equal "The Second Topic of the day", records[1].title + assert_equal "The Fifth Topic of the day", records[2].title end def test_find_with_ids_where_and_limit @@ -104,17 +104,17 @@ class FinderTest < ActiveRecord::TestCase # if it were among the first 3 it would raise an ActiveRecord::RecordNotFound records = Topic.where(approved: true).limit(3).find([3,2,5,1,4]) assert_equal 3, records.size - assert_equal 'The Third Topic of the day', records[0].title - assert_equal 'The Second Topic of the day', records[1].title - assert_equal 'The Fifth Topic of the day', records[2].title + assert_equal "The Third Topic of the day", records[0].title + assert_equal "The Second Topic of the day", records[1].title + assert_equal "The Fifth Topic of the day", records[2].title end def test_find_with_ids_and_offset records = Topic.offset(2).find([3,2,5,1,4]) assert_equal 3, records.size - assert_equal 'The Fifth Topic of the day', records[0].title - assert_equal 'The First Topic', records[1].title - assert_equal 'The Fourth Topic of the day', records[2].title + assert_equal "The Fifth Topic of the day", records[0].title + assert_equal "The First Topic", records[1].title + assert_equal "The Fourth Topic of the day", records[2].title end def test_find_passing_active_record_object_is_deprecated @@ -127,7 +127,7 @@ class FinderTest < ActiveRecord::TestCase gc_disabled = GC.disable Post.where("author_id" => nil) # warm up x = Symbol.all_symbols.count - Post.where("title" => {"xxxqqqq" => "bar"}) + Post.where("title" => { "xxxqqqq" => "bar" }) assert_equal x, Symbol.all_symbols.count ensure GC.enable if gc_disabled == false @@ -144,7 +144,7 @@ class FinderTest < ActiveRecord::TestCase assert_equal true, Topic.exists?("1") assert_equal true, Topic.exists?(title: "The First Topic") assert_equal true, Topic.exists?(heading: "The First Topic") - assert_equal true, Topic.exists?(:author_name => "Mary", :approved => true) + assert_equal true, Topic.exists?(author_name: "Mary", approved: true) assert_equal true, Topic.exists?(["parent_id = ?", 1]) assert_equal true, Topic.exists?(id: [1, 9999]) @@ -155,11 +155,11 @@ class FinderTest < ActiveRecord::TestCase end def test_exists_with_polymorphic_relation - post = Post.create!(title: 'Post', body: 'default', taggings: [Tagging.new(comment: 'tagging comment')]) - relation = Post.tagged_with_comment('tagging comment') + post = Post.create!(title: "Post", body: "default", taggings: [Tagging.new(comment: "tagging comment")]) + relation = Post.tagged_with_comment("tagging comment") - assert_equal true, relation.exists?(title: ['Post']) - assert_equal true, relation.exists?(['title LIKE ?', 'Post%']) + assert_equal true, relation.exists?(title: ["Post"]) + assert_equal true, relation.exists?(["title LIKE ?", "Post%"]) assert_equal true, relation.exists? assert_equal true, relation.exists?(post.id) assert_equal true, relation.exists?(post.id.to_s) @@ -173,11 +173,9 @@ class FinderTest < ActiveRecord::TestCase end end - def test_exists_fails_when_parameter_has_invalid_type - assert_raises(RangeError) do - assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int - end + def test_exists_returns_false_when_parameter_has_invalid_type assert_equal false, Topic.exists?("foo") + assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int end def test_exists_does_not_select_columns_without_alias @@ -211,7 +209,7 @@ class FinderTest < ActiveRecord::TestCase def test_exists_with_includes_limit_and_empty_result assert_equal false, Topic.includes(:replies).limit(0).exists? - assert_equal false, Topic.includes(:replies).limit(1).where('0 = 1').exists? + assert_equal false, Topic.includes(:replies).limit(1).where("0 = 1").exists? end def test_exists_with_distinct_association_includes_and_limit @@ -222,8 +220,8 @@ class FinderTest < ActiveRecord::TestCase def test_exists_with_distinct_association_includes_limit_and_order author = Author.first - assert_equal false, author.unique_categorized_posts.includes(:special_comments).order('comments.tags_count DESC').limit(0).exists? - assert_equal true, author.unique_categorized_posts.includes(:special_comments).order('comments.tags_count DESC').limit(1).exists? + assert_equal false, author.unique_categorized_posts.includes(:special_comments).order("comments.tags_count DESC").limit(0).exists? + assert_equal true, author.unique_categorized_posts.includes(:special_comments).order("comments.tags_count DESC").limit(1).exists? end def test_exists_with_empty_table_and_no_args_given @@ -233,17 +231,14 @@ class FinderTest < ActiveRecord::TestCase def test_exists_with_aggregate_having_three_mappings existing_address = customers(:david).address - assert_equal true, Customer.exists?(:address => existing_address) + assert_equal true, Customer.exists?(address: existing_address) end def test_exists_with_aggregate_having_three_mappings_with_one_difference existing_address = customers(:david).address - assert_equal false, Customer.exists?(:address => - Address.new(existing_address.street, existing_address.city, existing_address.country + "1")) - assert_equal false, Customer.exists?(:address => - Address.new(existing_address.street, existing_address.city + "1", existing_address.country)) - assert_equal false, Customer.exists?(:address => - Address.new(existing_address.street + "1", existing_address.city, existing_address.country)) + assert_equal false, Customer.exists?(address: Address.new(existing_address.street, existing_address.city, existing_address.country + "1")) + assert_equal false, Customer.exists?(address: Address.new(existing_address.street, existing_address.city + "1", existing_address.country)) + assert_equal false, Customer.exists?(address: Address.new(existing_address.street + "1", existing_address.city, existing_address.country)) end def test_exists_does_not_instantiate_records @@ -266,7 +261,7 @@ class FinderTest < ActiveRecord::TestCase assert_equal 2, Entrant.limit(2).find([1,3,2]).size entrants = Entrant.limit(3).offset(2).find([1,3,2]) assert_equal 1, entrants.size - assert_equal 'Ruby Guru', entrants.first.name + assert_equal "Ruby Guru", entrants.first.name # Also test an edge case: If you have 11 results, and you set a # limit of 3 and offset of 9, then you should find that there @@ -274,29 +269,29 @@ class FinderTest < ActiveRecord::TestCase devs = Developer.all last_devs = Developer.limit(3).offset(9).find devs.map(&:id) assert_equal 2, last_devs.size - assert_equal 'fixture_10', last_devs[0].name - assert_equal 'Jamis', last_devs[1].name + assert_equal "fixture_10", last_devs[0].name + assert_equal "Jamis", last_devs[1].name end def test_find_with_large_number - assert_raises(ActiveRecord::RecordNotFound) { Topic.find('9999999999999999999999999999999') } + assert_raises(ActiveRecord::RecordNotFound) { Topic.find("9999999999999999999999999999999") } end def test_find_by_with_large_number - assert_nil Topic.find_by(id: '9999999999999999999999999999999') + assert_nil Topic.find_by(id: "9999999999999999999999999999999") end def test_find_by_id_with_large_number - assert_nil Topic.find_by_id('9999999999999999999999999999999') + assert_nil Topic.find_by_id("9999999999999999999999999999999") end def test_find_on_relation_with_large_number - assert_nil Topic.where('1=1').find_by(id: 9999999999999999999999999999999) + assert_nil Topic.where("1=1").find_by(id: 9999999999999999999999999999999) end def test_find_by_bang_on_relation_with_large_number assert_raises(ActiveRecord::RecordNotFound) do - Topic.where('1=1').find_by!(id: 9999999999999999999999999999999) + Topic.where("1=1").find_by!(id: 9999999999999999999999999999999) end end @@ -313,7 +308,7 @@ class FinderTest < ActiveRecord::TestCase end def test_find_with_group_and_sanitized_having_method - developers = Developer.group(:salary).having("sum(salary) > ?", 10000).select('salary').to_a + developers = Developer.group(:salary).having("sum(salary) > ?", 10000).select("salary").to_a assert_equal 3, developers.size assert_equal 3, developers.map(&:salary).uniq.size assert developers.all? { |developer| developer.salary > 10000 } @@ -567,9 +562,9 @@ class FinderTest < ActiveRecord::TestCase end def test_take_and_first_and_last_with_integer_should_use_sql_limit - assert_sql(/LIMIT|ROWNUM <=/) { Topic.take(3).entries } - assert_sql(/LIMIT|ROWNUM <=/) { Topic.first(2).entries } - assert_sql(/LIMIT|ROWNUM <=/) { Topic.last(5).entries } + assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.take(3).entries } + assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.first(2).entries } + assert_sql(/LIMIT|ROWNUM <=|FETCH FIRST/) { Topic.last(5).entries } end def test_last_with_integer_and_order_should_keep_the_order @@ -603,7 +598,7 @@ class FinderTest < ActiveRecord::TestCase end def test_last_on_relation_with_limit_and_offset - post = posts('sti_comments') + post = posts("sti_comments") comments = post.comments.order(id: :asc) assert_equal comments.limit(2).to_a.last, comments.limit(2).last @@ -632,8 +627,8 @@ class FinderTest < ActiveRecord::TestCase def test_find_only_some_columns topic = Topic.select("author_name").find(1) - assert_raise(ActiveModel::MissingAttributeError) {topic.title} - assert_raise(ActiveModel::MissingAttributeError) {topic.title?} + assert_raise(ActiveModel::MissingAttributeError) { topic.title } + assert_raise(ActiveModel::MissingAttributeError) { topic.title? } assert_nil topic.read_attribute("title") assert_equal "David", topic.author_name assert !topic.attribute_present?("title") @@ -653,8 +648,8 @@ class FinderTest < ActiveRecord::TestCase end def test_find_on_hash_conditions_with_qualified_attribute_dot_notation_string - assert Topic.where('topics.approved' => false).find(1) - assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved' => true).find(1) } + assert Topic.where("topics.approved" => false).find(1) + assert_raise(ActiveRecord::RecordNotFound) { Topic.where("topics.approved" => true).find(1) } end def test_find_on_hash_conditions_with_qualified_attribute_dot_notation_symbol @@ -668,28 +663,28 @@ class FinderTest < ActiveRecord::TestCase end def test_find_on_combined_explicit_and_hashed_table_names - assert Topic.where('topics.approved' => false, topics: { author_name: "David" }).find(1) - assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved' => true, topics: { author_name: "David" }).find(1) } - assert_raise(ActiveRecord::RecordNotFound) { Topic.where('topics.approved' => false, topics: { author_name: "Melanie" }).find(1) } + assert Topic.where("topics.approved" => false, topics: { author_name: "David" }).find(1) + assert_raise(ActiveRecord::RecordNotFound) { Topic.where("topics.approved" => true, topics: { author_name: "David" }).find(1) } + assert_raise(ActiveRecord::RecordNotFound) { Topic.where("topics.approved" => false, topics: { author_name: "Melanie" }).find(1) } end def test_find_with_hash_conditions_on_joined_table - firms = Firm.joins(:account).where(:accounts => { :credit_limit => 50 }) + firms = Firm.joins(:account).where(accounts: { credit_limit: 50 }) assert_equal 1, firms.size assert_equal companies(:first_firm), firms.first end def test_find_with_hash_conditions_on_joined_table_and_with_range - firms = DependentFirm.joins(:account).where(name: 'RailsCore', accounts: { credit_limit: 55..60 }) + firms = DependentFirm.joins(:account).where(name: "RailsCore", accounts: { credit_limit: 55..60 }) assert_equal 1, firms.size assert_equal companies(:rails_core), firms.first end def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate david = customers(:david) - assert Customer.where('customers.name' => david.name, :address => david.address).find(david.id) + assert Customer.where("customers.name" => david.name, :address => david.address).find(david.id) assert_raise(ActiveRecord::RecordNotFound) { - Customer.where('customers.name' => david.name + "1", :address => david.address).find(david.id) + Customer.where("customers.name" => david.name + "1", :address => david.address).find(david.id) } end @@ -760,9 +755,9 @@ class FinderTest < ActiveRecord::TestCase end def test_hash_condition_find_with_array - p1, p2 = Post.limit(2).order('id asc').to_a - assert_equal [p1, p2], Post.where(id: [p1, p2]).order('id asc').to_a - assert_equal [p1, p2], Post.where(id: [p1, p2.id]).order('id asc').to_a + p1, p2 = Post.limit(2).order("id asc").to_a + assert_equal [p1, p2], Post.where(id: [p1, p2]).order("id asc").to_a + assert_equal [p1, p2], Post.where(id: [p1, p2.id]).order("id asc").to_a end def test_hash_condition_find_with_nil @@ -774,56 +769,56 @@ class FinderTest < ActiveRecord::TestCase def test_hash_condition_find_with_aggregate_having_one_mapping balance = customers(:david).balance assert_kind_of Money, balance - found_customer = Customer.where(:balance => balance).first + found_customer = Customer.where(balance: balance).first assert_equal customers(:david), found_customer end def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_aggregate gps_location = customers(:david).gps_location assert_kind_of GpsLocation, gps_location - found_customer = Customer.where(:gps_location => gps_location).first + found_customer = Customer.where(gps_location: gps_location).first assert_equal customers(:david), found_customer end def test_hash_condition_find_with_aggregate_having_one_mapping_and_key_value_being_attribute_value balance = customers(:david).balance assert_kind_of Money, balance - found_customer = Customer.where(:balance => balance.amount).first + found_customer = Customer.where(balance: balance.amount).first assert_equal customers(:david), found_customer end def test_hash_condition_find_with_aggregate_attribute_having_same_name_as_field_and_key_value_being_attribute_value gps_location = customers(:david).gps_location assert_kind_of GpsLocation, gps_location - found_customer = Customer.where(:gps_location => gps_location.gps_location).first + found_customer = Customer.where(gps_location: gps_location.gps_location).first assert_equal customers(:david), found_customer end def test_hash_condition_find_with_aggregate_having_three_mappings address = customers(:david).address assert_kind_of Address, address - found_customer = Customer.where(:address => address).first + found_customer = Customer.where(address: address).first assert_equal customers(:david), found_customer end def test_hash_condition_find_with_one_condition_being_aggregate_and_another_not address = customers(:david).address assert_kind_of Address, address - found_customer = Customer.where(:address => address, :name => customers(:david).name).first + found_customer = Customer.where(address: address, name: customers(:david).name).first assert_equal customers(:david), found_customer end def test_condition_utc_time_interpolation_with_default_timezone_local - with_env_tz 'America/New_York' do + with_env_tz "America/New_York" do with_timezone_config default: :local do topic = Topic.first - assert_equal topic, Topic.where(['written_on = ?', topic.written_on.getutc]).first + assert_equal topic, Topic.where(["written_on = ?", topic.written_on.getutc]).first end end end def test_hash_condition_utc_time_interpolation_with_default_timezone_local - with_env_tz 'America/New_York' do + with_env_tz "America/New_York" do with_timezone_config default: :local do topic = Topic.first assert_equal topic, Topic.where(written_on: topic.written_on.getutc).first @@ -832,16 +827,16 @@ class FinderTest < ActiveRecord::TestCase end def test_condition_local_time_interpolation_with_default_timezone_utc - with_env_tz 'America/New_York' do + with_env_tz "America/New_York" do with_timezone_config default: :utc do topic = Topic.first - assert_equal topic, Topic.where(['written_on = ?', topic.written_on.getlocal]).first + assert_equal topic, Topic.where(["written_on = ?", topic.written_on.getlocal]).first end end end def test_hash_condition_local_time_interpolation_with_default_timezone_utc - with_env_tz 'America/New_York' do + with_env_tz "America/New_York" do with_timezone_config default: :utc do topic = Topic.first assert_equal topic, Topic.where(written_on: topic.written_on.getlocal).first @@ -858,7 +853,7 @@ class FinderTest < ActiveRecord::TestCase Company.where(["id=? AND name = ?", 2]).first } assert_raise(ActiveRecord::PreparedStatementInvalid) { - Company.where(["id=?", 2, 3, 4]).first + Company.where(["id=?", 2, 3, 4]).first } end @@ -869,7 +864,7 @@ class FinderTest < ActiveRecord::TestCase def test_named_bind_variables_with_quotes Company.create("name" => "37signals' go'es agains") - assert Company.where(["name = :name", {name: "37signals' go'es agains"}]).first + assert Company.where(["name = :name", { name: "37signals' go'es agains" }]).first end def test_named_bind_variables @@ -879,11 +874,6 @@ class FinderTest < ActiveRecord::TestCase assert_kind_of Time, Topic.where(["id = :id", { id: 1 }]).first.written_on end - def test_string_sanitation - assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1") - assert_equal "'something; select table'", ActiveRecord::Base.sanitize("something; select table") - end - def test_count_by_sql assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3")) assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2])) @@ -903,7 +893,7 @@ class FinderTest < ActiveRecord::TestCase end def test_find_by_on_attribute_that_is_a_reserved_word - dog_alias = 'Dog' + dog_alias = "Dog" dog = Dog.create(alias: dog_alias) assert_equal dog, Dog.find_by_alias(dog_alias) @@ -920,7 +910,7 @@ class FinderTest < ActiveRecord::TestCase end def test_find_by_one_attribute_with_conditions - assert_equal accounts(:rails_core_account), Account.where('firm_id = ?', 6).find_by_credit_limit(50) + assert_equal accounts(:rails_core_account), Account.where("firm_id = ?", 6).find_by_credit_limit(50) end def test_find_by_one_attribute_that_is_an_aggregate @@ -960,12 +950,12 @@ class FinderTest < ActiveRecord::TestCase def test_dynamic_finder_on_one_attribute_with_conditions_returns_same_results_after_caching # ensure this test can run independently of order class << Account; self; end.send(:remove_method, :find_by_credit_limit) if Account.public_methods.include?(:find_by_credit_limit) - a = Account.where('firm_id = ?', 6).find_by_credit_limit(50) - assert_equal a, Account.where('firm_id = ?', 6).find_by_credit_limit(50) # find_by_credit_limit has been cached + a = Account.where("firm_id = ?", 6).find_by_credit_limit(50) + assert_equal a, Account.where("firm_id = ?", 6).find_by_credit_limit(50) # find_by_credit_limit has been cached end def test_find_by_one_attribute_with_several_options - assert_equal accounts(:unknown), Account.order('id DESC').where('id != ?', 3).find_by_credit_limit(50) + assert_equal accounts(:unknown), Account.order("id DESC").where("id != ?", 3).find_by_credit_limit(50) end def test_find_by_one_missing_attribute @@ -989,12 +979,12 @@ class FinderTest < ActiveRecord::TestCase end def test_find_last_with_offset - devs = Developer.order('id') + devs = Developer.order("id") assert_equal devs[2], Developer.offset(2).first assert_equal devs[-3], Developer.offset(2).last assert_equal devs[-3], Developer.offset(2).last - assert_equal devs[-3], Developer.offset(2).order('id DESC').first + assert_equal devs[-3], Developer.offset(2).order("id DESC").first end def test_find_by_nil_attribute @@ -1014,18 +1004,18 @@ class FinderTest < ActiveRecord::TestCase def test_find_all_with_join developers_on_project_one = Developer. - joins('LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id'). - where('project_id=1').to_a + joins("LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id"). + where("project_id=1").to_a assert_equal 3, developers_on_project_one.length developer_names = developers_on_project_one.map(&:name) - assert developer_names.include?('David') - assert developer_names.include?('Jamis') + assert_includes developer_names, "David" + assert_includes developer_names, "Jamis" end def test_joins_dont_clobber_id first = Firm. - joins('INNER JOIN companies clients ON clients.firm_id = companies.id'). - where('companies.id = 1').first + joins("INNER JOIN companies clients ON clients.firm_id = companies.id"). + where("companies.id = 1").first assert_equal 1, first.id end @@ -1044,7 +1034,7 @@ class FinderTest < ActiveRecord::TestCase end def test_find_ignores_previously_inserted_record - Post.create!(:title => 'test', :body => 'it out') + Post.create!(title: "test", body: "it out") assert_equal [], Post.where(id: nil) end @@ -1053,13 +1043,13 @@ class FinderTest < ActiveRecord::TestCase end def test_find_by_empty_in_condition - assert_equal [], Post.where('id in (?)', []) + assert_equal [], Post.where("id in (?)", []) end def test_find_by_records - p1, p2 = Post.limit(2).order('id asc').to_a - assert_equal [p1, p2], Post.where(['id in (?)', [p1, p2]]).order('id asc') - assert_equal [p1, p2], Post.where(['id in (?)', [p1, p2.id]]).order('id asc') + p1, p2 = Post.limit(2).order("id asc").to_a + assert_equal [p1, p2], Post.where(["id in (?)", [p1, p2]]).order("id asc") + assert_equal [p1, p2], Post.where(["id in (?)", [p1, p2.id]]).order("id asc") end def test_select_value @@ -1080,36 +1070,36 @@ class FinderTest < ActiveRecord::TestCase [["1", "1", nil, "37signals"], ["2", "1", "2", "Summit"], ["3", "1", "1", "Microsoft"]], - Company.connection.select_rows("SELECT id, firm_id, client_of, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! {|i| i.map! {|j| j.to_s unless j.nil?}}) + Company.connection.select_rows("SELECT id, firm_id, client_of, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! { |i| i.map! { |j| j.to_s unless j.nil? } }) assert_equal [["1", "37signals"], ["2", "Summit"], ["3", "Microsoft"]], - Company.connection.select_rows("SELECT id, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! {|i| i.map! {|j| j.to_s unless j.nil?}} + Company.connection.select_rows("SELECT id, name FROM companies WHERE id IN (1,2,3) ORDER BY id").map! { |i| i.map! { |j| j.to_s unless j.nil? } } end def test_find_with_order_on_included_associations_with_construct_finder_sql_for_association_limiting_and_is_distinct assert_equal 2, Post.includes(authors: :author_address). where.not(author_addresses: { id: nil }). - order('author_addresses.id DESC').limit(2).to_a.size + order("author_addresses.id DESC").limit(2).to_a.size assert_equal 3, Post.includes(author: :author_address, authors: :author_address). where.not(author_addresses_authors: { id: nil }). - order('author_addresses_authors.id DESC').limit(3).to_a.size + order("author_addresses_authors.id DESC").limit(3).to_a.size end def test_find_with_nil_inside_set_passed_for_one_attribute client_of = Company. where(client_of: [2, 1, nil], - name: ['37signals', 'Summit', 'Microsoft']). - order('client_of DESC'). + name: ["37signals", "Summit", "Microsoft"]). + order("client_of DESC"). map(&:client_of) - assert client_of.include?(nil) + assert_includes client_of, nil assert_equal [2, 1].sort, client_of.compact.sort end def test_find_with_nil_inside_set_passed_for_attribute client_of = Company. where(client_of: [nil]). - order('client_of DESC'). + order("client_of DESC"). map(&:client_of) assert_equal [], client_of.compact @@ -1117,20 +1107,30 @@ class FinderTest < ActiveRecord::TestCase def test_with_limiting_with_custom_select posts = Post.references(:authors).merge( - :includes => :author, :select => 'posts.*, authors.id as "author_id"', - :limit => 3, :order => 'posts.id' + includes: :author, select: 'posts.*, authors.id as "author_id"', + limit: 3, order: "posts.id" ).to_a assert_equal 3, posts.size assert_equal [0, 1, 1], posts.map(&:author_id).sort end + def test_find_one_message_on_primary_key + e = assert_raises(ActiveRecord::RecordNotFound) do + Car.find(0) + end + assert_equal 0, e.id + assert_equal "id", e.primary_key + assert_equal "Car", e.model + assert_equal "Couldn't find Car with 'id'=0", e.message + end + def test_find_one_message_with_custom_primary_key table_with_custom_primary_key do |model| model.primary_key = :name e = assert_raises(ActiveRecord::RecordNotFound) do - model.find 'Hello World!' + model.find "Hello World!" end - assert_equal %Q{Couldn't find MercedesCar with 'name'=Hello World!}, e.message + assert_equal "Couldn't find MercedesCar with 'name'=Hello World!", e.message end end @@ -1138,9 +1138,9 @@ class FinderTest < ActiveRecord::TestCase table_with_custom_primary_key do |model| model.primary_key = :name e = assert_raises(ActiveRecord::RecordNotFound) do - model.find 'Hello', 'World!' + model.find "Hello", "World!" end - assert_equal %Q{Couldn't find all MercedesCars with 'name': (Hello, World!) (found 0 results, but was looking for 2)}, e.message + assert_equal "Couldn't find all MercedesCars with 'name': (Hello, World!) (found 0 results, but was looking for 2)", e.message end end @@ -1163,7 +1163,7 @@ class FinderTest < ActiveRecord::TestCase end test "find_by with multi-arg conditions returns the first matching record" do - assert_equal posts(:eager_other), Post.find_by('id = ?', posts(:eager_other).id) + assert_equal posts(:eager_other), Post.find_by("id = ?", posts(:eager_other).id) end test "find_by returns nil if the record is missing" do @@ -1188,7 +1188,7 @@ class FinderTest < ActiveRecord::TestCase end test "find_by! with multi-arg conditions returns the first matching record" do - assert_equal posts(:eager_other), Post.find_by!('id = ?', posts(:eager_other).id) + assert_equal posts(:eager_other), Post.find_by!("id = ?", posts(:eager_other).id) end test "find_by! doesn't have implicit ordering" do @@ -1225,7 +1225,7 @@ class FinderTest < ActiveRecord::TestCase def table_with_custom_primary_key yield(Class.new(Toy) do def self.name - 'MercedesCar' + "MercedesCar" end end) end @@ -1234,5 +1234,4 @@ class FinderTest < ActiveRecord::TestCase err = assert_raises(exception_class) { block.call } assert_match message, err.message end - end diff --git a/activerecord/test/cases/fixture_set/file_test.rb b/activerecord/test/cases/fixture_set/file_test.rb index e64b90507e..cf2a73595a 100644 --- a/activerecord/test/cases/fixture_set/file_test.rb +++ b/activerecord/test/cases/fixture_set/file_test.rb @@ -1,5 +1,5 @@ -require 'cases/helper' -require 'tempfile' +require "cases/helper" +require "tempfile" module ActiveRecord class FixtureSet @@ -15,7 +15,7 @@ module ActiveRecord called = true assert_equal 6, fh.to_a.length end - assert called, 'block called' + assert called, "block called" end def test_names @@ -32,7 +32,7 @@ module ActiveRecord def test_values File.open(::File.join(FIXTURES_ROOT, "accounts.yml")) do |fh| assert_equal [1,2,3,4,5,6].sort, fh.to_a.map(&:last).map { |x| - x['id'] + x["id"] }.sort end end @@ -45,7 +45,7 @@ module ActiveRecord end def test_empty_file - tmp_yaml ['empty', 'yml'], '' do |t| + tmp_yaml ["empty", "yml"], "" do |t| assert_equal [], File.open(t.path) { |fh| fh.to_a } end end @@ -53,7 +53,7 @@ module ActiveRecord # A valid YAML file is not necessarily a value Fixture file. Make sure # an exception is raised if the format is not valid Fixture format. def test_wrong_fixture_format_string - tmp_yaml ['empty', 'yml'], 'qwerty' do |t| + tmp_yaml ["empty", "yml"], "qwerty" do |t| assert_raises(ActiveRecord::Fixture::FormatError) do File.open(t.path) { |fh| fh.to_a } end @@ -61,7 +61,7 @@ module ActiveRecord end def test_wrong_fixture_format_nested - tmp_yaml ['empty', 'yml'], 'one: two' do |t| + tmp_yaml ["empty", "yml"], "one: two" do |t| assert_raises(ActiveRecord::Fixture::FormatError) do File.open(t.path) { |fh| fh.to_a } end @@ -75,9 +75,9 @@ module ActiveRecord end end yaml = "one:\n name: <%= fixture_helper %>\n" - tmp_yaml ['curious', 'yml'], yaml do |t| + tmp_yaml ["curious", "yml"], yaml do |t| golden = - [["one", {"name" => "Fixture helper"}]] + [["one", { "name" => "Fixture helper" }]] assert_equal golden, File.open(t.path) { |fh| fh.to_a } end ActiveRecord::FixtureSet.context_class.class_eval do @@ -95,15 +95,15 @@ one: File: <%= File.name %> END - golden = [['one', { - 'ActiveRecord' => 'constant', - 'ActiveRecord_FixtureSet' => 'constant', - 'FixtureSet' => nil, - 'ActiveRecord_FixtureSet_File' => 'constant', - 'File' => 'File' + golden = [["one", { + "ActiveRecord" => "constant", + "ActiveRecord_FixtureSet" => "constant", + "FixtureSet" => nil, + "ActiveRecord_FixtureSet_File" => "constant", + "File" => "File" }]] - tmp_yaml ['curious', 'yml'], yaml do |t| + tmp_yaml ["curious", "yml"], yaml do |t| assert_equal golden, File.open(t.path) { |fh| fh.to_a } end end @@ -113,8 +113,8 @@ END def test_independent_render_contexts yaml1 = "<% def leaked_method; 'leak'; end %>\n" yaml2 = "one:\n name: <%= leaked_method %>\n" - tmp_yaml ['leaky', 'yml'], yaml1 do |t1| - tmp_yaml ['curious', 'yml'], yaml2 do |t2| + tmp_yaml ["leaky", "yml"], yaml1 do |t1| + tmp_yaml ["curious", "yml"], yaml2 do |t2| File.open(t1.path) { |fh| fh.to_a } assert_raises(NameError) do File.open(t2.path) { |fh| fh.to_a } @@ -124,33 +124,33 @@ END end def test_removes_fixture_config_row - File.open(::File.join(FIXTURES_ROOT, 'other_posts.yml')) do |fh| - assert_equal(['second_welcome'], fh.each.map { |name, _| name }) + File.open(::File.join(FIXTURES_ROOT, "other_posts.yml")) do |fh| + assert_equal(["second_welcome"], fh.each.map { |name, _| name }) end end def test_extracts_model_class_from_config_row - File.open(::File.join(FIXTURES_ROOT, 'other_posts.yml')) do |fh| - assert_equal 'Post', fh.model_class + File.open(::File.join(FIXTURES_ROOT, "other_posts.yml")) do |fh| + assert_equal "Post", fh.model_class end end def test_erb_filename - filename = 'filename.yaml' + filename = "filename.yaml" erb = File.new(filename).send(:prepare_erb, "<% Rails.env %>\n") assert_equal erb.filename, filename end private - def tmp_yaml(name, contents) - t = Tempfile.new name - t.binmode - t.write contents - t.close - yield t - ensure - t.close true - end + def tmp_yaml(name, contents) + t = Tempfile.new name + t.binmode + t.write contents + t.close + yield t + ensure + t.close true + end end end end diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index da934ab8fe..3f111447ff 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -1,31 +1,31 @@ -require 'cases/helper' -require 'models/admin' -require 'models/admin/account' -require 'models/admin/randomly_named_c1' -require 'models/admin/user' -require 'models/binary' -require 'models/book' -require 'models/bulb' -require 'models/category' -require 'models/comment' -require 'models/company' -require 'models/computer' -require 'models/course' -require 'models/developer' -require 'models/doubloon' -require 'models/joke' -require 'models/matey' -require 'models/parrot' -require 'models/pirate' -require 'models/post' -require 'models/randomly_named_c1' -require 'models/reply' -require 'models/ship' -require 'models/task' -require 'models/topic' -require 'models/traffic_light' -require 'models/treasure' -require 'tempfile' +require "cases/helper" +require "models/admin" +require "models/admin/account" +require "models/admin/randomly_named_c1" +require "models/admin/user" +require "models/binary" +require "models/book" +require "models/bulb" +require "models/category" +require "models/comment" +require "models/company" +require "models/computer" +require "models/course" +require "models/developer" +require "models/doubloon" +require "models/joke" +require "models/matey" +require "models/parrot" +require "models/pirate" +require "models/post" +require "models/randomly_named_c1" +require "models/reply" +require "models/ship" +require "models/task" +require "models/topic" +require "models/traffic_light" +require "models/treasure" +require "tempfile" class FixturesTest < ActiveRecord::TestCase self.use_instantiated_fixtures = true @@ -53,12 +53,12 @@ class FixturesTest < ActiveRecord::TestCase end def test_broken_yaml_exception - badyaml = Tempfile.new ['foo', '.yml'] - badyaml.write 'a: : ' + badyaml = Tempfile.new ["foo", ".yml"] + badyaml.write "a: : " badyaml.flush dir = File.dirname badyaml.path - name = File.basename badyaml.path, '.yml' + name = File.basename badyaml.path, ".yml" assert_raises(ActiveRecord::Fixture::FormatError) do ActiveRecord::FixtureSet.create_fixtures(dir, name) end @@ -69,8 +69,8 @@ class FixturesTest < ActiveRecord::TestCase def test_create_fixtures fixtures = ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT, "parrots") - assert Parrot.find_by_name('Curious George'), 'George is not in the database' - assert fixtures.detect { |f| f.name == 'parrots' }, "no fixtures named 'parrots' in #{fixtures.map(&:name).inspect}" + assert Parrot.find_by_name("Curious George"), "George is not in the database" + assert fixtures.detect { |f| f.name == "parrots" }, "no fixtures named 'parrots' in #{fixtures.map(&:name).inspect}" end def test_multiple_clean_fixtures @@ -81,10 +81,10 @@ class FixturesTest < ActiveRecord::TestCase end def test_create_symbol_fixtures - fixtures = ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT, :collections, :collections => Course) { Course.connection } + fixtures = ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT, :collections, collections: Course) { Course.connection } - assert Course.find_by_name('Collection'), 'course is not in the database' - assert fixtures.detect { |f| f.name == 'collections' }, "no fixtures named 'collections' in #{fixtures.map(&:name).inspect}" + assert Course.find_by_name("Collection"), "course is not in the database" + assert fixtures.detect { |f| f.name == "collections" }, "no fixtures named 'collections' in #{fixtures.map(&:name).inspect}" end def test_attributes @@ -115,10 +115,10 @@ class FixturesTest < ActiveRecord::TestCase t.column :bonus_time, :time t.column :last_read, :date t.column :content, :string - t.column :approved, :boolean, :default => true - t.column :replies_count, :integer, :default => 0 + t.column :approved, :boolean, default: true + t.column :replies_count, :integer, default: 0 t.column :parent_id, :integer - t.column :type, :string, :limit => 50 + t.column :type, :string, limit: 50 end # Store existing prefix/suffix @@ -126,8 +126,8 @@ class FixturesTest < ActiveRecord::TestCase old_suffix = ActiveRecord::Base.table_name_suffix # Set a prefix/suffix we can test against - ActiveRecord::Base.table_name_prefix = 'prefix_' - ActiveRecord::Base.table_name_suffix = '_suffix' + ActiveRecord::Base.table_name_prefix = "prefix_" + ActiveRecord::Base.table_name_suffix = "_suffix" other_topic_klass = Class.new(ActiveRecord::Base) do def self.name @@ -170,7 +170,7 @@ class FixturesTest < ActiveRecord::TestCase def test_logger_level_invariant level = ActiveRecord::Base.logger.level - create_fixtures('topics') + create_fixtures("topics") assert_equal level, ActiveRecord::Base.logger.level end @@ -229,11 +229,11 @@ class FixturesTest < ActiveRecord::TestCase def test_omap_fixtures assert_nothing_raised do - fixtures = ActiveRecord::FixtureSet.new(Account.connection, 'categories', Category, FIXTURES_ROOT + "/categories_ordered") + fixtures = ActiveRecord::FixtureSet.new(Account.connection, "categories", Category, FIXTURES_ROOT + "/categories_ordered") fixtures.each.with_index do |(name, fixture), i| assert_equal "fixture_no_#{i}", name - assert_equal "Category #{i}", fixture['name'] + assert_equal "Category #{i}", fixture["name"] end end end @@ -249,8 +249,8 @@ class FixturesTest < ActiveRecord::TestCase end def test_binary_in_fixtures - data = File.open(ASSETS_ROOT + "/flowers.jpg", 'rb') { |f| f.read } - data.force_encoding('ASCII-8BIT') + data = File.open(ASSETS_ROOT + "/flowers.jpg", "rb") { |f| f.read } + data.force_encoding("ASCII-8BIT") data.freeze assert_equal data, @flowers.data end @@ -260,8 +260,8 @@ class FixturesTest < ActiveRecord::TestCase end def test_fixtures_are_set_up_with_database_env_variable - db_url_tmp = ENV['DATABASE_URL'] - ENV['DATABASE_URL'] = "sqlite3::memory:" + db_url_tmp = ENV["DATABASE_URL"] + ENV["DATABASE_URL"] = "sqlite3::memory:" ActiveRecord::Base.stub(:configurations, {}) do test_case = Class.new(ActiveRecord::TestCase) do fixtures :accounts @@ -276,11 +276,11 @@ class FixturesTest < ActiveRecord::TestCase assert result.passed?, "Expected #{result.name} to pass:\n#{result}" end ensure - ENV['DATABASE_URL'] = db_url_tmp + ENV["DATABASE_URL"] = db_url_tmp end end -class HasManyThroughFixture < ActiveSupport::TestCase +class HasManyThroughFixture < ActiveRecord::TestCase def make_model(name) Class.new(ActiveRecord::Base) { define_singleton_method(:name) { name } } end @@ -291,17 +291,17 @@ class HasManyThroughFixture < ActiveSupport::TestCase treasure = make_model "Treasure" pt.table_name = "parrots_treasures" - pt.belongs_to :parrot, :anonymous_class => parrot - pt.belongs_to :treasure, :anonymous_class => treasure + pt.belongs_to :parrot, anonymous_class: parrot + pt.belongs_to :treasure, anonymous_class: treasure - parrot.has_many :parrot_treasures, :anonymous_class => pt - parrot.has_many :treasures, :through => :parrot_treasures + parrot.has_many :parrot_treasures, anonymous_class: pt + parrot.has_many :treasures, through: :parrot_treasures - parrots = File.join FIXTURES_ROOT, 'parrots' + parrots = File.join FIXTURES_ROOT, "parrots" fs = ActiveRecord::FixtureSet.new parrot.connection, "parrots", parrot, parrots rows = fs.table_rows - assert_equal load_has_and_belongs_to_many['parrots_treasures'], rows['parrots_treasures'] + assert_equal load_has_and_belongs_to_many["parrots_treasures"], rows["parrots_treasures"] end def test_has_many_through_with_renamed_table @@ -309,24 +309,24 @@ class HasManyThroughFixture < ActiveSupport::TestCase parrot = make_model "Parrot" treasure = make_model "Treasure" - pt.belongs_to :parrot, :anonymous_class => parrot - pt.belongs_to :treasure, :anonymous_class => treasure + pt.belongs_to :parrot, anonymous_class: parrot + pt.belongs_to :treasure, anonymous_class: treasure - parrot.has_many :parrot_treasures, :anonymous_class => pt - parrot.has_many :treasures, :through => :parrot_treasures + parrot.has_many :parrot_treasures, anonymous_class: pt + parrot.has_many :treasures, through: :parrot_treasures - parrots = File.join FIXTURES_ROOT, 'parrots' + parrots = File.join FIXTURES_ROOT, "parrots" fs = ActiveRecord::FixtureSet.new parrot.connection, "parrots", parrot, parrots rows = fs.table_rows - assert_equal load_has_and_belongs_to_many['parrots_treasures'], rows['parrot_treasures'] + assert_equal load_has_and_belongs_to_many["parrots_treasures"], rows["parrot_treasures"] end def load_has_and_belongs_to_many parrot = make_model "Parrot" parrot.has_and_belongs_to_many :treasures - parrots = File.join FIXTURES_ROOT, 'parrots' + parrots = File.join FIXTURES_ROOT, "parrots" fs = ActiveRecord::FixtureSet.new parrot.connection, "parrots", parrot, parrots fs.table_rows @@ -339,7 +339,7 @@ if Account.connection.respond_to?(:reset_pk_sequence!) fixtures :companies def setup - @instances = [Account.new(:credit_limit => 50), Company.new(:name => 'RoR Consulting'), Course.new(name: 'Test')] + @instances = [Account.new(credit_limit: 50), Company.new(name: "RoR Consulting"), Course.new(name: "Test")] ActiveRecord::FixtureSet.reset_cache # make sure tables get reinitialized end @@ -368,7 +368,7 @@ if Account.connection.respond_to?(:reset_pk_sequence!) def test_create_fixtures_resets_sequences_when_not_cached @instances.each do |instance| max_id = create_fixtures(instance.class.table_name).first.fixtures.inject(0) do |_max_id, (_, fixture)| - fixture_id = fixture['id'].to_i + fixture_id = fixture["id"].to_i fixture_id > _max_id ? fixture_id : _max_id end @@ -414,7 +414,7 @@ class FixturesWithoutInstantiationTest < ActiveRecord::TestCase def test_reloading_fixtures_through_accessor_methods topic = Struct.new(:title) assert_equal "The First Topic", topics(:first).title - assert_called(@loaded_fixtures['topics']['first'], :find, returns: topic.new("Fresh Topic!")) do + assert_called(@loaded_fixtures["topics"]["first"], :find, returns: topic.new("Fresh Topic!")) do assert_equal "Fresh Topic!", topics(:first, true).title end end @@ -479,7 +479,6 @@ class SetupSubclassTest < SetupTest end end - class OverlappingFixturesTest < ActiveRecord::TestCase fixtures :topics, :developers fixtures :developers, :accounts @@ -510,13 +509,13 @@ class OverRideFixtureMethodTest < ActiveRecord::TestCase def topics(name) topic = super - topic.title = 'omg' + topic.title = "omg" topic end def test_fixture_methods_can_be_overridden x = topics :first - assert_equal 'omg', x.title + assert_equal "omg", x.title end end @@ -553,7 +552,7 @@ class SetFixtureClassPrevailsTest < ActiveRecord::TestCase end class CheckSetTableNameFixturesTest < ActiveRecord::TestCase - set_fixture_class :funny_jokes => Joke + set_fixture_class funny_jokes: Joke fixtures :funny_jokes # Set to false to blow away fixtures cache and ensure our fixtures are loaded # and thus takes into account our set_fixture_class @@ -565,7 +564,7 @@ class CheckSetTableNameFixturesTest < ActiveRecord::TestCase end class FixtureNameIsNotTableNameFixturesTest < ActiveRecord::TestCase - set_fixture_class :items => Book + set_fixture_class items: Book fixtures :items # Set to false to blow away fixtures cache and ensure our fixtures are loaded # and thus takes into account our set_fixture_class @@ -577,7 +576,7 @@ class FixtureNameIsNotTableNameFixturesTest < ActiveRecord::TestCase end class FixtureNameIsNotTableNameMultipleFixturesTest < ActiveRecord::TestCase - set_fixture_class :items => Book, :funny_jokes => Joke + set_fixture_class items: Book, funny_jokes: Joke fixtures :items, :funny_jokes # Set to false to blow away fixtures cache and ensure our fixtures are loaded # and thus takes into account our set_fixture_class @@ -593,7 +592,7 @@ class FixtureNameIsNotTableNameMultipleFixturesTest < ActiveRecord::TestCase end class CustomConnectionFixturesTest < ActiveRecord::TestCase - set_fixture_class :courses => Course + set_fixture_class courses: Course fixtures :courses self.use_transactional_tests = false @@ -608,7 +607,7 @@ class CustomConnectionFixturesTest < ActiveRecord::TestCase end class TransactionalFixturesOnCustomConnectionTest < ActiveRecord::TestCase - set_fixture_class :courses => Course + set_fixture_class courses: Course fixtures :courses self.use_transactional_tests = true @@ -622,6 +621,46 @@ class TransactionalFixturesOnCustomConnectionTest < ActiveRecord::TestCase end end +class TransactionalFixturesOnConnectionNotification < ActiveRecord::TestCase + self.use_transactional_tests = true + self.use_instantiated_fixtures = false + + def test_transaction_created_on_connection_notification + connection = stub(transaction_open?: false) + connection.expects(:begin_transaction).with(joinable: false) + fire_connection_notification(connection) + end + + def test_notification_established_transactions_are_rolled_back + # Mocha is not thread-safe so define our own stub to test + connection = Class.new do + attr_accessor :rollback_transaction_called + def transaction_open?; true; end + def begin_transaction(*args); end + def rollback_transaction(*args) + @rollback_transaction_called = true + end + end.new + fire_connection_notification(connection) + teardown_fixtures + assert(connection.rollback_transaction_called, "Expected <mock connection>#rollback_transaction to be called but was not") + end + + private + + def fire_connection_notification(connection) + ActiveRecord::Base.connection_handler.stubs(:retrieve_connection).with("book").returns(connection) + message_bus = ActiveSupport::Notifications.instrumenter + payload = { + spec_name: "book", + config: nil, + connection_id: connection.object_id + } + + message_bus.instrument("!connection.active_record", payload) {} + end +end + class InvalidTableNameFixturesTest < ActiveRecord::TestCase fixtures :funny_jokes # Set to false to blow away fixtures cache and ensure our fixtures are loaded @@ -636,7 +675,7 @@ class InvalidTableNameFixturesTest < ActiveRecord::TestCase end class CheckEscapedYamlFixturesTest < ActiveRecord::TestCase - set_fixture_class :funny_jokes => Joke + set_fixture_class funny_jokes: Joke fixtures :funny_jokes # Set to false to blow away fixtures cache and ensure our fixtures are loaded # and thus takes into account our set_fixture_class @@ -679,7 +718,7 @@ class FixturesBrokenRollbackTest < ActiveRecord::TestCase private def load_fixtures(config) - raise 'argh' + raise "argh" end end @@ -689,7 +728,7 @@ class LoadAllFixturesTest < ActiveRecord::TestCase self.class.fixtures :all if File.symlink? FIXTURES_ROOT + "/all/admin" - assert_equal %w(admin/accounts admin/users developers people tasks), fixture_table_names.sort + assert_equal %w(admin/accounts admin/users developers namespaced/accounts people tasks), fixture_table_names.sort end ensure ActiveRecord::FixtureSet.reset_cache @@ -698,11 +737,11 @@ end class LoadAllFixturesWithPathnameTest < ActiveRecord::TestCase def test_all_there - self.class.fixture_path = Pathname.new(FIXTURES_ROOT).join('all') + self.class.fixture_path = Pathname.new(FIXTURES_ROOT).join("all") self.class.fixtures :all if File.symlink? FIXTURES_ROOT + "/all/admin" - assert_equal %w(admin/accounts admin/users developers people tasks), fixture_table_names.sort + assert_equal %w(admin/accounts admin/users developers namespaced/accounts people tasks), fixture_table_names.sort end ensure ActiveRecord::FixtureSet.reset_cache @@ -720,18 +759,18 @@ class FasterFixturesTest < ActiveRecord::TestCase end def test_cache - assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, 'categories') - assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, 'authors') + assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, "categories") + assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, "authors") assert_no_queries do - create_fixtures('categories') - create_fixtures('authors') + create_fixtures("categories") + create_fixtures("authors") end - load_extra_fixture('posts') - assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, 'posts') + load_extra_fixture("posts") + assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, "posts") self.class.setup_fixture_accessors :posts - assert_equal 'Welcome to the weblog', posts(:welcome).title + assert_equal "Welcome to the weblog", posts(:welcome).title end end @@ -739,9 +778,9 @@ class FoxyFixturesTest < ActiveRecord::TestCase fixtures :parrots, :parrots_pirates, :pirates, :treasures, :mateys, :ships, :computers, :developers, :"admin/accounts", :"admin/users", :live_parrots, :dead_parrots, :books - if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - require 'models/uuid_parent' - require 'models/uuid_child' + if ActiveRecord::Base.connection.adapter_name == "PostgreSQL" + require "models/uuid_parent" + require "models/uuid_child" fixtures :uuid_parents, :uuid_children end @@ -758,8 +797,8 @@ class FoxyFixturesTest < ActiveRecord::TestCase assert_equal 207281424, ActiveRecord::FixtureSet.identify(:ruby) assert_equal 1066363776, ActiveRecord::FixtureSet.identify(:sapphire_2) - assert_equal 'f92b6bda-0d0d-5fe1-9124-502b18badded', ActiveRecord::FixtureSet.identify(:daddy, :uuid) - assert_equal 'b4b10018-ad47-595d-b42f-d8bdaa6d01bf', ActiveRecord::FixtureSet.identify(:sonny, :uuid) + assert_equal "f92b6bda-0d0d-5fe1-9124-502b18badded", ActiveRecord::FixtureSet.identify(:daddy, :uuid) + assert_equal "b4b10018-ad47-595d-b42f-d8bdaa6d01bf", ActiveRecord::FixtureSet.identify(:sonny, :uuid) end TIMESTAMP_COLUMNS = %w(created_at created_on updated_at updated_on) @@ -857,7 +896,7 @@ class FoxyFixturesTest < ActiveRecord::TestCase assert_equal("X marks the spot!", pirates(:mark).catchphrase) end - def test_supports_label_interpolation_for_fixnum_label + def test_supports_label_interpolation_for_integer_label assert_equal("#1 pirate!", pirates(1).catchphrase) end @@ -884,7 +923,7 @@ class FoxyFixturesTest < ActiveRecord::TestCase end def test_namespaced_models - assert admin_accounts(:signals37).users.include?(admin_users(:david)) + assert_includes admin_accounts(:signals37).users, admin_users(:david) assert_equal 2, admin_accounts(:signals37).users.size end @@ -913,10 +952,10 @@ class CustomNameForFixtureOrModelTest < ActiveRecord::TestCase ClassNameThatDoesNotFollowCONVENTIONS, :'admin/randomly_named_a9' => Admin::ClassNameThatDoesNotFollowCONVENTIONS1, - 'admin/randomly_named_b0' => + "admin/randomly_named_b0" => Admin::ClassNameThatDoesNotFollowCONVENTIONS2 - fixtures :randomly_named_a9, 'admin/randomly_named_a9', + fixtures :randomly_named_a9, "admin/randomly_named_a9", :'admin/randomly_named_b0' def test_named_accessor_for_randomly_named_fixture_and_class @@ -932,8 +971,8 @@ class CustomNameForFixtureOrModelTest < ActiveRecord::TestCase end def test_table_name_is_defined_in_the_model - assert_equal 'randomly_named_table2', ActiveRecord::FixtureSet::all_loaded_fixtures["admin/randomly_named_a9"].table_name - assert_equal 'randomly_named_table2', Admin::ClassNameThatDoesNotFollowCONVENTIONS1.table_name + assert_equal "randomly_named_table2", ActiveRecord::FixtureSet::all_loaded_fixtures["admin/randomly_named_a9"].table_name + assert_equal "randomly_named_table2", Admin::ClassNameThatDoesNotFollowCONVENTIONS1.table_name end end @@ -965,10 +1004,10 @@ class FixtureClassNamesTest < ActiveRecord::TestCase end def teardown - self.fixture_class_names.replace(@saved_cache) + fixture_class_names.replace(@saved_cache) end test "fixture_class_names returns nil for unregistered identifier" do - assert_nil self.fixture_class_names['unregistered_identifier'] + assert_nil fixture_class_names["unregistered_identifier"] end end diff --git a/activerecord/test/cases/forbidden_attributes_protection_test.rb b/activerecord/test/cases/forbidden_attributes_protection_test.rb index 91921469b8..75c3493527 100644 --- a/activerecord/test/cases/forbidden_attributes_protection_test.rb +++ b/activerecord/test/cases/forbidden_attributes_protection_test.rb @@ -1,11 +1,11 @@ -require 'cases/helper' -require 'active_support/core_ext/hash/indifferent_access' +require "cases/helper" +require "active_support/core_ext/hash/indifferent_access" -require 'models/company' -require 'models/person' -require 'models/ship' -require 'models/ship_part' -require 'models/treasure' +require "models/company" +require "models/person" +require "models/ship" +require "models/ship_part" +require "models/treasure" class ProtectedParams attr_accessor :permitted @@ -44,40 +44,40 @@ end class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase def test_forbidden_attributes_cannot_be_used_for_mass_assignment - params = ProtectedParams.new(first_name: 'Guille', gender: 'm') + params = ProtectedParams.new(first_name: "Guille", gender: "m") assert_raises(ActiveModel::ForbiddenAttributesError) do Person.new(params) end end def test_permitted_attributes_can_be_used_for_mass_assignment - params = ProtectedParams.new(first_name: 'Guille', gender: 'm') + params = ProtectedParams.new(first_name: "Guille", gender: "m") params.permit! person = Person.new(params) - assert_equal 'Guille', person.first_name - assert_equal 'm', person.gender + assert_equal "Guille", person.first_name + assert_equal "m", person.gender end def test_forbidden_attributes_cannot_be_used_for_sti_inheritance_column - params = ProtectedParams.new(type: 'Client') + params = ProtectedParams.new(type: "Client") assert_raises(ActiveModel::ForbiddenAttributesError) do Company.new(params) end end def test_permitted_attributes_can_be_used_for_sti_inheritance_column - params = ProtectedParams.new(type: 'Client') + params = ProtectedParams.new(type: "Client") params.permit! person = Company.new(params) assert_equal person.class, Client end def test_regular_hash_should_still_be_used_for_mass_assignment - person = Person.new(first_name: 'Guille', gender: 'm') + person = Person.new(first_name: "Guille", gender: "m") - assert_equal 'Guille', person.first_name - assert_equal 'm', person.gender + assert_equal "Guille", person.first_name + assert_equal "m", person.gender end def test_blank_attributes_should_not_raise @@ -86,7 +86,7 @@ class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase end def test_create_with_checks_permitted - params = ProtectedParams.new(first_name: 'Guille', gender: 'm') + params = ProtectedParams.new(first_name: "Guille", gender: "m") assert_raises(ActiveModel::ForbiddenAttributesError) do Person.create_with(params).create! @@ -94,21 +94,21 @@ class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase end def test_create_with_works_with_permitted_params - params = ProtectedParams.new(first_name: 'Guille').permit! + params = ProtectedParams.new(first_name: "Guille").permit! person = Person.create_with(params).create! - assert_equal 'Guille', person.first_name + assert_equal "Guille", person.first_name end def test_create_with_works_with_params_values - params = ProtectedParams.new(first_name: 'Guille') + params = ProtectedParams.new(first_name: "Guille") person = Person.create_with(first_name: params[:first_name]).create! - assert_equal 'Guille', person.first_name + assert_equal "Guille", person.first_name end def test_where_checks_permitted - params = ProtectedParams.new(first_name: 'Guille', gender: 'm') + params = ProtectedParams.new(first_name: "Guille", gender: "m") assert_raises(ActiveModel::ForbiddenAttributesError) do Person.where(params).create! @@ -116,21 +116,21 @@ class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase end def test_where_works_with_permitted_params - params = ProtectedParams.new(first_name: 'Guille').permit! + params = ProtectedParams.new(first_name: "Guille").permit! person = Person.where(params).create! - assert_equal 'Guille', person.first_name + assert_equal "Guille", person.first_name end def test_where_works_with_params_values - params = ProtectedParams.new(first_name: 'Guille') + params = ProtectedParams.new(first_name: "Guille") person = Person.where(first_name: params[:first_name]).create! - assert_equal 'Guille', person.first_name + assert_equal "Guille", person.first_name end def test_where_not_checks_permitted - params = ProtectedParams.new(first_name: 'Guille', gender: 'm') + params = ProtectedParams.new(first_name: "Guille", gender: "m") assert_raises(ActiveModel::ForbiddenAttributesError) do Person.where().not(params) @@ -138,9 +138,9 @@ class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase end def test_where_not_works_with_permitted_params - params = ProtectedParams.new(first_name: 'Guille').permit! + params = ProtectedParams.new(first_name: "Guille").permit! Person.create!(params) - assert_empty Person.where.not(params).select {|p| p.first_name == 'Guille' } + assert_empty Person.where.not(params).select { |p| p.first_name == "Guille" } end def test_strong_params_style_objects_work_with_singular_associations @@ -161,5 +161,4 @@ class ForbiddenAttributesProtectionTest < ActiveRecord::TestCase assert_equal "Necklace", part.trinkets[0].name assert_equal "Spoon", part.trinkets[1].name end - end diff --git a/activerecord/test/cases/habtm_destroy_order_test.rb b/activerecord/test/cases/habtm_destroy_order_test.rb index 2ce0de360e..365d4576dd 100644 --- a/activerecord/test/cases/habtm_destroy_order_test.rb +++ b/activerecord/test/cases/habtm_destroy_order_test.rb @@ -4,21 +4,21 @@ require "models/student" class HabtmDestroyOrderTest < ActiveRecord::TestCase test "may not delete a lesson with students" do - sicp = Lesson.new(:name => "SICP") - ben = Student.new(:name => "Ben Bitdiddle") + sicp = Lesson.new(name: "SICP") + ben = Student.new(name: "Ben Bitdiddle") sicp.students << ben sicp.save! assert_raises LessonError do - assert_no_difference('Lesson.count') do + assert_no_difference("Lesson.count") do sicp.destroy end end assert !sicp.destroyed? end - test 'should not raise error if have foreign key in the join table' do - student = Student.new(:name => "Ben Bitdiddle") - lesson = Lesson.new(:name => "SICP") + test "should not raise error if have foreign key in the join table" do + student = Student.new(name: "Ben Bitdiddle") + lesson = Lesson.new(name: "SICP") lesson.students << student lesson.save! assert_nothing_raised do @@ -29,8 +29,8 @@ class HabtmDestroyOrderTest < ActiveRecord::TestCase test "not destroying a student with lessons leaves student<=>lesson association intact" do # test a normal before_destroy doesn't destroy the habtm joins begin - sicp = Lesson.new(:name => "SICP") - ben = Student.new(:name => "Ben Bitdiddle") + sicp = Lesson.new(name: "SICP") + ben = Student.new(name: "Ben Bitdiddle") # add a before destroy to student Student.class_eval do before_destroy do @@ -49,8 +49,8 @@ class HabtmDestroyOrderTest < ActiveRecord::TestCase test "not destroying a lesson with students leaves student<=>lesson association intact" do # test a more aggressive before_destroy doesn't destroy the habtm joins and still throws the exception - sicp = Lesson.new(:name => "SICP") - ben = Student.new(:name => "Ben Bitdiddle") + sicp = Lesson.new(name: "SICP") + ben = Student.new(name: "Ben Bitdiddle") sicp.students << ben sicp.save! assert_raises LessonError do diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb index d2fdf03e9d..f1d69a215a 100644 --- a/activerecord/test/cases/helper.rb +++ b/activerecord/test/cases/helper.rb @@ -1,17 +1,15 @@ -require 'config' +require "config" -require 'active_support/testing/autorun' -require 'active_support/testing/method_call_assertions' -require 'stringio' +require "stringio" -require 'active_record' -require 'cases/test_case' -require 'active_support/dependencies' -require 'active_support/logger' -require 'active_support/core_ext/string/strip' +require "active_record" +require "cases/test_case" +require "active_support/dependencies" +require "active_support/logger" +require "active_support/core_ext/string/strip" -require 'support/config' -require 'support/connection' +require "support/config" +require "support/connection" # TODO: Move all these random hacks into the ARTest namespace and into the support/ dir @@ -27,7 +25,7 @@ I18n.enforce_available_locales = false ARTest.connect # Quote "type" if it's a reserved word for the current connection. -QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type') +QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name("type") # FIXME: Remove this when the deprecation cycle on TZ aware types by default ends. ActiveRecord::Base.time_zone_aware_types << :time @@ -49,18 +47,18 @@ def subsecond_precision_supported? end def mysql_enforcing_gtid_consistency? - current_adapter?(:Mysql2Adapter) && 'ON' == ActiveRecord::Base.connection.show_variable('enforce_gtid_consistency') + current_adapter?(:Mysql2Adapter) && "ON" == ActiveRecord::Base.connection.show_variable("enforce_gtid_consistency") end def supports_savepoints? ActiveRecord::Base.connection.supports_savepoints? end -def with_env_tz(new_tz = 'US/Eastern') - old_tz, ENV['TZ'] = ENV['TZ'], new_tz +def with_env_tz(new_tz = "US/Eastern") + old_tz, ENV["TZ"] = ENV["TZ"], new_tz yield ensure - old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ') + old_tz ? ENV["TZ"] = old_tz : ENV.delete("TZ") end def with_timezone_config(cfg) @@ -134,21 +132,6 @@ def disable_extension!(extension, connection) connection.reconnect! end -require "cases/validations_repair_helper" -class ActiveSupport::TestCase - include ActiveRecord::TestFixtures - include ActiveRecord::ValidationsRepairHelper - include ActiveSupport::Testing::MethodCallAssertions - - self.fixture_path = FIXTURES_ROOT - self.use_instantiated_fixtures = false - self.use_transactional_tests = true - - def create_fixtures(*fixture_set_names, &block) - ActiveRecord::FixtureSet.create_fixtures(ActiveSupport::TestCase.fixture_path, fixture_set_names, fixture_class_names, &block) - end -end - def load_schema # silence verbose schema loading original_stdout = $stdout @@ -188,17 +171,17 @@ end module InTimeZone private - def in_time_zone(zone) - old_zone = Time.zone - old_tz = ActiveRecord::Base.time_zone_aware_attributes - - Time.zone = zone ? ActiveSupport::TimeZone[zone] : nil - ActiveRecord::Base.time_zone_aware_attributes = !zone.nil? - yield - ensure - Time.zone = old_zone - ActiveRecord::Base.time_zone_aware_attributes = old_tz - end + def in_time_zone(zone) + old_zone = Time.zone + old_tz = ActiveRecord::Base.time_zone_aware_attributes + + Time.zone = zone ? ActiveSupport::TimeZone[zone] : nil + ActiveRecord::Base.time_zone_aware_attributes = !zone.nil? + yield + ensure + Time.zone = old_zone + ActiveRecord::Base.time_zone_aware_attributes = old_tz + end end -require 'mocha/setup' # FIXME: stop using mocha +require "mocha/setup" # FIXME: stop using mocha diff --git a/activerecord/test/cases/hot_compatibility_test.rb b/activerecord/test/cases/hot_compatibility_test.rb index 9fc75b7377..e107ff2362 100644 --- a/activerecord/test/cases/hot_compatibility_test.rb +++ b/activerecord/test/cases/hot_compatibility_test.rb @@ -1,5 +1,5 @@ -require 'cases/helper' -require 'support/connection_helper' +require "cases/helper" +require "support/connection_helper" class HotCompatibilityTest < ActiveRecord::TestCase self.use_transactional_tests = false @@ -12,7 +12,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase t.string :bar end - def self.name; 'HotCompatibility'; end + def self.name; "HotCompatibility"; end end end @@ -35,29 +35,29 @@ class HotCompatibilityTest < ActiveRecord::TestCase # but we can successfully create a record so long as we don't # reference the removed column - record = @klass.create! foo: 'foo' + record = @klass.create! foo: "foo" record.reload - assert_equal 'foo', record.foo + assert_equal "foo", record.foo end test "update after remove_column" do - record = @klass.create! foo: 'foo' + record = @klass.create! foo: "foo" assert_equal 3, @klass.columns.length @klass.connection.remove_column :hot_compatibilities, :bar assert_equal 3, @klass.columns.length record.reload - assert_equal 'foo', record.foo - record.foo = 'bar' + assert_equal "foo", record.foo + record.foo = "bar" record.save! record.reload - assert_equal 'bar', record.foo + assert_equal "bar", record.foo end if current_adapter?(:PostgreSQLAdapter) test "cleans up after prepared statement failure in a transaction" do with_two_connections do |original_connection, ddl_connection| - record = @klass.create! bar: 'bar' + record = @klass.create! bar: "bar" # prepare the reload statement in a transaction @klass.transaction do @@ -83,7 +83,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase test "cleans up after prepared statement failure in nested transactions" do with_two_connections do |original_connection, ddl_connection| - record = @klass.create! bar: 'bar' + record = @klass.create! bar: "bar" # prepare the reload statement in a transaction @klass.transaction do @@ -114,29 +114,29 @@ class HotCompatibilityTest < ActiveRecord::TestCase private - def get_prepared_statement_cache(connection) - connection.instance_variable_get(:@statements) - .instance_variable_get(:@cache)[Process.pid] - end + def get_prepared_statement_cache(connection) + connection.instance_variable_get(:@statements) + .instance_variable_get(:@cache)[Process.pid] + end - # Rails will automatically clear the prepared statements on the connection - # that runs the migration, so we use two connections to simulate what would - # actually happen on a production system; we'd have one connection running the - # migration from the rake task ("ddl_connection" here), and we'd have another - # connection in a web worker. - def with_two_connections - run_without_connection do |original_connection| - ActiveRecord::Base.establish_connection(original_connection.merge(pool_size: 2)) - begin - ddl_connection = ActiveRecord::Base.connection_pool.checkout + # Rails will automatically clear the prepared statements on the connection + # that runs the migration, so we use two connections to simulate what would + # actually happen on a production system; we'd have one connection running the + # migration from the rake task ("ddl_connection" here), and we'd have another + # connection in a web worker. + def with_two_connections + run_without_connection do |original_connection| + ActiveRecord::Base.establish_connection(original_connection.merge(pool_size: 2)) begin - yield original_connection, ddl_connection + ddl_connection = ActiveRecord::Base.connection_pool.checkout + begin + yield original_connection, ddl_connection + ensure + ActiveRecord::Base.connection_pool.checkin ddl_connection + end ensure - ActiveRecord::Base.connection_pool.checkin ddl_connection + ActiveRecord::Base.clear_all_connections! end - ensure - ActiveRecord::Base.clear_all_connections! end end - end end diff --git a/activerecord/test/cases/i18n_test.rb b/activerecord/test/cases/i18n_test.rb index a428f1d87b..7f03c5b23d 100644 --- a/activerecord/test/cases/i18n_test.rb +++ b/activerecord/test/cases/i18n_test.rb @@ -1,45 +1,44 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' +require "models/topic" +require "models/reply" class ActiveRecordI18nTests < ActiveRecord::TestCase - def setup I18n.backend = I18n::Backend::Simple.new end def test_translated_model_attributes - I18n.backend.store_translations 'en', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } } - assert_equal 'topic title attribute', Topic.human_attribute_name('title') + I18n.backend.store_translations "en", activerecord: { attributes: { topic: { title: "topic title attribute" } } } + assert_equal "topic title attribute", Topic.human_attribute_name("title") end def test_translated_model_attributes_with_symbols - I18n.backend.store_translations 'en', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } } - assert_equal 'topic title attribute', Topic.human_attribute_name(:title) + I18n.backend.store_translations "en", activerecord: { attributes: { topic: { title: "topic title attribute" } } } + assert_equal "topic title attribute", Topic.human_attribute_name(:title) end def test_translated_model_attributes_with_sti - I18n.backend.store_translations 'en', :activerecord => {:attributes => {:reply => {:title => 'reply title attribute'} } } - assert_equal 'reply title attribute', Reply.human_attribute_name('title') + I18n.backend.store_translations "en", activerecord: { attributes: { reply: { title: "reply title attribute" } } } + assert_equal "reply title attribute", Reply.human_attribute_name("title") end def test_translated_model_attributes_with_sti_fallback - I18n.backend.store_translations 'en', :activerecord => {:attributes => {:topic => {:title => 'topic title attribute'} } } - assert_equal 'topic title attribute', Reply.human_attribute_name('title') + I18n.backend.store_translations "en", activerecord: { attributes: { topic: { title: "topic title attribute" } } } + assert_equal "topic title attribute", Reply.human_attribute_name("title") end def test_translated_model_names - I18n.backend.store_translations 'en', :activerecord => {:models => {:topic => 'topic model'} } - assert_equal 'topic model', Topic.model_name.human + I18n.backend.store_translations "en", activerecord: { models: { topic: "topic model" } } + assert_equal "topic model", Topic.model_name.human end def test_translated_model_names_with_sti - I18n.backend.store_translations 'en', :activerecord => {:models => {:reply => 'reply model'} } - assert_equal 'reply model', Reply.model_name.human + I18n.backend.store_translations "en", activerecord: { models: { reply: "reply model" } } + assert_equal "reply model", Reply.model_name.human end def test_translated_model_names_with_sti_fallback - I18n.backend.store_translations 'en', :activerecord => {:models => {:topic => 'topic model'} } - assert_equal 'topic model', Reply.model_name.human + I18n.backend.store_translations "en", activerecord: { models: { topic: "topic model" } } + assert_equal "topic model", Reply.model_name.human end end diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index e234b9a6a9..9ad4664567 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -1,13 +1,13 @@ -require 'cases/helper' -require 'models/author' -require 'models/company' -require 'models/person' -require 'models/post' -require 'models/project' -require 'models/subscriber' -require 'models/vegetables' -require 'models/shop' -require 'models/sponsor' +require "cases/helper" +require "models/author" +require "models/company" +require "models/person" +require "models/post" +require "models/project" +require "models/subscriber" +require "models/vegetables" +require "models/shop" +require "models/sponsor" module InheritanceTestHelper def with_store_full_sti_class(&block) @@ -33,7 +33,7 @@ class InheritanceTest < ActiveRecord::TestCase def test_class_with_store_full_sti_class_returns_full_name with_store_full_sti_class do - assert_equal 'Namespaced::Company', Namespaced::Company.sti_name + assert_equal "Namespaced::Company", Namespaced::Company.sti_name end end @@ -42,37 +42,37 @@ class InheritanceTest < ActiveRecord::TestCase company = company.dup company.extend(Module.new { def _read_attribute(name) - return ' ' if name == 'type' + return " " if name == "type" super end }) company.save! company = Company.all.to_a.find { |x| x.id == company.id } - assert_equal ' ', company.type + assert_equal " ", company.type end def test_class_without_store_full_sti_class_returns_demodulized_name without_store_full_sti_class do - assert_equal 'Company', Namespaced::Company.sti_name + assert_equal "Company", Namespaced::Company.sti_name end end def test_compute_type_success - assert_equal Author, ActiveRecord::Base.send(:compute_type, 'Author') + assert_equal Author, ActiveRecord::Base.send(:compute_type, "Author") end def test_compute_type_nonexistent_constant e = assert_raises NameError do - ActiveRecord::Base.send :compute_type, 'NonexistentModel' + ActiveRecord::Base.send :compute_type, "NonexistentModel" end - assert_equal 'uninitialized constant ActiveRecord::Base::NonexistentModel', e.message - assert_equal 'ActiveRecord::Base::NonexistentModel', e.name + assert_equal "uninitialized constant ActiveRecord::Base::NonexistentModel", e.message + assert_equal "ActiveRecord::Base::NonexistentModel", e.name end def test_compute_type_no_method_error - ActiveSupport::Dependencies.stub(:safe_constantize, proc{ raise NoMethodError }) do + ActiveSupport::Dependencies.stub(:safe_constantize, proc { raise NoMethodError }) do assert_raises NoMethodError do - ActiveRecord::Base.send :compute_type, 'InvalidModel' + ActiveRecord::Base.send :compute_type, "InvalidModel" end end end @@ -87,19 +87,19 @@ class InheritanceTest < ActiveRecord::TestCase error = e end - ActiveSupport::Dependencies.stub(:safe_constantize, proc{ raise e }) do + ActiveSupport::Dependencies.stub(:safe_constantize, proc { raise e }) do exception = assert_raises NameError do - ActiveRecord::Base.send :compute_type, 'InvalidModel' + ActiveRecord::Base.send :compute_type, "InvalidModel" end assert_equal error.message, exception.message end end def test_compute_type_argument_error - ActiveSupport::Dependencies.stub(:safe_constantize, proc{ raise ArgumentError }) do + ActiveSupport::Dependencies.stub(:safe_constantize, proc { raise ArgumentError }) do assert_raises ArgumentError do - ActiveRecord::Base.send :compute_type, 'InvalidModel' + ActiveRecord::Base.send :compute_type, "InvalidModel" end end end @@ -107,14 +107,14 @@ class InheritanceTest < ActiveRecord::TestCase def test_should_store_demodulized_class_name_with_store_full_sti_class_option_disabled without_store_full_sti_class do item = Namespaced::Company.new - assert_equal 'Company', item[:type] + assert_equal "Company", item[:type] end end def test_should_store_full_class_name_with_store_full_sti_class_option_enabled with_store_full_sti_class do item = Namespaced::Company.new - assert_equal 'Namespaced::Company', item[:type] + assert_equal "Namespaced::Company", item[:type] end end @@ -154,9 +154,9 @@ class InheritanceTest < ActiveRecord::TestCase def test_company_descends_from_active_record assert !ActiveRecord::Base.descends_from_active_record? - assert AbstractCompany.descends_from_active_record?, 'AbstractCompany should descend from ActiveRecord::Base' - assert Company.descends_from_active_record?, 'Company should descend from ActiveRecord::Base' - assert !Class.new(Company).descends_from_active_record?, 'Company subclass should not descend from ActiveRecord::Base' + assert AbstractCompany.descends_from_active_record?, "AbstractCompany should descend from ActiveRecord::Base" + assert Company.descends_from_active_record?, "Company should descend from ActiveRecord::Base" + assert !Class.new(Company).descends_from_active_record?, "Company subclass should not descend from ActiveRecord::Base" end def test_abstract_class @@ -214,7 +214,7 @@ class InheritanceTest < ActiveRecord::TestCase def test_becomes_and_change_tracking_for_inheritance_columns cucumber = Vegetable.find(1) cabbage = cucumber.becomes!(Cabbage) - assert_equal ['Cucumber', 'Cabbage'], cabbage.custom_type_change + assert_equal ["Cucumber", "Cabbage"], cabbage.custom_type_change end def test_alt_becomes_bang_resets_inheritance_type_column @@ -229,13 +229,13 @@ class InheritanceTest < ActiveRecord::TestCase end def test_inheritance_find_all - companies = Company.all.merge!(:order => 'id').to_a + companies = Company.all.merge!(order: "id").to_a assert_kind_of Firm, companies[0], "37signals should be a firm" assert_kind_of Client, companies[1], "Summit should be a client" end def test_alt_inheritance_find_all - companies = Vegetable.all.merge!(:order => 'id').to_a + companies = Vegetable.all.merge!(order: "id").to_a assert_kind_of Cucumber, companies[0] assert_kind_of Cabbage, companies[1] end @@ -250,7 +250,7 @@ class InheritanceTest < ActiveRecord::TestCase end def test_alt_inheritance_save - cabbage = Cabbage.new(:name => 'Savoy') + cabbage = Cabbage.new(name: "Savoy") cabbage.save! savoy = Vegetable.find(cabbage.id) @@ -263,12 +263,12 @@ class InheritanceTest < ActiveRecord::TestCase end def test_inheritance_new_with_base_class - company = Company.new(:type => 'Company') + company = Company.new(type: "Company") assert_equal Company, company.class end def test_inheritance_new_with_subclass - firm = Company.new(:type => 'Firm') + firm = Company.new(type: "Firm") assert_equal Firm, firm.class end @@ -287,17 +287,17 @@ class InheritanceTest < ActiveRecord::TestCase end def test_new_with_invalid_type - assert_raise(ActiveRecord::SubclassNotFound) { Company.new(:type => 'InvalidType') } + assert_raise(ActiveRecord::SubclassNotFound) { Company.new(type: "InvalidType") } end def test_new_with_unrelated_type - assert_raise(ActiveRecord::SubclassNotFound) { Company.new(:type => 'Account') } + assert_raise(ActiveRecord::SubclassNotFound) { Company.new(type: "Account") } end def test_new_with_unrelated_namespaced_type without_store_full_sti_class do e = assert_raises ActiveRecord::SubclassNotFound do - Namespaced::Company.new(type: 'Firm') + Namespaced::Company.new(type: "Firm") end assert_equal "Invalid single-table inheritance type: Namespaced::Firm is not a subclass of Namespaced::Company", e.message @@ -305,21 +305,21 @@ class InheritanceTest < ActiveRecord::TestCase end def test_new_with_complex_inheritance - assert_nothing_raised { Client.new(type: 'VerySpecialClient') } + assert_nothing_raised { Client.new(type: "VerySpecialClient") } end def test_new_without_storing_full_sti_class without_store_full_sti_class do - item = Company.new(type: 'SpecialCo') + item = Company.new(type: "SpecialCo") assert_instance_of Company::SpecialCo, item end end def test_new_with_autoload_paths - path = File.expand_path('../../models/autoloadable', __FILE__) + path = File.expand_path("../../models/autoloadable", __FILE__) ActiveSupport::Dependencies.autoload_paths << path - firm = Company.new(:type => 'ExtraFirm') + firm = Company.new(type: "ExtraFirm") assert_equal ExtraFirm, firm.class ensure ActiveSupport::Dependencies.autoload_paths.reject! { |p| p == path } @@ -352,7 +352,7 @@ class InheritanceTest < ActiveRecord::TestCase Client.update_all "name = 'I am a client'" assert_equal "I am a client", Client.first.name # Order by added as otherwise Oracle tests were failing because of different order of results - assert_equal "37signals", Firm.all.merge!(:order => "id").to_a.first.name + assert_equal "37signals", Firm.all.merge!(order: "id").to_a.first.name end def test_alt_update_all_within_inheritance @@ -374,51 +374,51 @@ class InheritanceTest < ActiveRecord::TestCase end def test_find_first_within_inheritance - assert_kind_of Firm, Company.all.merge!(:where => "name = '37signals'").first - assert_kind_of Firm, Firm.all.merge!(:where => "name = '37signals'").first - assert_nil Client.all.merge!(:where => "name = '37signals'").first + assert_kind_of Firm, Company.all.merge!(where: "name = '37signals'").first + assert_kind_of Firm, Firm.all.merge!(where: "name = '37signals'").first + assert_nil Client.all.merge!(where: "name = '37signals'").first end def test_alt_find_first_within_inheritance - assert_kind_of Cabbage, Vegetable.all.merge!(:where => "name = 'his cabbage'").first - assert_kind_of Cabbage, Cabbage.all.merge!(:where => "name = 'his cabbage'").first - assert_nil Cucumber.all.merge!(:where => "name = 'his cabbage'").first + assert_kind_of Cabbage, Vegetable.all.merge!(where: "name = 'his cabbage'").first + assert_kind_of Cabbage, Cabbage.all.merge!(where: "name = 'his cabbage'").first + assert_nil Cucumber.all.merge!(where: "name = 'his cabbage'").first end def test_complex_inheritance very_special_client = VerySpecialClient.create("name" => "veryspecial") assert_equal very_special_client, VerySpecialClient.where("name = 'veryspecial'").first - assert_equal very_special_client, SpecialClient.all.merge!(:where => "name = 'veryspecial'").first - assert_equal very_special_client, Company.all.merge!(:where => "name = 'veryspecial'").first - assert_equal very_special_client, Client.all.merge!(:where => "name = 'veryspecial'").first - assert_equal 1, Client.all.merge!(:where => "name = 'Summit'").to_a.size + assert_equal very_special_client, SpecialClient.all.merge!(where: "name = 'veryspecial'").first + assert_equal very_special_client, Company.all.merge!(where: "name = 'veryspecial'").first + assert_equal very_special_client, Client.all.merge!(where: "name = 'veryspecial'").first + assert_equal 1, Client.all.merge!(where: "name = 'Summit'").to_a.size assert_equal very_special_client, Client.find(very_special_client.id) end def test_alt_complex_inheritance king_cole = KingCole.create("name" => "uniform heads") assert_equal king_cole, KingCole.where("name = 'uniform heads'").first - assert_equal king_cole, GreenCabbage.all.merge!(:where => "name = 'uniform heads'").first - assert_equal king_cole, Cabbage.all.merge!(:where => "name = 'uniform heads'").first - assert_equal king_cole, Vegetable.all.merge!(:where => "name = 'uniform heads'").first - assert_equal 1, Cabbage.all.merge!(:where => "name = 'his cabbage'").to_a.size + assert_equal king_cole, GreenCabbage.all.merge!(where: "name = 'uniform heads'").first + assert_equal king_cole, Cabbage.all.merge!(where: "name = 'uniform heads'").first + assert_equal king_cole, Vegetable.all.merge!(where: "name = 'uniform heads'").first + assert_equal 1, Cabbage.all.merge!(where: "name = 'his cabbage'").to_a.size assert_equal king_cole, Cabbage.find(king_cole.id) end def test_eager_load_belongs_to_something_inherited - account = Account.all.merge!(:includes => :firm).find(1) + account = Account.all.merge!(includes: :firm).find(1) assert account.association(:firm).loaded?, "association was not eager loaded" end def test_alt_eager_loading - cabbage = RedCabbage.all.merge!(:includes => :seller).find(4) + cabbage = RedCabbage.all.merge!(includes: :seller).find(4) assert cabbage.association(:seller).loaded?, "association was not eager loaded" end def test_eager_load_belongs_to_primary_key_quoting con = Account.connection assert_sql(/#{con.quote_table_name('companies')}.#{con.quote_column_name('id')} = 1/) do - Account.all.merge!(:includes => :firm).find(1) + Account.all.merge!(includes: :firm).find(1) end end @@ -428,7 +428,7 @@ class InheritanceTest < ActiveRecord::TestCase def test_inheritance_without_mapping assert_kind_of SpecialSubscriber, SpecialSubscriber.find("webster132") - assert_nothing_raised { s = SpecialSubscriber.new("name" => "And breaaaaathe!"); s.id = 'roger'; s.save } + assert_nothing_raised { s = SpecialSubscriber.new("name" => "And breaaaaathe!"); s.id = "roger"; s.save } end def test_scope_inherited_properly @@ -449,7 +449,7 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase def test_instantiation_doesnt_try_to_require_corresponding_file without_store_full_sti_class do foo = Firm.first.clone - foo.type = 'FirmOnTheFly' + foo.type = "FirmOnTheFly" foo.save! # Should fail without FirmOnTheFly in the type condition. @@ -470,30 +470,30 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase end def test_sti_type_from_attributes_disabled_in_non_sti_class - phone = Shop::Product::Type.new(name: 'Phone') - product = Shop::Product.new(:type => phone) + phone = Shop::Product::Type.new(name: "Phone") + product = Shop::Product.new(type: phone) assert product.save end def test_inheritance_new_with_subclass_as_default original_type = Company.columns_hash["type"].default - ActiveRecord::Base.connection.change_column_default :companies, :type, 'Firm' + ActiveRecord::Base.connection.change_column_default :companies, :type, "Firm" Company.reset_column_information firm = Company.new # without arguments - assert_equal 'Firm', firm.type + assert_equal "Firm", firm.type assert_instance_of Firm, firm - firm = Company.new(firm_name: 'Shri Hans Plastic') # with arguments - assert_equal 'Firm', firm.type + firm = Company.new(firm_name: "Shri Hans Plastic") # with arguments + assert_equal "Firm", firm.type assert_instance_of Firm, firm client = Client.new - assert_equal 'Client', client.type + assert_equal "Client", client.type assert_instance_of Client, client - firm = Company.new(type: 'Client') # overwrite the default type - assert_equal 'Client', firm.type + firm = Company.new(type: "Client") # overwrite the default type + assert_equal "Client", firm.type assert_instance_of Client, firm ensure ActiveRecord::Base.connection.change_column_default :companies, :type, original_type @@ -502,9 +502,8 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase end class InheritanceAttributeTest < ActiveRecord::TestCase - class Company < ActiveRecord::Base - self.table_name = 'companies' + self.table_name = "companies" attribute :type, :string, default: "InheritanceAttributeTest::Startup" end @@ -516,11 +515,11 @@ class InheritanceAttributeTest < ActiveRecord::TestCase def test_inheritance_new_with_subclass_as_default startup = Company.new # without arguments - assert_equal 'InheritanceAttributeTest::Startup', startup.type + assert_equal "InheritanceAttributeTest::Startup", startup.type assert_instance_of Startup, startup - empire = Company.new(type: 'InheritanceAttributeTest::Empire') # without arguments - assert_equal 'InheritanceAttributeTest::Empire', empire.type + empire = Company.new(type: "InheritanceAttributeTest::Empire") # without arguments + assert_equal "InheritanceAttributeTest::Empire", empire.type assert_instance_of Empire, empire end end @@ -555,7 +554,7 @@ class InheritanceAttributeMappingTest < ActiveRecord::TestCase end class Company < ActiveRecord::Base - self.table_name = 'companies' + self.table_name = "companies" attribute :type, :omg_sti end @@ -563,18 +562,18 @@ class InheritanceAttributeMappingTest < ActiveRecord::TestCase class Empire < Company; end class Sponsor < ActiveRecord::Base - self.table_name = 'sponsors' + self.table_name = "sponsors" attribute :sponsorable_type, :omg_sti belongs_to :sponsorable, polymorphic: true end def test_sti_with_custom_type - Startup.create! name: 'a Startup' - Empire.create! name: 'an Empire' + Startup.create! name: "a Startup" + Empire.create! name: "an Empire" assert_equal [["a Startup", "omg_inheritance_attribute_mapping_test/startup"], - ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.connection.select_rows('SELECT name, type FROM companies').sort + ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.connection.select_rows("SELECT name, type FROM companies").sort assert_equal [["a Startup", "InheritanceAttributeMappingTest::Startup"], ["an Empire", "InheritanceAttributeMappingTest::Empire"]], Company.all.map { |a| [a.name, a.type] }.sort @@ -583,17 +582,17 @@ class InheritanceAttributeMappingTest < ActiveRecord::TestCase startup.save! assert_equal [["a Startup", "omg_inheritance_attribute_mapping_test/empire"], - ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.connection.select_rows('SELECT name, type FROM companies').sort + ["an Empire", "omg_inheritance_attribute_mapping_test/empire"]], ActiveRecord::Base.connection.select_rows("SELECT name, type FROM companies").sort assert_equal [["a Startup", "InheritanceAttributeMappingTest::Empire"], ["an Empire", "InheritanceAttributeMappingTest::Empire"]], Company.all.map { |a| [a.name, a.type] }.sort end def test_polymorphic_associations_custom_type - startup = Startup.create! name: 'a Startup' + startup = Startup.create! name: "a Startup" sponsor = Sponsor.create! sponsorable: startup - assert_equal ["omg_inheritance_attribute_mapping_test/company"], ActiveRecord::Base.connection.select_values('SELECT sponsorable_type FROM sponsors') + assert_equal ["omg_inheritance_attribute_mapping_test/company"], ActiveRecord::Base.connection.select_values("SELECT sponsorable_type FROM sponsors") sponsor = Sponsor.first assert_equal startup, sponsor.sponsorable diff --git a/activerecord/test/cases/integration_test.rb b/activerecord/test/cases/integration_test.rb index 08a186ae07..00457965d7 100644 --- a/activerecord/test/cases/integration_test.rb +++ b/activerecord/test/cases/integration_test.rb @@ -1,10 +1,10 @@ -require 'cases/helper' -require 'models/company' -require 'models/developer' -require 'models/computer' -require 'models/owner' -require 'models/pet' +require "cases/helper" +require "models/company" +require "models/developer" +require "models/computer" +require "models/owner" +require "models/pet" class IntegrationTest < ActiveRecord::TestCase fixtures :companies, :developers, :owners, :pets @@ -21,53 +21,79 @@ class IntegrationTest < ActiveRecord::TestCase def test_to_param_returns_id_if_not_persisted_but_id_is_set client = Client.new client.id = 1 - assert_equal '1', client.to_param + assert_equal "1", client.to_param end def test_to_param_class_method firm = Firm.find(4) - assert_equal '4-flamboyant-software', firm.to_param + assert_equal "4-flamboyant-software", firm.to_param + end + + def test_to_param_class_method_truncates_words_properly + firm = Firm.find(4) + firm.name << ", Inc." + assert_equal "4-flamboyant-software", firm.to_param + end + + def test_to_param_class_method_truncates_after_parameterize + firm = Firm.find(4) + firm.name = "Huey, Dewey, & Louie LLC" + # 123456789T123456789v + assert_equal "4-huey-dewey-louie-llc", firm.to_param + end + + def test_to_param_class_method_truncates_after_parameterize_with_hyphens + firm = Firm.find(4) + firm.name = "Door-to-Door Wash-n-Fold Service" + # 123456789T123456789v + assert_equal "4-door-to-door-wash-n", firm.to_param end def test_to_param_class_method_truncates firm = Firm.find(4) - firm.name = 'a ' * 100 - assert_equal '4-a-a-a-a-a-a-a-a-a', firm.to_param + firm.name = "a " * 100 + assert_equal "4-a-a-a-a-a-a-a-a-a-a", firm.to_param end def test_to_param_class_method_truncates_edge_case firm = Firm.find(4) - firm.name = 'David HeinemeierHansson' - assert_equal '4-david', firm.to_param + firm.name = "David HeinemeierHansson" + assert_equal "4-david", firm.to_param + end + + def test_to_param_class_method_truncates_case_shown_in_doc + firm = Firm.find(4) + firm.name = "David Heinemeier Hansson" + assert_equal "4-david-heinemeier", firm.to_param end def test_to_param_class_method_squishes firm = Firm.find(4) firm.name = "ab \n" * 100 - assert_equal '4-ab-ab-ab-ab-ab-ab', firm.to_param + assert_equal "4-ab-ab-ab-ab-ab-ab-ab", firm.to_param end def test_to_param_class_method_multibyte_character firm = Firm.find(4) firm.name = "戦場ヶ原 ひたぎ" - assert_equal '4', firm.to_param + assert_equal "4", firm.to_param end def test_to_param_class_method_uses_default_if_blank firm = Firm.find(4) firm.name = nil - assert_equal '4', firm.to_param - firm.name = ' ' - assert_equal '4', firm.to_param + assert_equal "4", firm.to_param + firm.name = " " + assert_equal "4", firm.to_param end def test_to_param_class_method_uses_default_if_not_persisted - firm = Firm.new(name: 'Fancy Shirts') + firm = Firm.new(name: "Fancy Shirts") assert_equal nil, firm.to_param end def test_to_param_with_no_arguments - assert_equal 'Firm', Firm.to_param + assert_equal "Firm", Firm.to_param end def test_cache_key_for_existing_record_is_not_timezone_dependent @@ -146,4 +172,10 @@ class IntegrationTest < ActiveRecord::TestCase owner = owners(:blackbeard) assert_equal "owners/#{owner.id}-#{owner.happy_at.utc.to_s(:usec)}", owner.cache_key(:updated_at, :happy_at) end + + def test_cache_key_when_named_timestamp_is_nil + owner = owners(:blackbeard) + owner.happy_at = nil + assert_equal "owners/#{owner.id}", owner.cache_key(:happy_at) + end end diff --git a/activerecord/test/cases/invalid_connection_test.rb b/activerecord/test/cases/invalid_connection_test.rb index a16b52751a..1367af2859 100644 --- a/activerecord/test/cases/invalid_connection_test.rb +++ b/activerecord/test/cases/invalid_connection_test.rb @@ -1,24 +1,24 @@ require "cases/helper" if current_adapter?(:Mysql2Adapter) -class TestAdapterWithInvalidConnection < ActiveRecord::TestCase - self.use_transactional_tests = false + class TestAdapterWithInvalidConnection < ActiveRecord::TestCase + self.use_transactional_tests = false - class Bird < ActiveRecord::Base - end + class Bird < ActiveRecord::Base + end - def setup - # Can't just use current adapter; sqlite3 will create a database - # file on the fly. - Bird.establish_connection adapter: 'mysql2', database: 'i_do_not_exist' - end + def setup + # Can't just use current adapter; sqlite3 will create a database + # file on the fly. + Bird.establish_connection adapter: "mysql2", database: "i_do_not_exist" + end - teardown do - Bird.remove_connection - end + teardown do + Bird.remove_connection + end - test "inspect on Model class does not raise" do - assert_equal "#{Bird.name} (call '#{Bird.name}.connection' to establish a connection)", Bird.inspect + test "inspect on Model class does not raise" do + assert_equal "#{Bird.name} (call '#{Bird.name}.connection' to establish a connection)", Bird.inspect + end end end -end diff --git a/activerecord/test/cases/invertible_migration_test.rb b/activerecord/test/cases/invertible_migration_test.rb index e030f6c588..9d5aace7db 100644 --- a/activerecord/test/cases/invertible_migration_test.rb +++ b/activerecord/test/cases/invertible_migration_test.rb @@ -6,7 +6,7 @@ end module ActiveRecord class InvertibleMigrationTest < ActiveRecord::TestCase class SilentMigration < ActiveRecord::Migration::Current - def write(text = '') + def write(text = "") # sssshhhhh!! end end @@ -151,6 +151,14 @@ module ActiveRecord end end + class RevertCustomForeignKeyTable < SilentMigration + def change + change_table(:horses) do |t| + t.references :owner, foreign_key: { to_table: :developers } + end + end + end + setup do @verbose_was, ActiveRecord::Migration.verbose = ActiveRecord::Migration.verbose, false end @@ -217,7 +225,7 @@ module ActiveRecord InvertibleMigration.new.migrate :up received = [] migration = InvertibleByPartsMigration.new - migration.test = ->(dir){ + migration.test = ->(dir) { ActiveSupport::Deprecation.silence do assert migration.connection.table_exists?("horses") assert migration.connection.table_exists?("new_horses") @@ -283,21 +291,21 @@ module ActiveRecord migration1.migrate(:up) migration2.migrate(:up) - assert_equal true, Horse.connection.extension_enabled?('hstore') + assert_equal true, Horse.connection.extension_enabled?("hstore") migration3.migrate(:up) - assert_equal false, Horse.connection.extension_enabled?('hstore') + assert_equal false, Horse.connection.extension_enabled?("hstore") migration3.migrate(:down) - assert_equal true, Horse.connection.extension_enabled?('hstore') + assert_equal true, Horse.connection.extension_enabled?("hstore") migration2.migrate(:down) - assert_equal false, Horse.connection.extension_enabled?('hstore') + assert_equal false, Horse.connection.extension_enabled?("hstore") end end def test_revert_order - block = Proc.new{|t| t.string :name } + block = Proc.new { |t| t.string :name } recorder = ActiveRecord::Migration::CommandRecorder.new(ActiveRecord::Base.connection) recorder.instance_eval do create_table("apples", &block) @@ -343,14 +351,21 @@ module ActiveRecord end def test_migrate_down_with_table_name_prefix - ActiveRecord::Base.table_name_prefix = 'p_' - ActiveRecord::Base.table_name_suffix = '_s' + ActiveRecord::Base.table_name_prefix = "p_" + ActiveRecord::Base.table_name_suffix = "_s" migration = InvertibleMigration.new migration.migrate(:up) assert_nothing_raised { migration.migrate(:down) } ActiveSupport::Deprecation.silence { assert !ActiveRecord::Base.connection.table_exists?("p_horses_s"), "p_horses_s should not exist" } ensure - ActiveRecord::Base.table_name_prefix = ActiveRecord::Base.table_name_suffix = '' + ActiveRecord::Base.table_name_prefix = ActiveRecord::Base.table_name_suffix = "" + end + + def test_migrations_can_handle_foreign_keys_to_specific_tables + migration = RevertCustomForeignKeyTable.new + InvertibleMigration.migrate(:up) + migration.migrate(:up) + migration.migrate(:down) end # MySQL 5.7 and Oracle do not allow to create duplicate indexes on the same columns @@ -367,6 +382,5 @@ module ActiveRecord "horses_index_named index should not exist" end end - end end diff --git a/activerecord/test/cases/json_serialization_test.rb b/activerecord/test/cases/json_serialization_test.rb index a222675918..b06fed4f0d 100644 --- a/activerecord/test/cases/json_serialization_test.rb +++ b/activerecord/test/cases/json_serialization_test.rb @@ -1,21 +1,21 @@ require "cases/helper" -require 'models/contact' -require 'models/post' -require 'models/author' -require 'models/tagging' -require 'models/tag' -require 'models/comment' +require "models/contact" +require "models/post" +require "models/author" +require "models/tagging" +require "models/tag" +require "models/comment" module JsonSerializationHelpers private - def set_include_root_in_json(value) - original_root_in_json = ActiveRecord::Base.include_root_in_json - ActiveRecord::Base.include_root_in_json = value - yield - ensure - ActiveRecord::Base.include_root_in_json = original_root_in_json - end + def set_include_root_in_json(value) + original_root_in_json = ActiveRecord::Base.include_root_in_json + ActiveRecord::Base.include_root_in_json = value + yield + ensure + ActiveRecord::Base.include_root_in_json = original_root_in_json + end end class JsonSerializationTest < ActiveRecord::TestCase @@ -27,18 +27,18 @@ class JsonSerializationTest < ActiveRecord::TestCase def setup @contact = Contact.new( - :name => 'Konata Izumi', - :age => 16, - :avatar => 'binarydata', - :created_at => Time.utc(2006, 8, 1), - :awesome => true, - :preferences => { :shows => 'anime' } + name: "Konata Izumi", + age: 16, + avatar: "binarydata", + created_at: Time.utc(2006, 8, 1), + awesome: true, + preferences: { shows: "anime" } ) end def test_should_demodulize_root_in_json set_include_root_in_json(true) do - @contact = NamespacedContact.new name: 'whatever' + @contact = NamespacedContact.new name: "whatever" json = @contact.to_json assert_match %r{^\{"namespaced_contact":\{}, json end @@ -51,7 +51,7 @@ class JsonSerializationTest < ActiveRecord::TestCase assert_match %r{^\{"contact":\{}, json assert_match %r{"name":"Konata Izumi"}, json assert_match %r{"age":16}, json - assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))})) + assert_includes json, %("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}) assert_match %r{"awesome":true}, json assert_match %r{"preferences":\{"shows":"anime"\}}, json end @@ -62,28 +62,28 @@ class JsonSerializationTest < ActiveRecord::TestCase assert_match %r{"name":"Konata Izumi"}, json assert_match %r{"age":16}, json - assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))})) + assert_includes json, %("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}) assert_match %r{"awesome":true}, json assert_match %r{"preferences":\{"shows":"anime"\}}, json end def test_should_allow_attribute_filtering_with_only - json = @contact.to_json(:only => [:name, :age]) + json = @contact.to_json(only: [:name, :age]) assert_match %r{"name":"Konata Izumi"}, json assert_match %r{"age":16}, json assert_no_match %r{"awesome":true}, json - assert !json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))})) + assert_not_includes json, %("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}) assert_no_match %r{"preferences":\{"shows":"anime"\}}, json end def test_should_allow_attribute_filtering_with_except - json = @contact.to_json(:except => [:name, :age]) + json = @contact.to_json(except: [:name, :age]) assert_no_match %r{"name":"Konata Izumi"}, json assert_no_match %r{"age":16}, json assert_match %r{"awesome":true}, json - assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))})) + assert_includes json, %("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}) assert_match %r{"preferences":\{"shows":"anime"\}}, json end @@ -93,10 +93,10 @@ class JsonSerializationTest < ActiveRecord::TestCase def @contact.favorite_quote; "Constraints are liberating"; end # Single method. - assert_match %r{"label":"Has cheezburger"}, @contact.to_json(:only => :name, :methods => :label) + assert_match %r{"label":"Has cheezburger"}, @contact.to_json(only: :name, methods: :label) # Both methods. - methods_json = @contact.to_json(:only => :name, :methods => [:label, :favorite_quote]) + methods_json = @contact.to_json(only: :name, methods: [:label, :favorite_quote]) assert_match %r{"label":"Has cheezburger"}, methods_json assert_match %r{"favorite_quote":"Constraints are liberating"}, methods_json end @@ -125,7 +125,7 @@ class JsonSerializationTest < ActiveRecord::TestCase def test_does_not_include_inheritance_column_from_sti @contact = ContactSti.new(@contact.attributes) - assert_equal 'ContactSti', @contact.type + assert_equal "ContactSti", @contact.type json = @contact.to_json assert_match %r{"name":"Konata Izumi"}, json @@ -135,7 +135,7 @@ class JsonSerializationTest < ActiveRecord::TestCase def test_serializable_hash_with_default_except_option_and_excluding_inheritance_column_from_sti @contact = ContactSti.new(@contact.attributes) - assert_equal 'ContactSti', @contact.type + assert_equal "ContactSti", @contact.type def @contact.serializable_hash(options={}) super({ except: %w(age) }.merge!(options)) @@ -149,7 +149,7 @@ class JsonSerializationTest < ActiveRecord::TestCase end def test_serializable_hash_should_not_modify_options_in_argument - options = { :only => :name } + options = { only: :name } @contact.serializable_hash(options) assert_nil options[:except] @@ -167,7 +167,7 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase end def test_includes_uses_association_name - json = @david.to_json(:include => :posts) + json = @david.to_json(include: :posts) assert_match %r{"posts":\[}, json @@ -183,7 +183,7 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase end def test_includes_uses_association_name_and_applies_attribute_filters - json = @david.to_json(:include => { :posts => { :only => :title } }) + json = @david.to_json(include: { posts: { only: :title } }) assert_match %r{"name":"David"}, json assert_match %r{"posts":\[}, json @@ -196,7 +196,7 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase end def test_includes_fetches_second_level_associations - json = @david.to_json(:include => { :posts => { :include => { :comments => { :only => :body } } } }) + json = @david.to_json(include: { posts: { include: { comments: { only: :body } } } }) assert_match %r{"name":"David"}, json assert_match %r{"posts":\[}, json @@ -209,12 +209,12 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase def test_includes_fetches_nth_level_associations json = @david.to_json( - :include => { - :posts => { - :include => { - :taggings => { - :include => { - :tag => { :only => :name } + include: { + posts: { + include: { + taggings: { + include: { + tag: { only: :name } } } } @@ -230,8 +230,8 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase def test_includes_doesnt_merge_opts_from_base json = @david.to_json( - :only => :id, - :include => :posts + only: :id, + include: :posts ) assert_match %{"title":"Welcome to the weblog"}, json @@ -239,7 +239,7 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase def test_should_not_call_methods_on_associations_that_dont_respond def @david.favorite_quote; "Constraints are liberating"; end - json = @david.to_json(:include => :posts, :methods => :favorite_quote) + json = @david.to_json(include: :posts, methods: :favorite_quote) assert !@david.posts.first.respond_to?(:favorite_quote) assert_match %r{"favorite_quote":"Constraints are liberating"}, json @@ -267,15 +267,15 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase def test_should_allow_includes_for_list_of_authors authors = [@david, @mary] json = ActiveSupport::JSON.encode(authors, - :only => :name, - :include => { - :posts => { :only => :id } + only: :name, + include: { + posts: { only: :id } } ) ['"name":"David"', '"posts":[', '{"id":1}', '{"id":2}', '{"id":4}', '{"id":5}', '{"id":6}', '"name":"Mary"', '"posts":[', '{"id":7}', '{"id":9}'].each do |fragment| - assert json.include?(fragment), json + assert_includes json, fragment, json end end diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index 9fc0041892..13b6f6daaf 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -1,18 +1,18 @@ -require 'thread' +require "thread" require "cases/helper" -require 'models/person' -require 'models/job' -require 'models/reader' -require 'models/ship' -require 'models/legacy_thing' -require 'models/personal_legacy_thing' -require 'models/reference' -require 'models/string_key_object' -require 'models/car' -require 'models/bulb' -require 'models/engine' -require 'models/wheel' -require 'models/treasure' +require "models/person" +require "models/job" +require "models/reader" +require "models/ship" +require "models/legacy_thing" +require "models/personal_legacy_thing" +require "models/reference" +require "models/string_key_object" +require "models/car" +require "models/bulb" +require "models/engine" +require "models/wheel" +require "models/treasure" class LockWithoutDefault < ActiveRecord::Base; end @@ -33,7 +33,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase p1 = Person.find(1) assert_equal 0, p1.lock_version - p1.first_name = 'anika2' + p1.first_name = "anika2" p1.save! assert_equal 1, p1.lock_version @@ -45,12 +45,12 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal 0, s1.lock_version assert_equal 0, s2.lock_version - s1.name = 'updated record' + s1.name = "updated record" s1.save! assert_equal 1, s1.lock_version assert_equal 0, s2.lock_version - s2.name = 'doubly updated record' + s2.name = "doubly updated record" assert_raise(ActiveRecord::StaleObjectError) { s2.save! } end @@ -60,7 +60,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal 0, s1.lock_version assert_equal 0, s2.lock_version - s1.name = 'updated record' + s1.name = "updated record" s1.save! assert_equal 1, s1.lock_version assert_equal 0, s2.lock_version @@ -78,12 +78,12 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal 0, p1.lock_version assert_equal 0, p2.lock_version - p1.first_name = 'stu' + p1.first_name = "stu" p1.save! assert_equal 1, p1.lock_version assert_equal 0, p2.lock_version - p2.first_name = 'sue' + p2.first_name = "sue" assert_raise(ActiveRecord::StaleObjectError) { p2.save! } end @@ -94,7 +94,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal 0, p1.lock_version assert_equal 0, p2.lock_version - p1.first_name = 'stu' + p1.first_name = "stu" p1.save! assert_equal 1, p1.lock_version assert_equal 0, p2.lock_version @@ -113,56 +113,56 @@ class OptimisticLockingTest < ActiveRecord::TestCase assert_equal 0, p1.lock_version assert_equal 0, p2.lock_version - p1.first_name = 'stu' + p1.first_name = "stu" p1.save! assert_equal 1, p1.lock_version assert_equal 0, p2.lock_version - p2.first_name = 'sue' + p2.first_name = "sue" assert_raise(ActiveRecord::StaleObjectError) { p2.save! } - p2.first_name = 'sue2' + p2.first_name = "sue2" assert_raise(ActiveRecord::StaleObjectError) { p2.save! } end def test_lock_new - p1 = Person.new(:first_name => 'anika') + p1 = Person.new(first_name: "anika") assert_equal 0, p1.lock_version - p1.first_name = 'anika2' + p1.first_name = "anika2" p1.save! p2 = Person.find(p1.id) assert_equal 0, p1.lock_version assert_equal 0, p2.lock_version - p1.first_name = 'anika3' + p1.first_name = "anika3" p1.save! assert_equal 1, p1.lock_version assert_equal 0, p2.lock_version - p2.first_name = 'sue' + p2.first_name = "sue" assert_raise(ActiveRecord::StaleObjectError) { p2.save! } end def test_lock_exception_record - p1 = Person.new(:first_name => 'mira') + p1 = Person.new(first_name: "mira") assert_equal 0, p1.lock_version - p1.first_name = 'mira2' + p1.first_name = "mira2" p1.save! p2 = Person.find(p1.id) assert_equal 0, p1.lock_version assert_equal 0, p2.lock_version - p1.first_name = 'mira3' + p1.first_name = "mira3" p1.save! - p2.first_name = 'sue' + p2.first_name = "sue" error = assert_raise(ActiveRecord::StaleObjectError) { p2.save! } assert_equal(error.record.object_id, p2.object_id) end def test_lock_new_with_nil - p1 = Person.new(:first_name => 'anika') + p1 = Person.new(first_name: "anika") p1.save! p1.lock_version = nil # simulate bad fixture or column with no default p1.save! @@ -170,7 +170,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase end def test_lock_new_when_explicitly_passing_nil - p1 = Person.new(:first_name => 'anika', lock_version: nil) + p1 = Person.new(first_name: "anika", lock_version: nil) p1.save! assert_equal 0, p1.lock_version end @@ -181,12 +181,13 @@ class OptimisticLockingTest < ActiveRecord::TestCase p1.touch assert_equal 1, p1.lock_version + assert_not p1.changed?, "Changes should have been cleared" end def test_touch_stale_object - person = Person.create!(first_name: 'Mehmet Emin') + person = Person.create!(first_name: "Mehmet Emin") stale_person = Person.find(person.id) - person.update_attribute(:gender, 'M') + person.update_attribute(:gender, "M") assert_raises(ActiveRecord::StaleObjectError) do stale_person.touch @@ -209,11 +210,11 @@ class OptimisticLockingTest < ActiveRecord::TestCase end def test_lock_column_is_mass_assignable - p1 = Person.create(:first_name => 'bianca') + p1 = Person.create(first_name: "bianca") assert_equal 0, p1.lock_version assert_equal p1.lock_version, Person.new(p1.attributes).lock_version - p1.first_name = 'bianca2' + p1.first_name = "bianca2" p1.save! assert_equal 1, p1.lock_version assert_equal p1.lock_version, Person.new(p1.attributes).lock_version @@ -240,9 +241,9 @@ class OptimisticLockingTest < ActiveRecord::TestCase end def test_readonly_attributes - assert_equal Set.new([ 'name' ]), ReadonlyNameShip.readonly_attributes + assert_equal Set.new([ "name" ]), ReadonlyNameShip.readonly_attributes - s = ReadonlyNameShip.create(:name => "unchangeable name") + s = ReadonlyNameShip.create(name: "unchangeable name") s.reload assert_equal "unchangeable name", s.name @@ -261,7 +262,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase # is nothing else being updated. def test_update_without_attributes_does_not_only_update_lock_version assert_nothing_raised do - p1 = Person.create!(:first_name => 'anika') + p1 = Person.create!(first_name: "anika") lock_version = p1.lock_version p1.save p1.reload @@ -272,17 +273,17 @@ class OptimisticLockingTest < ActiveRecord::TestCase def test_polymorphic_destroy_with_dependencies_and_lock_version car = Car.create! - assert_difference 'car.wheels.count' do + assert_difference "car.wheels.count" do car.wheels << Wheel.create! end - assert_difference 'car.wheels.count', -1 do + assert_difference "car.wheels.count", -1 do car.reload.destroy end assert car.destroyed? end def test_removing_has_and_belongs_to_many_associations_upon_destroy - p = RichPerson.create! first_name: 'Jon' + p = RichPerson.create! first_name: "Jon" p.treasures.create! assert !p.treasures.empty? p.destroy @@ -306,7 +307,7 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase # of a test (see test_increment_counter_*). self.use_transactional_tests = false - { :lock_version => Person, :custom_lock_version => LegacyThing }.each do |name, model| + { lock_version: Person, custom_lock_version: LegacyThing }.each do |name, model| define_method("test_increment_counter_updates_#{name}") do counter_test model, 1 do |id| model.increment_counter :test_count, id @@ -321,7 +322,7 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase define_method("test_update_counters_updates_#{name}") do counter_test model, 1 do |id| - model.update_counters id, :test_count => 1 + model.update_counters id, test_count: 1 end end end @@ -329,13 +330,13 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase # See Lighthouse ticket #1966 def test_destroy_dependents # Establish dependent relationship between Person and PersonalLegacyThing - add_counter_column_to(Person, 'personal_legacy_things_count') + add_counter_column_to(Person, "personal_legacy_things_count") PersonalLegacyThing.reset_column_information # Make sure that counter incrementing doesn't cause problems - p1 = Person.new(:first_name => 'fjord') + p1 = Person.new(first_name: "fjord") p1.save! - t = PersonalLegacyThing.new(:person => p1) + t = PersonalLegacyThing.new(person: p1) t.save! p1.reload assert_equal 1, p1.personal_legacy_things_count @@ -344,14 +345,14 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase assert_raises(ActiveRecord::RecordNotFound) { Person.find(p1.id) } assert_raises(ActiveRecord::RecordNotFound) { PersonalLegacyThing.find(t.id) } ensure - remove_counter_column_from(Person, 'personal_legacy_things_count') + remove_counter_column_from(Person, "personal_legacy_things_count") PersonalLegacyThing.reset_column_information end private - def add_counter_column_to(model, col='test_count') - model.connection.add_column model.table_name, col, :integer, :null => false, :default => 0 + def add_counter_column_to(model, col="test_count") + model.connection.add_column model.table_name, col, :integer, null: false, default: 0 model.reset_column_information end @@ -374,7 +375,6 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase end end - # TODO: test against the generated SQL since testing locking behavior itself # is so cumbersome. Will deadlock Ruby threads if the underlying db.execute # blocks, so separate script called by Kernel#system is needed. @@ -416,7 +416,7 @@ unless in_memory_db? assert_nothing_raised do Person.transaction do person = Person.find 1 - old, person.first_name = person.first_name, 'fooman' + old, person.first_name = person.first_name, "fooman" person.lock! assert_equal old, person.first_name end @@ -426,19 +426,19 @@ unless in_memory_db? def test_with_lock_commits_transaction person = Person.find 1 person.with_lock do - person.first_name = 'fooman' + person.first_name = "fooman" person.save! end - assert_equal 'fooman', person.reload.first_name + assert_equal "fooman", person.reload.first_name end def test_with_lock_rolls_back_transaction person = Person.find 1 old = person.first_name person.with_lock do - person.first_name = 'fooman' + person.first_name = "fooman" person.save! - raise 'oops' + raise "oops" end rescue nil assert_equal old, person.reload.first_name end @@ -448,7 +448,7 @@ unless in_memory_db? Person.transaction do person = Person.find(1) assert_sql(/LIMIT \$?\d FOR SHARE NOWAIT/) do - person.lock!('FOR SHARE NOWAIT') + person.lock!("FOR SHARE NOWAIT") end end end @@ -461,33 +461,33 @@ unless in_memory_db? end protected - def duel(zzz = 5) - t0, t1, t2, t3 = nil, nil, nil, nil - - a = Thread.new do - t0 = Time.now - Person.transaction do - yield - sleep zzz # block thread 2 for zzz seconds - end - t1 = Time.now - end + def duel(zzz = 5) + t0, t1, t2, t3 = nil, nil, nil, nil - b = Thread.new do - sleep zzz / 2.0 # ensure thread 1 tx starts first - t2 = Time.now - Person.transaction { yield } - t3 = Time.now + a = Thread.new do + t0 = Time.now + Person.transaction do + yield + sleep zzz # block thread 2 for zzz seconds end + t1 = Time.now + end - a.join - b.join - - assert t1 > t0 + zzz - assert t2 > t0 - assert t3 > t2 - [t0.to_f..t1.to_f, t2.to_f..t3.to_f] + b = Thread.new do + sleep zzz / 2.0 # ensure thread 1 tx starts first + t2 = Time.now + Person.transaction { yield } + t3 = Time.now end + + a.join + b.join + + assert t1 > t0 + zzz + assert t2 > t0 + assert t3 > t2 + [t0.to_f..t1.to_f, t2.to_f..t3.to_f] + end end end end diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb index 707a2d1da1..90ad970e16 100644 --- a/activerecord/test/cases/log_subscriber_test.rb +++ b/activerecord/test/cases/log_subscriber_test.rb @@ -30,7 +30,7 @@ class LogSubscriberTest < ActiveRecord::TestCase super end - def debug message + def debug(message) @debugs << message end end @@ -60,20 +60,20 @@ class LogSubscriberTest < ActiveRecord::TestCase logger = TestDebugLogSubscriber.new assert_equal 0, logger.debugs.length - logger.sql(event.new(0, sql: 'hi mom!')) + logger.sql(event.new(0, sql: "hi mom!")) assert_equal 1, logger.debugs.length - logger.sql(event.new(0, sql: 'hi mom!', name: 'foo')) + logger.sql(event.new(0, sql: "hi mom!", name: "foo")) assert_equal 2, logger.debugs.length - logger.sql(event.new(0, sql: 'hi mom!', name: 'SCHEMA')) + logger.sql(event.new(0, sql: "hi mom!", name: "SCHEMA")) assert_equal 2, logger.debugs.length end def test_sql_statements_are_not_squeezed event = Struct.new(:duration, :payload) logger = TestDebugLogSubscriber.new - logger.sql(event.new(0, sql: 'ruby rails')) + logger.sql(event.new(0, sql: "ruby rails")) assert_match(/ruby rails/, logger.debugs.first) end @@ -103,7 +103,7 @@ class LogSubscriberTest < ActiveRecord::TestCase logger.sql(event.new(0, sql: verb.to_s)) assert_match(/#{REGEXP_BOLD}#{REGEXP_MAGENTA} \(0.0ms\)#{REGEXP_CLEAR}/i, logger.debugs.last) - logger.sql(event.new(0, {sql: verb.to_s, name: "SQL"})) + logger.sql(event.new(0, sql: verb.to_s, name: "SQL")) assert_match(/#{REGEXP_BOLD}#{REGEXP_MAGENTA}SQL \(0.0ms\)#{REGEXP_CLEAR}/i, logger.debugs.last) end end @@ -113,13 +113,13 @@ class LogSubscriberTest < ActiveRecord::TestCase logger = TestDebugLogSubscriber.new logger.colorize_logging = true SQL_COLORINGS.each do |verb, _| - logger.sql(event.new(0, {sql: verb.to_s, name: "Model Load"})) + logger.sql(event.new(0, sql: verb.to_s, name: "Model Load")) assert_match(/#{REGEXP_BOLD}#{REGEXP_CYAN}Model Load \(0.0ms\)#{REGEXP_CLEAR}/i, logger.debugs.last) - logger.sql(event.new(0, {sql: verb.to_s, name: "Model Exists"})) + logger.sql(event.new(0, sql: verb.to_s, name: "Model Exists")) assert_match(/#{REGEXP_BOLD}#{REGEXP_CYAN}Model Exists \(0.0ms\)#{REGEXP_CLEAR}/i, logger.debugs.last) - logger.sql(event.new(0, {sql: verb.to_s, name: "ANY SPECIFIC NAME"})) + logger.sql(event.new(0, sql: verb.to_s, name: "ANY SPECIFIC NAME")) assert_match(/#{REGEXP_BOLD}#{REGEXP_CYAN}ANY SPECIFIC NAME \(0.0ms\)#{REGEXP_CLEAR}/i, logger.debugs.last) end end @@ -211,9 +211,15 @@ class LogSubscriberTest < ActiveRecord::TestCase if ActiveRecord::Base.connection.prepared_statements def test_binary_data_is_not_logged - Binary.create(data: 'some binary data') + Binary.create(data: "some binary data") wait assert_match(/<16 bytes of binary data>/, @logger.logged(:debug).join) end + + def test_binary_data_hash + Binary.create(data: { a: 1 }) + wait + assert_match(/<7 bytes of binary data>/, @logger.logged(:debug).join) + end end end diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb index d6963b48d7..bdb90eaa74 100644 --- a/activerecord/test/cases/migration/change_schema_test.rb +++ b/activerecord/test/cases/migration/change_schema_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class Migration @@ -40,7 +40,7 @@ module ActiveRecord def test_create_table_with_not_null_column connection.create_table :testings do |t| - t.column :foo, :string, :null => false + t.column :foo, :string, null: false end assert_raises(ActiveRecord::StatementInvalid) do @@ -53,11 +53,11 @@ module ActiveRecord mysql = current_adapter?(:Mysql2Adapter) connection.create_table :testings do |t| - t.column :one, :string, :default => "hello" - t.column :two, :boolean, :default => true - t.column :three, :boolean, :default => false - t.column :four, :integer, :default => 1 - t.column :five, :text, :default => "hello" unless mysql + t.column :one, :string, default: "hello" + t.column :two, :boolean, default: true + t.column :three, :boolean, default: false + t.column :four, :integer, default: 1 + t.column :five, :text, default: "hello" unless mysql end columns = connection.columns(:testings) @@ -70,14 +70,14 @@ module ActiveRecord assert_equal "hello", one.default assert_equal true, connection.lookup_cast_type_from_column(two).deserialize(two.default) assert_equal false, connection.lookup_cast_type_from_column(three).deserialize(three.default) - assert_equal '1', four.default + assert_equal "1", four.default assert_equal "hello", five.default unless mysql end if current_adapter?(:PostgreSQLAdapter) def test_add_column_with_array connection.create_table :testings - connection.add_column :testings, :foo, :string, :array => true + connection.add_column :testings, :foo, :string, array: true columns = connection.columns(:testings) array_column = columns.detect { |c| c.name == "foo" } @@ -87,7 +87,7 @@ module ActiveRecord def test_create_table_with_array_column connection.create_table :testings do |t| - t.string :foo, :array => true + t.string :foo, array: true end columns = connection.columns(:testings) @@ -105,9 +105,9 @@ module ActiveRecord eight = columns.detect { |c| c.name == "eight_int" } if current_adapter?(:OracleAdapter) - assert_equal 'NUMBER(19)', eight.sql_type + assert_equal "NUMBER(19)", eight.sql_type elsif current_adapter?(:SQLite3Adapter) - assert_equal 'bigint', eight.sql_type + assert_equal "bigint", eight.sql_type else assert_equal :integer, eight.type assert_equal 8, eight.limit @@ -118,13 +118,13 @@ module ActiveRecord def test_create_table_with_limits connection.create_table :testings do |t| - t.column :foo, :string, :limit => 255 + t.column :foo, :string, limit: 255 t.column :default_int, :integer - t.column :one_int, :integer, :limit => 1 - t.column :four_int, :integer, :limit => 4 - t.column :eight_int, :integer, :limit => 8 + t.column :one_int, :integer, limit: 1 + t.column :four_int, :integer, limit: 4 + t.column :eight_int, :integer, limit: 8 end columns = connection.columns(:testings) @@ -137,20 +137,20 @@ module ActiveRecord eight = columns.detect { |c| c.name == "eight_int" } if current_adapter?(:PostgreSQLAdapter) - assert_equal 'integer', default.sql_type - assert_equal 'smallint', one.sql_type - assert_equal 'integer', four.sql_type - assert_equal 'bigint', eight.sql_type + assert_equal "integer", default.sql_type + assert_equal "smallint", one.sql_type + assert_equal "integer", four.sql_type + assert_equal "bigint", eight.sql_type elsif current_adapter?(:Mysql2Adapter) - assert_match 'int(11)', default.sql_type - assert_match 'tinyint', one.sql_type - assert_match 'int', four.sql_type - assert_match 'bigint', eight.sql_type + assert_match "int(11)", default.sql_type + assert_match "tinyint", one.sql_type + assert_match "int", four.sql_type + assert_match "bigint", eight.sql_type elsif current_adapter?(:OracleAdapter) - assert_equal 'NUMBER(38)', default.sql_type - assert_equal 'NUMBER(1)', one.sql_type - assert_equal 'NUMBER(4)', four.sql_type - assert_equal 'NUMBER(8)', eight.sql_type + assert_equal "NUMBER(38)", default.sql_type + assert_equal "NUMBER(1)", one.sql_type + assert_equal "NUMBER(4)", four.sql_type + assert_equal "NUMBER(8)", eight.sql_type end end @@ -200,8 +200,8 @@ module ActiveRecord end created_columns = connection.columns(table_name) - created_at_column = created_columns.detect {|c| c.name == 'created_at' } - updated_at_column = created_columns.detect {|c| c.name == 'updated_at' } + created_at_column = created_columns.detect { |c| c.name == "created_at" } + updated_at_column = created_columns.detect { |c| c.name == "updated_at" } assert !created_at_column.null assert !updated_at_column.null @@ -213,8 +213,8 @@ module ActiveRecord end created_columns = connection.columns(table_name) - created_at_column = created_columns.detect {|c| c.name == 'created_at' } - updated_at_column = created_columns.detect {|c| c.name == 'updated_at' } + created_at_column = created_columns.detect { |c| c.name == "created_at" } + updated_at_column = created_columns.detect { |c| c.name == "updated_at" } assert created_at_column.null assert updated_at_column.null @@ -231,7 +231,7 @@ module ActiveRecord connection.create_table :testings do |t| t.column :foo, :string end - connection.add_column :testings, :bar, :string, :null => false + connection.add_column :testings, :bar, :string, null: false assert_raise(ActiveRecord::StatementInvalid) do connection.execute "insert into testings (foo, bar) values ('hello', NULL)" @@ -246,7 +246,7 @@ module ActiveRecord con = connection connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}) values (1, 'hello')" - assert_nothing_raised {connection.add_column :testings, :bar, :string, :null => false, :default => "default" } + assert_nothing_raised { connection.add_column :testings, :bar, :string, null: false, default: "default" } assert_raises(ActiveRecord::StatementInvalid) do connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) values (2, 'hello', NULL)" @@ -259,14 +259,14 @@ module ActiveRecord end klass = Class.new(ActiveRecord::Base) - klass.table_name = 'testings' + klass.table_name = "testings" - assert_equal :datetime, klass.columns_hash['foo'].type + assert_equal :datetime, klass.columns_hash["foo"].type if current_adapter?(:PostgreSQLAdapter) - assert_equal 'timestamp without time zone', klass.columns_hash['foo'].sql_type + assert_equal "timestamp without time zone", klass.columns_hash["foo"].sql_type else - assert_equal klass.connection.type_to_sql('datetime'), klass.columns_hash['foo'].sql_type + assert_equal klass.connection.type_to_sql("datetime"), klass.columns_hash["foo"].sql_type end end @@ -275,7 +275,7 @@ module ActiveRecord t.column :select, :string end - connection.change_column :testings, :select, :string, :limit => 10 + connection.change_column :testings, :select, :string, limit: 10 # Oracle needs primary key value from sequence if current_adapter?(:OracleAdapter) @@ -290,17 +290,17 @@ module ActiveRecord t.column :title, :string end person_klass = Class.new(ActiveRecord::Base) - person_klass.table_name = 'testings' + person_klass.table_name = "testings" - person_klass.connection.add_column "testings", "wealth", :integer, :null => false, :default => 99 + person_klass.connection.add_column "testings", "wealth", :integer, null: false, default: 99 person_klass.reset_column_information assert_equal 99, person_klass.column_defaults["wealth"] assert_equal false, person_klass.columns_hash["wealth"].null # Oracle needs primary key value from sequence if current_adapter?(:OracleAdapter) - assert_nothing_raised {person_klass.connection.execute("insert into testings (id, title) values (testings_seq.nextval, 'tester')")} + assert_nothing_raised { person_klass.connection.execute("insert into testings (id, title) values (testings_seq.nextval, 'tester')") } else - assert_nothing_raised {person_klass.connection.execute("insert into testings (title) values ('tester')")} + assert_nothing_raised { person_klass.connection.execute("insert into testings (title) values ('tester')") } end # change column default to see that column doesn't lose its not null definition @@ -317,19 +317,19 @@ module ActiveRecord assert_equal false, person_klass.columns_hash["money"].null # change column - person_klass.connection.change_column "testings", "money", :integer, :null => false, :default => 1000 + person_klass.connection.change_column "testings", "money", :integer, null: false, default: 1000 person_klass.reset_column_information assert_equal 1000, person_klass.column_defaults["money"] assert_equal false, person_klass.columns_hash["money"].null # change column, make it nullable and clear default - person_klass.connection.change_column "testings", "money", :integer, :null => true, :default => nil + person_klass.connection.change_column "testings", "money", :integer, null: true, default: nil person_klass.reset_column_information assert_nil person_klass.columns_hash["money"].default assert_equal true, person_klass.columns_hash["money"].null # change_column_null, make it not nullable and set null values to a default value - person_klass.connection.execute('UPDATE testings SET money = NULL') + person_klass.connection.execute("UPDATE testings SET money = NULL") person_klass.connection.change_column_null "testings", "money", false, 2000 person_klass.reset_column_information assert_nil person_klass.columns_hash["money"].default @@ -346,9 +346,9 @@ module ActiveRecord end notnull_migration.new.suppress_messages do notnull_migration.migrate(:up) - assert_equal false, connection.columns(:testings).find{ |c| c.name == "foo"}.null + assert_equal false, connection.columns(:testings).find { |c| c.name == "foo" }.null notnull_migration.migrate(:down) - assert connection.columns(:testings).find{ |c| c.name == "foo"}.null + assert connection.columns(:testings).find { |c| c.name == "foo" }.null end end end @@ -365,7 +365,7 @@ module ActiveRecord def test_column_exists_with_type connection.create_table :testings do |t| t.column :foo, :string - t.column :bar, :decimal, :precision => 8, :scale => 2 + t.column :bar, :decimal, precision: 8, scale: 2 end assert connection.column_exists?(:testings, :foo, :string) @@ -380,7 +380,7 @@ module ActiveRecord t.column :foo, :string, limit: 100 t.column :bar, :decimal, precision: 8, scale: 2 t.column :taggable_id, :integer, null: false - t.column :taggable_type, :string, default: 'Photo' + t.column :taggable_type, :string, default: "Photo" end assert connection.column_exists?(:testings, :foo, :string, limit: 100) @@ -389,7 +389,7 @@ module ActiveRecord assert_not connection.column_exists?(:testings, :bar, :decimal, precision: nil, scale: nil) assert connection.column_exists?(:testings, :taggable_id, :integer, null: false) assert_not connection.column_exists?(:testings, :taggable_id, :integer, null: true) - assert connection.column_exists?(:testings, :taggable_type, :string, default: 'Photo') + assert connection.column_exists?(:testings, :taggable_type, :string, default: "Photo") assert_not connection.column_exists?(:testings, :taggable_type, :string, default: nil) end @@ -415,13 +415,13 @@ module ActiveRecord end private - def testing_table_with_only_foo_attribute - connection.create_table :testings, :id => false do |t| - t.column :foo, :string - end + def testing_table_with_only_foo_attribute + connection.create_table :testings, id: false do |t| + t.column :foo, :string + end - yield - end + yield + end end if ActiveRecord::Base.connection.supports_foreign_keys? diff --git a/activerecord/test/cases/migration/change_table_test.rb b/activerecord/test/cases/migration/change_table_test.rb index 2f9c50141f..ec817a579b 100644 --- a/activerecord/test/cases/migration/change_table_test.rb +++ b/activerecord/test/cases/migration/change_table_test.rb @@ -95,7 +95,7 @@ module ActiveRecord def test_remove_timestamps_creates_updated_at_and_created_at with_change_table do |t| @connection.expect :remove_timestamps, nil, [:delete_me, { null: true }] - t.remove_timestamps({ null: true }) + t.remove_timestamps(null: true) end end @@ -157,8 +157,8 @@ module ActiveRecord def test_column_creates_column_with_options with_change_table do |t| - @connection.expect :add_column, nil, [:delete_me, :bar, :integer, {:null => false}] - t.column :bar, :integer, :null => false + @connection.expect :add_column, nil, [:delete_me, :bar, :integer, { null: false }] + t.column :bar, :integer, null: false end end @@ -171,8 +171,8 @@ module ActiveRecord def test_index_creates_index_with_options with_change_table do |t| - @connection.expect :add_index, nil, [:delete_me, :bar, {:unique => true}] - t.index :bar, :unique => true + @connection.expect :add_index, nil, [:delete_me, :bar, { unique: true }] + t.index :bar, unique: true end end @@ -185,8 +185,8 @@ module ActiveRecord def test_index_exists_with_options with_change_table do |t| - @connection.expect :index_exists?, nil, [:delete_me, :bar, {:unique => true}] - t.index_exists?(:bar, :unique => true) + @connection.expect :index_exists?, nil, [:delete_me, :bar, { unique: true }] + t.index_exists?(:bar, unique: true) end end @@ -206,8 +206,8 @@ module ActiveRecord def test_change_changes_column_with_options with_change_table do |t| - @connection.expect :change_column, nil, [:delete_me, :bar, :string, {:null => true}] - t.change :bar, :string, :null => true + @connection.expect :change_column, nil, [:delete_me, :bar, :string, { null: true }] + t.change :bar, :string, null: true end end @@ -234,8 +234,8 @@ module ActiveRecord def test_remove_index_removes_index_with_options with_change_table do |t| - @connection.expect :remove_index, nil, [:delete_me, {:unique => true}] - t.remove_index :unique => true + @connection.expect :remove_index, nil, [:delete_me, { unique: true }] + t.remove_index unique: true end end diff --git a/activerecord/test/cases/migration/column_attributes_test.rb b/activerecord/test/cases/migration/column_attributes_test.rb index c7a1b81a75..03d781d3d2 100644 --- a/activerecord/test/cases/migration/column_attributes_test.rb +++ b/activerecord/test/cases/migration/column_attributes_test.rb @@ -9,7 +9,7 @@ module ActiveRecord def test_add_column_newline_default string = "foo\nbar" - add_column 'test_models', 'command', :string, :default => string + add_column "test_models", "command", :string, default: string TestModel.reset_column_information assert_equal string, TestModel.new.command @@ -18,10 +18,10 @@ module ActiveRecord def test_add_remove_single_field_using_string_arguments assert_no_column TestModel, :last_name - add_column 'test_models', 'last_name', :string + add_column "test_models", "last_name", :string assert_column TestModel, :last_name - remove_column 'test_models', 'last_name' + remove_column "test_models", "last_name" assert_no_column TestModel, :last_name end @@ -47,7 +47,7 @@ module ActiveRecord def test_unabstracted_database_dependent_types add_column :test_models, :intelligence_quotient, :tinyint TestModel.reset_column_information - assert_match(/tinyint/, TestModel.columns_hash['intelligence_quotient'].sql_type) + assert_match(/tinyint/, TestModel.columns_hash["intelligence_quotient"].sql_type) end end @@ -56,15 +56,13 @@ module ActiveRecord # functionality. This allows us to more easily catch INSERT being broken, # but SELECT actually working fine. def test_native_decimal_insert_manual_vs_automatic - correct_value = '0012345678901234567890.0123456789'.to_d + correct_value = "0012345678901234567890.0123456789".to_d - connection.add_column "test_models", "wealth", :decimal, :precision => '30', :scale => '10' + connection.add_column "test_models", "wealth", :decimal, precision: "30", scale: "10" # Do a manual insertion if current_adapter?(:OracleAdapter) connection.execute "insert into test_models (id, wealth) values (people_seq.nextval, 12345678901234567890.0123456789)" - elsif current_adapter?(:PostgreSQLAdapter) - connection.execute "insert into test_models (wealth) values (12345678901234567890.0123456789)" else connection.execute "insert into test_models (wealth) values (12345678901234567890.0123456789)" end @@ -82,7 +80,7 @@ module ActiveRecord TestModel.delete_all # Now use the Rails insertion - TestModel.create :wealth => BigDecimal.new("12345678901234567890.0123456789") + TestModel.create wealth: BigDecimal.new("12345678901234567890.0123456789") # SELECT row = TestModel.first @@ -94,26 +92,26 @@ module ActiveRecord end def test_add_column_with_precision_and_scale - connection.add_column 'test_models', 'wealth', :decimal, :precision => 9, :scale => 7 + connection.add_column "test_models", "wealth", :decimal, precision: 9, scale: 7 - wealth_column = TestModel.columns_hash['wealth'] + wealth_column = TestModel.columns_hash["wealth"] assert_equal 9, wealth_column.precision assert_equal 7, wealth_column.scale end if current_adapter?(:SQLite3Adapter) def test_change_column_preserve_other_column_precision_and_scale - connection.add_column 'test_models', 'last_name', :string - connection.add_column 'test_models', 'wealth', :decimal, :precision => 9, :scale => 7 + connection.add_column "test_models", "last_name", :string + connection.add_column "test_models", "wealth", :decimal, precision: 9, scale: 7 - wealth_column = TestModel.columns_hash['wealth'] + wealth_column = TestModel.columns_hash["wealth"] assert_equal 9, wealth_column.precision assert_equal 7, wealth_column.scale - connection.change_column 'test_models', 'last_name', :string, :null => false + connection.change_column "test_models", "last_name", :string, null: false TestModel.reset_column_information - wealth_column = TestModel.columns_hash['wealth'] + wealth_column = TestModel.columns_hash["wealth"] assert_equal 9, wealth_column.precision assert_equal 7, wealth_column.scale end @@ -126,21 +124,21 @@ module ActiveRecord add_column "test_models", "bio", :text add_column "test_models", "age", :integer add_column "test_models", "height", :float - add_column "test_models", "wealth", :decimal, :precision => '30', :scale => '10' + add_column "test_models", "wealth", :decimal, precision: "30", scale: "10" add_column "test_models", "birthday", :datetime add_column "test_models", "favorite_day", :date add_column "test_models", "moment_of_truth", :datetime add_column "test_models", "male", :boolean - TestModel.create :first_name => 'bob', :last_name => 'bobsen', - :bio => "I was born ....", :age => 18, :height => 1.78, - :wealth => BigDecimal.new("12345678901234567890.0123456789"), - :birthday => 18.years.ago, :favorite_day => 10.days.ago, - :moment_of_truth => "1782-10-10 21:40:18", :male => true + TestModel.create first_name: "bob", last_name: "bobsen", + bio: "I was born ....", age: 18, height: 1.78, + wealth: BigDecimal.new("12345678901234567890.0123456789"), + birthday: 18.years.ago, favorite_day: 10.days.ago, + moment_of_truth: "1782-10-10 21:40:18", male: true bob = TestModel.first - assert_equal 'bob', bob.first_name - assert_equal 'bobsen', bob.last_name + assert_equal "bob", bob.first_name + assert_equal "bobsen", bob.last_name assert_equal "I was born ....", bob.bio assert_equal 18, bob.age @@ -154,16 +152,9 @@ module ActiveRecord assert_equal String, bob.first_name.class assert_equal String, bob.last_name.class assert_equal String, bob.bio.class - assert_equal Fixnum, bob.age.class + assert_kind_of Integer, bob.age assert_equal Time, bob.birthday.class - - if current_adapter?(:OracleAdapter) - # Oracle doesn't differentiate between date/time - assert_equal Time, bob.favorite_day.class - else - assert_equal Date, bob.favorite_day.class - end - + assert_equal Date, bob.favorite_day.class assert_instance_of TrueClass, bob.male? assert_kind_of BigDecimal, bob.wealth end @@ -171,10 +162,10 @@ module ActiveRecord if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter) def test_out_of_range_limit_should_raise - assert_raise(ActiveRecordError) { add_column :test_models, :integer_too_big, :integer, :limit => 10 } + assert_raise(ActiveRecordError) { add_column :test_models, :integer_too_big, :integer, limit: 10 } unless current_adapter?(:PostgreSQLAdapter) - assert_raise(ActiveRecordError) { add_column :test_models, :text_too_big, :integer, :limit => 0xfffffffff } + assert_raise(ActiveRecordError) { add_column :test_models, :text_too_big, :integer, limit: 0xfffffffff } end end end diff --git a/activerecord/test/cases/migration/column_positioning_test.rb b/activerecord/test/cases/migration/column_positioning_test.rb index 8294da0373..f2162d91b1 100644 --- a/activerecord/test/cases/migration/column_positioning_test.rb +++ b/activerecord/test/cases/migration/column_positioning_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class Migration @@ -11,7 +11,7 @@ module ActiveRecord @connection = ActiveRecord::Base.connection - connection.create_table :testings, :id => false do |t| + connection.create_table :testings, id: false do |t| t.column :first, :integer t.column :second, :integer t.column :third, :integer @@ -34,20 +34,20 @@ module ActiveRecord end def test_add_column_with_positioning_first - conn.add_column :testings, :new_col, :integer, :first => true + conn.add_column :testings, :new_col, :integer, first: true assert_equal %w(new_col first second third), conn.columns(:testings).map(&:name) end def test_add_column_with_positioning_after - conn.add_column :testings, :new_col, :integer, :after => :first + conn.add_column :testings, :new_col, :integer, after: :first assert_equal %w(first new_col second third), conn.columns(:testings).map(&:name) end def test_change_column_with_positioning - conn.change_column :testings, :second, :integer, :first => true + conn.change_column :testings, :second, :integer, first: true assert_equal %w(second first third), conn.columns(:testings).map(&:name) - conn.change_column :testings, :second, :integer, :after => :third + conn.change_column :testings, :second, :integer, after: :third assert_equal %w(first third second), conn.columns(:testings).map(&:name) end end diff --git a/activerecord/test/cases/migration/columns_test.rb b/activerecord/test/cases/migration/columns_test.rb index fca1cb7e97..55c06da411 100644 --- a/activerecord/test/cases/migration/columns_test.rb +++ b/activerecord/test/cases/migration/columns_test.rb @@ -13,7 +13,7 @@ module ActiveRecord add_column "test_models", "girlfriend", :string TestModel.reset_column_information - TestModel.create :girlfriend => 'bobette' + TestModel.create girlfriend: "bobette" rename_column "test_models", "girlfriend", "exgirlfriend" @@ -28,12 +28,12 @@ module ActiveRecord def test_rename_column_using_symbol_arguments add_column :test_models, :first_name, :string - TestModel.create :first_name => 'foo' + TestModel.create first_name: "foo" rename_column :test_models, :first_name, :nick_name TestModel.reset_column_information - assert TestModel.column_names.include?("nick_name") - assert_equal ['foo'], TestModel.all.map(&:nick_name) + assert_includes TestModel.column_names, "nick_name" + assert_equal ["foo"], TestModel.all.map(&:nick_name) end # FIXME: another integration test. We should decouple this from the @@ -41,25 +41,25 @@ module ActiveRecord def test_rename_column add_column "test_models", "first_name", "string" - TestModel.create :first_name => 'foo' + TestModel.create first_name: "foo" rename_column "test_models", "first_name", "nick_name" TestModel.reset_column_information - assert TestModel.column_names.include?("nick_name") - assert_equal ['foo'], TestModel.all.map(&:nick_name) + assert_includes TestModel.column_names, "nick_name" + assert_equal ["foo"], TestModel.all.map(&:nick_name) end def test_rename_column_preserves_default_value_not_null - add_column 'test_models', 'salary', :integer, :default => 70000 + add_column "test_models", "salary", :integer, default: 70000 default_before = connection.columns("test_models").find { |c| c.name == "salary" }.default - assert_equal '70000', default_before + assert_equal "70000", default_before rename_column "test_models", "salary", "annual_salary" - assert TestModel.column_names.include?("annual_salary") + assert_includes TestModel.column_names, "annual_salary" default_after = connection.columns("test_models").find { |c| c.name == "annual_salary" }.default - assert_equal '70000', default_after + assert_equal "70000", default_after end if current_adapter?(:Mysql2Adapter) @@ -74,30 +74,31 @@ module ActiveRecord def test_rename_nonexistent_column exception = if current_adapter?(:PostgreSQLAdapter, :OracleAdapter) - ActiveRecord::StatementInvalid - else - ActiveRecord::ActiveRecordError - end + ActiveRecord::StatementInvalid + else + ActiveRecord::ActiveRecordError + end + assert_raise(exception) do rename_column "test_models", "nonexistent", "should_fail" end end def test_rename_column_with_sql_reserved_word - add_column 'test_models', 'first_name', :string + add_column "test_models", "first_name", :string rename_column "test_models", "first_name", "group" - assert TestModel.column_names.include?("group") + assert_includes TestModel.column_names, "group" end def test_rename_column_with_an_index add_column "test_models", :hat_name, :string add_index :test_models, :hat_name - assert_equal 1, connection.indexes('test_models').size + assert_equal 1, connection.indexes("test_models").size rename_column "test_models", "hat_name", "name" - assert_equal ['index_test_models_on_name'], connection.indexes('test_models').map(&:name) + assert_equal ["index_test_models_on_name"], connection.indexes("test_models").map(&:name) end def test_rename_column_with_multi_column_index @@ -105,153 +106,153 @@ module ActiveRecord add_column "test_models", :hat_style, :string, limit: 100 add_index "test_models", ["hat_style", "hat_size"], unique: true - rename_column "test_models", "hat_size", 'size' + rename_column "test_models", "hat_size", "size" if current_adapter? :OracleAdapter - assert_equal ['i_test_models_hat_style_size'], connection.indexes('test_models').map(&:name) + assert_equal ["i_test_models_hat_style_size"], connection.indexes("test_models").map(&:name) else - assert_equal ['index_test_models_on_hat_style_and_size'], connection.indexes('test_models').map(&:name) + assert_equal ["index_test_models_on_hat_style_and_size"], connection.indexes("test_models").map(&:name) end - rename_column "test_models", "hat_style", 'style' + rename_column "test_models", "hat_style", "style" if current_adapter? :OracleAdapter - assert_equal ['i_test_models_style_size'], connection.indexes('test_models').map(&:name) + assert_equal ["i_test_models_style_size"], connection.indexes("test_models").map(&:name) else - assert_equal ['index_test_models_on_style_and_size'], connection.indexes('test_models').map(&:name) + assert_equal ["index_test_models_on_style_and_size"], connection.indexes("test_models").map(&:name) end end def test_rename_column_does_not_rename_custom_named_index add_column "test_models", :hat_name, :string - add_index :test_models, :hat_name, :name => 'idx_hat_name' + add_index :test_models, :hat_name, name: "idx_hat_name" - assert_equal 1, connection.indexes('test_models').size + assert_equal 1, connection.indexes("test_models").size rename_column "test_models", "hat_name", "name" - assert_equal ['idx_hat_name'], connection.indexes('test_models').map(&:name) + assert_equal ["idx_hat_name"], connection.indexes("test_models").map(&:name) end def test_remove_column_with_index add_column "test_models", :hat_name, :string add_index :test_models, :hat_name - assert_equal 1, connection.indexes('test_models').size + assert_equal 1, connection.indexes("test_models").size remove_column("test_models", "hat_name") - assert_equal 0, connection.indexes('test_models').size + assert_equal 0, connection.indexes("test_models").size end def test_remove_column_with_multi_column_index add_column "test_models", :hat_size, :integer - add_column "test_models", :hat_style, :string, :limit => 100 - add_index "test_models", ["hat_style", "hat_size"], :unique => true + add_column "test_models", :hat_style, :string, limit: 100 + add_index "test_models", ["hat_style", "hat_size"], unique: true - assert_equal 1, connection.indexes('test_models').size + assert_equal 1, connection.indexes("test_models").size remove_column("test_models", "hat_size") # Every database and/or database adapter has their own behavior # if it drops the multi-column index when any of the indexed columns dropped by remove_column. if current_adapter?(:PostgreSQLAdapter, :OracleAdapter) - assert_equal [], connection.indexes('test_models').map(&:name) + assert_equal [], connection.indexes("test_models").map(&:name) else - assert_equal ['index_test_models_on_hat_style_and_hat_size'], connection.indexes('test_models').map(&:name) + assert_equal ["index_test_models_on_hat_style_and_hat_size"], connection.indexes("test_models").map(&:name) end end def test_change_type_of_not_null_column - change_column "test_models", "updated_at", :datetime, :null => false - change_column "test_models", "updated_at", :datetime, :null => false + change_column "test_models", "updated_at", :datetime, null: false + change_column "test_models", "updated_at", :datetime, null: false TestModel.reset_column_information - assert_equal false, TestModel.columns_hash['updated_at'].null + assert_equal false, TestModel.columns_hash["updated_at"].null ensure - change_column "test_models", "updated_at", :datetime, :null => true + change_column "test_models", "updated_at", :datetime, null: true end def test_change_column_nullability add_column "test_models", "funny", :boolean assert TestModel.columns_hash["funny"].null, "Column 'funny' must initially allow nulls" - change_column "test_models", "funny", :boolean, :null => false, :default => true + change_column "test_models", "funny", :boolean, null: false, default: true TestModel.reset_column_information assert_not TestModel.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point" - change_column "test_models", "funny", :boolean, :null => true + change_column "test_models", "funny", :boolean, null: true TestModel.reset_column_information assert TestModel.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point" end def test_change_column - add_column 'test_models', 'age', :integer - add_column 'test_models', 'approved', :boolean, :default => true + add_column "test_models", "age", :integer + add_column "test_models", "approved", :boolean, default: true old_columns = connection.columns(TestModel.table_name) - assert old_columns.find { |c| c.name == 'age' && c.type == :integer } + assert old_columns.find { |c| c.name == "age" && c.type == :integer } change_column "test_models", "age", :string new_columns = connection.columns(TestModel.table_name) - assert_not new_columns.find { |c| c.name == 'age' and c.type == :integer } - assert new_columns.find { |c| c.name == 'age' and c.type == :string } + assert_not new_columns.find { |c| c.name == "age" && c.type == :integer } + assert new_columns.find { |c| c.name == "age" && c.type == :string } old_columns = connection.columns(TestModel.table_name) assert old_columns.find { |c| default = connection.lookup_cast_type_from_column(c).deserialize(c.default) - c.name == 'approved' && c.type == :boolean && default == true + c.name == "approved" && c.type == :boolean && default == true } - change_column :test_models, :approved, :boolean, :default => false + change_column :test_models, :approved, :boolean, default: false new_columns = connection.columns(TestModel.table_name) assert_not new_columns.find { |c| default = connection.lookup_cast_type_from_column(c).deserialize(c.default) - c.name == 'approved' and c.type == :boolean and default == true + c.name == "approved" && c.type == :boolean && default == true } assert new_columns.find { |c| default = connection.lookup_cast_type_from_column(c).deserialize(c.default) - c.name == 'approved' and c.type == :boolean and default == false + c.name == "approved" && c.type == :boolean && default == false } - change_column :test_models, :approved, :boolean, :default => true + change_column :test_models, :approved, :boolean, default: true end def test_change_column_with_nil_default - add_column "test_models", "contributor", :boolean, :default => true + add_column "test_models", "contributor", :boolean, default: true assert TestModel.new.contributor? - change_column "test_models", "contributor", :boolean, :default => nil + change_column "test_models", "contributor", :boolean, default: nil TestModel.reset_column_information assert_not TestModel.new.contributor? assert_nil TestModel.new.contributor end def test_change_column_with_new_default - add_column "test_models", "administrator", :boolean, :default => true + add_column "test_models", "administrator", :boolean, default: true assert TestModel.new.administrator? - change_column "test_models", "administrator", :boolean, :default => false + change_column "test_models", "administrator", :boolean, default: false TestModel.reset_column_information assert_not TestModel.new.administrator? end def test_change_column_with_custom_index_name add_column "test_models", "category", :string - add_index :test_models, :category, name: 'test_models_categories_idx' + add_index :test_models, :category, name: "test_models_categories_idx" - assert_equal ['test_models_categories_idx'], connection.indexes('test_models').map(&:name) - change_column "test_models", "category", :string, null: false, default: 'article' + assert_equal ["test_models_categories_idx"], connection.indexes("test_models").map(&:name) + change_column "test_models", "category", :string, null: false, default: "article" - assert_equal ['test_models_categories_idx'], connection.indexes('test_models').map(&:name) + assert_equal ["test_models_categories_idx"], connection.indexes("test_models").map(&:name) end def test_change_column_with_long_index_name - table_name_prefix = 'test_models_' - long_index_name = table_name_prefix + ('x' * (connection.allowed_index_name_length - table_name_prefix.length)) + table_name_prefix = "test_models_" + long_index_name = table_name_prefix + ("x" * (connection.allowed_index_name_length - table_name_prefix.length)) add_column "test_models", "category", :string add_index :test_models, :category, name: long_index_name - change_column "test_models", "category", :string, null: false, default: 'article' + change_column "test_models", "category", :string, null: false, default: "article" - assert_equal [long_index_name], connection.indexes('test_models').map(&:name) + assert_equal [long_index_name], connection.indexes("test_models").map(&:name) end def test_change_column_default @@ -287,7 +288,7 @@ module ActiveRecord remove_column("my_table", "col_two") rename_column("my_table", "col_one", "col_three") - assert_equal 'my_table_id', connection.primary_key('my_table') + assert_equal "my_table_id", connection.primary_key("my_table") ensure connection.drop_table(:my_table) rescue nil end diff --git a/activerecord/test/cases/migration/command_recorder_test.rb b/activerecord/test/cases/migration/command_recorder_test.rb index 1e3529db54..802a969cb7 100644 --- a/activerecord/test/cases/migration/command_recorder_test.rb +++ b/activerecord/test/cases/migration/command_recorder_test.rb @@ -25,26 +25,26 @@ module ActiveRecord recorder = CommandRecorder.new(Class.new { def create_table(name); end }.new) - assert recorder.respond_to?(:create_table), 'respond_to? create_table' + assert recorder.respond_to?(:create_table), "respond_to? create_table" recorder.send(:create_table, :horses) assert_equal [[:create_table, [:horses], nil]], recorder.commands end def test_unknown_commands_delegate recorder = Struct.new(:foo) - recorder = CommandRecorder.new(recorder.new('bar')) - assert_equal 'bar', recorder.foo + recorder = CommandRecorder.new(recorder.new("bar")) + assert_equal "bar", recorder.foo end def test_inverse_of_raise_exception_on_unknown_commands assert_raises(ActiveRecord::IrreversibleMigration) do - @recorder.inverse_of :execute, ['some sql'] + @recorder.inverse_of :execute, ["some sql"] end end def test_irreversible_commands_raise_exception assert_raises(ActiveRecord::IrreversibleMigration) do - @recorder.revert{ @recorder.execute 'some sql' } + @recorder.revert { @recorder.execute "some sql" } end end @@ -58,12 +58,12 @@ module ActiveRecord @recorder.record :create_table, [:hello] @recorder.record :create_table, [:world] end - tables = @recorder.commands.map{|_cmd, args, _block| args} + tables = @recorder.commands.map { |_cmd, args, _block| args } assert_equal [[:world], [:hello]], tables end def test_revert_order - block = Proc.new{|t| t.string :name } + block = Proc.new { |t| t.string :name } @recorder.instance_eval do create_table("apples", &block) revert do @@ -115,13 +115,13 @@ module ActiveRecord end def test_invert_create_table_with_options_and_block - block = Proc.new{} + block = Proc.new {} drop_table = @recorder.inverse_of :create_table, [:people_reminders, id: false], &block assert_equal [:drop_table, [:people_reminders, id: false], block], drop_table end def test_invert_drop_table - block = Proc.new{} + block = Proc.new {} create_table = @recorder.inverse_of :drop_table, [:people_reminders, id: false], &block assert_equal [:create_table, [:people_reminders, id: false], block], create_table end @@ -143,7 +143,7 @@ module ActiveRecord end def test_invert_drop_join_table - block = Proc.new{} + block = Proc.new {} create_join_table = @recorder.inverse_of :drop_join_table, [:musics, :artists, table_name: :catalog], &block assert_equal [:create_join_table, [:musics, :artists, table_name: :catalog], block], create_join_table end @@ -166,7 +166,7 @@ module ActiveRecord def test_invert_change_column_default assert_raises(ActiveRecord::IrreversibleMigration) do - @recorder.inverse_of :change_column_default, [:table, :column, 'default_value'] + @recorder.inverse_of :change_column_default, [:table, :column, "default_value"] end end @@ -203,17 +203,17 @@ module ActiveRecord def test_invert_add_index remove = @recorder.inverse_of :add_index, [:table, [:one, :two]] - assert_equal [:remove_index, [:table, {column: [:one, :two]}]], remove + assert_equal [:remove_index, [:table, { column: [:one, :two] }]], remove end def test_invert_add_index_with_name remove = @recorder.inverse_of :add_index, [:table, [:one, :two], name: "new_index"] - assert_equal [:remove_index, [:table, {name: "new_index"}]], remove + assert_equal [:remove_index, [:table, { name: "new_index" }]], remove end def test_invert_add_index_with_no_options remove = @recorder.inverse_of :add_index, [:table, [:one, :two]] - assert_equal [:remove_index, [:table, {column: [:one, :two]}]], remove + assert_equal [:remove_index, [:table, { column: [:one, :two] }]], remove end def test_invert_remove_index @@ -222,17 +222,17 @@ module ActiveRecord end def test_invert_remove_index_with_column - add = @recorder.inverse_of :remove_index, [:table, {column: [:one, :two], options: true}] + add = @recorder.inverse_of :remove_index, [:table, { column: [:one, :two], options: true }] assert_equal [:add_index, [:table, [:one, :two], options: true]], add end def test_invert_remove_index_with_name - add = @recorder.inverse_of :remove_index, [:table, {column: [:one, :two], name: "new_index"}] + add = @recorder.inverse_of :remove_index, [:table, { column: [:one, :two], name: "new_index" }] assert_equal [:add_index, [:table, [:one, :two], name: "new_index"]], add end def test_invert_remove_index_with_no_special_options - add = @recorder.inverse_of :remove_index, [:table, {column: [:one, :two]}] + add = @recorder.inverse_of :remove_index, [:table, { column: [:one, :two] }] assert_equal [:add_index, [:table, [:one, :two], {}]], add end @@ -254,7 +254,7 @@ module ActiveRecord def test_invert_remove_timestamps add = @recorder.inverse_of :remove_timestamps, [:table, { null: true }] - assert_equal [:add_timestamps, [:table, {null: true }], nil], add + assert_equal [:add_timestamps, [:table, { null: true }], nil], add end def test_invert_add_reference @@ -283,13 +283,13 @@ module ActiveRecord end def test_invert_enable_extension - disable = @recorder.inverse_of :enable_extension, ['uuid-ossp'] - assert_equal [:disable_extension, ['uuid-ossp'], nil], disable + disable = @recorder.inverse_of :enable_extension, ["uuid-ossp"] + assert_equal [:disable_extension, ["uuid-ossp"], nil], disable end def test_invert_disable_extension - enable = @recorder.inverse_of :disable_extension, ['uuid-ossp'] - assert_equal [:enable_extension, ['uuid-ossp'], nil], enable + enable = @recorder.inverse_of :disable_extension, ["uuid-ossp"] + assert_equal [:enable_extension, ["uuid-ossp"], nil], enable end def test_invert_add_foreign_key diff --git a/activerecord/test/cases/migration/compatibility_test.rb b/activerecord/test/cases/migration/compatibility_test.rb index 60ca90464d..0a4b604601 100644 --- a/activerecord/test/cases/migration/compatibility_test.rb +++ b/activerecord/test/cases/migration/compatibility_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class Migration @@ -13,8 +13,8 @@ module ActiveRecord ActiveRecord::Migration.verbose = false connection.create_table :testings do |t| - t.column :foo, :string, :limit => 100 - t.column :bar, :string, :limit => 100 + t.column :foo, :string, limit: 100 + t.column :bar, :string, limit: 100 end end @@ -25,7 +25,7 @@ module ActiveRecord end def test_migration_doesnt_remove_named_index - connection.add_index :testings, :foo, :name => "custom_index_name" + connection.add_index :testings, :foo, name: "custom_index_name" migration = Class.new(ActiveRecord::Migration[4.2]) { def version; 101 end @@ -83,8 +83,8 @@ module ActiveRecord ActiveRecord::Migrator.new(:up, [migration]).migrate - assert connection.columns(:more_testings).find { |c| c.name == 'created_at' }.null - assert connection.columns(:more_testings).find { |c| c.name == 'updated_at' }.null + assert connection.columns(:more_testings).find { |c| c.name == "created_at" }.null + assert connection.columns(:more_testings).find { |c| c.name == "updated_at" }.null ensure connection.drop_table :more_testings rescue nil end @@ -98,8 +98,8 @@ module ActiveRecord ActiveRecord::Migrator.new(:up, [migration]).migrate - assert connection.columns(:testings).find { |c| c.name == 'created_at' }.null - assert connection.columns(:testings).find { |c| c.name == 'updated_at' }.null + assert connection.columns(:testings).find { |c| c.name == "created_at" }.null + assert connection.columns(:testings).find { |c| c.name == "updated_at" }.null end def test_legacy_migrations_get_deprecation_warning_when_run diff --git a/activerecord/test/cases/migration/create_join_table_test.rb b/activerecord/test/cases/migration/create_join_table_test.rb index 920c472c73..f14d68f12b 100644 --- a/activerecord/test/cases/migration/create_join_table_test.rb +++ b/activerecord/test/cases/migration/create_join_table_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class Migration @@ -31,13 +31,13 @@ module ActiveRecord end def test_create_join_table_with_strings - connection.create_join_table 'artists', 'musics' + connection.create_join_table "artists", "musics" assert_equal %w(artist_id music_id), connection.columns(:artists_musics).map(&:name).sort end def test_create_join_table_with_symbol_and_string - connection.create_join_table :artists, 'musics' + connection.create_join_table :artists, "musics" assert_equal %w(artist_id music_id), connection.columns(:artists_musics).map(&:name).sort end @@ -55,13 +55,13 @@ module ActiveRecord end def test_create_join_table_with_the_table_name_as_string - connection.create_join_table :artists, :musics, table_name: 'catalog' + connection.create_join_table :artists, :musics, table_name: "catalog" assert_equal %w(artist_id music_id), connection.columns(:catalog).map(&:name).sort end def test_create_join_table_with_column_options - connection.create_join_table :artists, :musics, column_options: {null: true} + connection.create_join_table :artists, :musics, column_options: { null: true } assert_equal [true, true], connection.columns(:artists_musics).map(&:null) end @@ -84,51 +84,51 @@ module ActiveRecord connection.create_join_table :artists, :musics connection.drop_join_table :artists, :musics - ActiveSupport::Deprecation.silence { assert !connection.table_exists?('artists_musics') } + ActiveSupport::Deprecation.silence { assert !connection.table_exists?("artists_musics") } end def test_drop_join_table_with_strings connection.create_join_table :artists, :musics - connection.drop_join_table 'artists', 'musics' + connection.drop_join_table "artists", "musics" - ActiveSupport::Deprecation.silence { assert !connection.table_exists?('artists_musics') } + ActiveSupport::Deprecation.silence { assert !connection.table_exists?("artists_musics") } end def test_drop_join_table_with_the_proper_order connection.create_join_table :videos, :musics connection.drop_join_table :videos, :musics - ActiveSupport::Deprecation.silence { assert !connection.table_exists?('musics_videos') } + ActiveSupport::Deprecation.silence { assert !connection.table_exists?("musics_videos") } end def test_drop_join_table_with_the_table_name connection.create_join_table :artists, :musics, table_name: :catalog connection.drop_join_table :artists, :musics, table_name: :catalog - ActiveSupport::Deprecation.silence { assert !connection.table_exists?('catalog') } + ActiveSupport::Deprecation.silence { assert !connection.table_exists?("catalog") } end def test_drop_join_table_with_the_table_name_as_string - connection.create_join_table :artists, :musics, table_name: 'catalog' - connection.drop_join_table :artists, :musics, table_name: 'catalog' + connection.create_join_table :artists, :musics, table_name: "catalog" + connection.drop_join_table :artists, :musics, table_name: "catalog" - ActiveSupport::Deprecation.silence { assert !connection.table_exists?('catalog') } + ActiveSupport::Deprecation.silence { assert !connection.table_exists?("catalog") } end def test_drop_join_table_with_column_options - connection.create_join_table :artists, :musics, column_options: {null: true} - connection.drop_join_table :artists, :musics, column_options: {null: true} + connection.create_join_table :artists, :musics, column_options: { null: true } + connection.drop_join_table :artists, :musics, column_options: { null: true } - ActiveSupport::Deprecation.silence { assert !connection.table_exists?('artists_musics') } + ActiveSupport::Deprecation.silence { assert !connection.table_exists?("artists_musics") } end def test_create_and_drop_join_table_with_common_prefix with_table_cleanup do - connection.create_join_table 'audio_artists', 'audio_musics' - ActiveSupport::Deprecation.silence { assert connection.table_exists?('audio_artists_musics') } + connection.create_join_table "audio_artists", "audio_musics" + ActiveSupport::Deprecation.silence { assert connection.table_exists?("audio_artists_musics") } - connection.drop_join_table 'audio_artists', 'audio_musics' - ActiveSupport::Deprecation.silence { assert !connection.table_exists?('audio_artists_musics'), "Should have dropped join table, but didn't" } + connection.drop_join_table "audio_artists", "audio_musics" + ActiveSupport::Deprecation.silence { assert !connection.table_exists?("audio_artists_musics"), "Should have dropped join table, but didn't" } end end diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb index 01162dcefe..cab2069754 100644 --- a/activerecord/test/cases/migration/foreign_key_test.rb +++ b/activerecord/test/cases/migration/foreign_key_test.rb @@ -1,304 +1,316 @@ -require 'cases/helper' -require 'support/ddl_helper' -require 'support/schema_dumping_helper' +require "cases/helper" +require "support/ddl_helper" +require "support/schema_dumping_helper" if ActiveRecord::Base.connection.supports_foreign_keys? -module ActiveRecord - class Migration - class ForeignKeyTest < ActiveRecord::TestCase - include DdlHelper - include SchemaDumpingHelper - include ActiveSupport::Testing::Stream - - class Rocket < ActiveRecord::Base - end - - class Astronaut < ActiveRecord::Base - end - - setup do - @connection = ActiveRecord::Base.connection - @connection.create_table "rockets", force: true do |t| - t.string :name + module ActiveRecord + class Migration + class ForeignKeyTest < ActiveRecord::TestCase + include DdlHelper + include SchemaDumpingHelper + include ActiveSupport::Testing::Stream + + class Rocket < ActiveRecord::Base end - @connection.create_table "astronauts", force: true do |t| - t.string :name - t.references :rocket + class Astronaut < ActiveRecord::Base end - end - teardown do - if defined?(@connection) - @connection.drop_table "astronauts", if_exists: true - @connection.drop_table "rockets", if_exists: true - end - end - - def test_foreign_keys - foreign_keys = @connection.foreign_keys("fk_test_has_fk") - assert_equal 1, foreign_keys.size + setup do + @connection = ActiveRecord::Base.connection + @connection.create_table "rockets", force: true do |t| + t.string :name + end - fk = foreign_keys.first - assert_equal "fk_test_has_fk", fk.from_table - assert_equal "fk_test_has_pk", fk.to_table - assert_equal "fk_id", fk.column - assert_equal "pk_id", fk.primary_key - assert_equal "fk_name", fk.name - end + @connection.create_table "astronauts", force: true do |t| + t.string :name + t.references :rocket + end + end - def test_add_foreign_key_inferes_column - @connection.add_foreign_key :astronauts, :rockets + teardown do + if defined?(@connection) + @connection.drop_table "astronauts", if_exists: true + @connection.drop_table "rockets", if_exists: true + end + end - foreign_keys = @connection.foreign_keys("astronauts") - assert_equal 1, foreign_keys.size + def test_foreign_keys + foreign_keys = @connection.foreign_keys("fk_test_has_fk") + assert_equal 1, foreign_keys.size - fk = foreign_keys.first - assert_equal "astronauts", fk.from_table - assert_equal "rockets", fk.to_table - assert_equal "rocket_id", fk.column - assert_equal "id", fk.primary_key - assert_equal("fk_rails_78146ddd2e", fk.name) - end + fk = foreign_keys.first + assert_equal "fk_test_has_fk", fk.from_table + assert_equal "fk_test_has_pk", fk.to_table + assert_equal "fk_id", fk.column + assert_equal "pk_id", fk.primary_key + assert_equal "fk_name", fk.name + end - def test_add_foreign_key_with_column - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id" + def test_add_foreign_key_inferes_column + @connection.add_foreign_key :astronauts, :rockets - foreign_keys = @connection.foreign_keys("astronauts") - assert_equal 1, foreign_keys.size + foreign_keys = @connection.foreign_keys("astronauts") + assert_equal 1, foreign_keys.size - fk = foreign_keys.first - assert_equal "astronauts", fk.from_table - assert_equal "rockets", fk.to_table - assert_equal "rocket_id", fk.column - assert_equal "id", fk.primary_key - assert_equal("fk_rails_78146ddd2e", fk.name) - end + fk = foreign_keys.first + assert_equal "astronauts", fk.from_table + assert_equal "rockets", fk.to_table + assert_equal "rocket_id", fk.column + assert_equal "id", fk.primary_key + assert_equal("fk_rails_78146ddd2e", fk.name) + end - def test_add_foreign_key_with_non_standard_primary_key - with_example_table @connection, "space_shuttles", "pk integer PRIMARY KEY" do - @connection.add_foreign_key(:astronauts, :space_shuttles, - column: "rocket_id", primary_key: "pk", name: "custom_pk") + def test_add_foreign_key_with_column + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id" foreign_keys = @connection.foreign_keys("astronauts") assert_equal 1, foreign_keys.size fk = foreign_keys.first assert_equal "astronauts", fk.from_table - assert_equal "space_shuttles", fk.to_table - assert_equal "pk", fk.primary_key - - @connection.remove_foreign_key :astronauts, name: "custom_pk" + assert_equal "rockets", fk.to_table + assert_equal "rocket_id", fk.column + assert_equal "id", fk.primary_key + assert_equal("fk_rails_78146ddd2e", fk.name) end - end - def test_add_on_delete_restrict_foreign_key - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :restrict + def test_add_foreign_key_with_non_standard_primary_key + with_example_table @connection, "space_shuttles", "pk integer PRIMARY KEY" do + @connection.add_foreign_key(:astronauts, :space_shuttles, + column: "rocket_id", primary_key: "pk", name: "custom_pk") + + foreign_keys = @connection.foreign_keys("astronauts") + assert_equal 1, foreign_keys.size - foreign_keys = @connection.foreign_keys("astronauts") - assert_equal 1, foreign_keys.size + fk = foreign_keys.first + assert_equal "astronauts", fk.from_table + assert_equal "space_shuttles", fk.to_table + assert_equal "pk", fk.primary_key - fk = foreign_keys.first - if current_adapter?(:Mysql2Adapter) - # ON DELETE RESTRICT is the default on MySQL - assert_equal nil, fk.on_delete - else - assert_equal :restrict, fk.on_delete + @connection.remove_foreign_key :astronauts, name: "custom_pk" + end end - end - def test_add_on_delete_cascade_foreign_key - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :cascade + def test_add_on_delete_restrict_foreign_key + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :restrict + + foreign_keys = @connection.foreign_keys("astronauts") + assert_equal 1, foreign_keys.size + + fk = foreign_keys.first + if current_adapter?(:Mysql2Adapter) + # ON DELETE RESTRICT is the default on MySQL + assert_equal nil, fk.on_delete + else + assert_equal :restrict, fk.on_delete + end + end - foreign_keys = @connection.foreign_keys("astronauts") - assert_equal 1, foreign_keys.size + def test_add_on_delete_cascade_foreign_key + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :cascade - fk = foreign_keys.first - assert_equal :cascade, fk.on_delete - end + foreign_keys = @connection.foreign_keys("astronauts") + assert_equal 1, foreign_keys.size - def test_add_on_delete_nullify_foreign_key - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify + fk = foreign_keys.first + assert_equal :cascade, fk.on_delete + end - foreign_keys = @connection.foreign_keys("astronauts") - assert_equal 1, foreign_keys.size + def test_add_on_delete_nullify_foreign_key + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify - fk = foreign_keys.first - assert_equal :nullify, fk.on_delete - end + foreign_keys = @connection.foreign_keys("astronauts") + assert_equal 1, foreign_keys.size - def test_on_update_and_on_delete_raises_with_invalid_values - assert_raises ArgumentError do - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :invalid + fk = foreign_keys.first + assert_equal :nullify, fk.on_delete end - assert_raises ArgumentError do - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_update: :invalid + def test_on_update_and_on_delete_raises_with_invalid_values + assert_raises ArgumentError do + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :invalid + end + + assert_raises ArgumentError do + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_update: :invalid + end end - end - def test_add_foreign_key_with_on_update - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_update: :nullify + def test_add_foreign_key_with_on_update + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_update: :nullify - foreign_keys = @connection.foreign_keys("astronauts") - assert_equal 1, foreign_keys.size + foreign_keys = @connection.foreign_keys("astronauts") + assert_equal 1, foreign_keys.size - fk = foreign_keys.first - assert_equal :nullify, fk.on_update - end + fk = foreign_keys.first + assert_equal :nullify, fk.on_update + end - def test_foreign_key_exists - @connection.add_foreign_key :astronauts, :rockets + def test_foreign_key_exists + @connection.add_foreign_key :astronauts, :rockets - assert @connection.foreign_key_exists?(:astronauts, :rockets) - assert_not @connection.foreign_key_exists?(:astronauts, :stars) - end + assert @connection.foreign_key_exists?(:astronauts, :rockets) + assert_not @connection.foreign_key_exists?(:astronauts, :stars) + end - def test_foreign_key_exists_by_column - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id" + def test_foreign_key_exists_by_column + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id" - assert @connection.foreign_key_exists?(:astronauts, column: "rocket_id") - assert_not @connection.foreign_key_exists?(:astronauts, column: "star_id") - end + assert @connection.foreign_key_exists?(:astronauts, column: "rocket_id") + assert_not @connection.foreign_key_exists?(:astronauts, column: "star_id") + end - def test_foreign_key_exists_by_name - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk" + def test_foreign_key_exists_by_name + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk" - assert @connection.foreign_key_exists?(:astronauts, name: "fancy_named_fk") - assert_not @connection.foreign_key_exists?(:astronauts, name: "other_fancy_named_fk") - end + assert @connection.foreign_key_exists?(:astronauts, name: "fancy_named_fk") + assert_not @connection.foreign_key_exists?(:astronauts, name: "other_fancy_named_fk") + end - def test_remove_foreign_key_inferes_column - @connection.add_foreign_key :astronauts, :rockets + def test_remove_foreign_key_inferes_column + @connection.add_foreign_key :astronauts, :rockets - assert_equal 1, @connection.foreign_keys("astronauts").size - @connection.remove_foreign_key :astronauts, :rockets - assert_equal [], @connection.foreign_keys("astronauts") - end + assert_equal 1, @connection.foreign_keys("astronauts").size + @connection.remove_foreign_key :astronauts, :rockets + assert_equal [], @connection.foreign_keys("astronauts") + end - def test_remove_foreign_key_by_column - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id" + def test_remove_foreign_key_by_column + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id" - assert_equal 1, @connection.foreign_keys("astronauts").size - @connection.remove_foreign_key :astronauts, column: "rocket_id" - assert_equal [], @connection.foreign_keys("astronauts") - end + assert_equal 1, @connection.foreign_keys("astronauts").size + @connection.remove_foreign_key :astronauts, column: "rocket_id" + assert_equal [], @connection.foreign_keys("astronauts") + end - def test_remove_foreign_key_by_symbol_column - @connection.add_foreign_key :astronauts, :rockets, column: :rocket_id + def test_remove_foreign_key_by_symbol_column + @connection.add_foreign_key :astronauts, :rockets, column: :rocket_id - assert_equal 1, @connection.foreign_keys("astronauts").size - @connection.remove_foreign_key :astronauts, column: :rocket_id - assert_equal [], @connection.foreign_keys("astronauts") - end + assert_equal 1, @connection.foreign_keys("astronauts").size + @connection.remove_foreign_key :astronauts, column: :rocket_id + assert_equal [], @connection.foreign_keys("astronauts") + end - def test_remove_foreign_key_by_name - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk" + def test_remove_foreign_key_by_name + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk" - assert_equal 1, @connection.foreign_keys("astronauts").size - @connection.remove_foreign_key :astronauts, name: "fancy_named_fk" - assert_equal [], @connection.foreign_keys("astronauts") - end + assert_equal 1, @connection.foreign_keys("astronauts").size + @connection.remove_foreign_key :astronauts, name: "fancy_named_fk" + assert_equal [], @connection.foreign_keys("astronauts") + end - def test_remove_foreign_non_existing_foreign_key_raises - assert_raises ArgumentError do - @connection.remove_foreign_key :astronauts, :rockets + def test_remove_foreign_non_existing_foreign_key_raises + assert_raises ArgumentError do + @connection.remove_foreign_key :astronauts, :rockets + end end - end - def test_schema_dumping - @connection.add_foreign_key :astronauts, :rockets - output = dump_table_schema "astronauts" - assert_match %r{\s+add_foreign_key "astronauts", "rockets"$}, output - end + def test_schema_dumping + @connection.add_foreign_key :astronauts, :rockets + output = dump_table_schema "astronauts" + assert_match %r{\s+add_foreign_key "astronauts", "rockets"$}, output + end - def test_schema_dumping_with_options - output = dump_table_schema "fk_test_has_fk" - assert_match %r{\s+add_foreign_key "fk_test_has_fk", "fk_test_has_pk", column: "fk_id", primary_key: "pk_id", name: "fk_name"$}, output - end + def test_schema_dumping_with_options + output = dump_table_schema "fk_test_has_fk" + assert_match %r{\s+add_foreign_key "fk_test_has_fk", "fk_test_has_pk", column: "fk_id", primary_key: "pk_id", name: "fk_name"$}, output + end - def test_schema_dumping_on_delete_and_on_update_options - @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify, on_update: :cascade + def test_schema_dumping_on_delete_and_on_update_options + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify, on_update: :cascade - output = dump_table_schema "astronauts" - assert_match %r{\s+add_foreign_key "astronauts",.+on_update: :cascade,.+on_delete: :nullify$}, output - end + output = dump_table_schema "astronauts" + assert_match %r{\s+add_foreign_key "astronauts",.+on_update: :cascade,.+on_delete: :nullify$}, output + end + + class CreateCitiesAndHousesMigration < ActiveRecord::Migration::Current + def change + create_table("cities") { |t| } - class CreateCitiesAndHousesMigration < ActiveRecord::Migration::Current - def change - create_table("cities") { |t| } + create_table("houses") do |t| + t.column :city_id, :integer + end + add_foreign_key :houses, :cities, column: "city_id" - create_table("houses") do |t| - t.column :city_id, :integer + # remove and re-add to test that schema is updated and not accidentally cached + remove_foreign_key :houses, :cities + add_foreign_key :houses, :cities, column: "city_id", on_delete: :cascade end - add_foreign_key :houses, :cities, column: "city_id" end - end - def test_add_foreign_key_is_reversible - migration = CreateCitiesAndHousesMigration.new - silence_stream($stdout) { migration.migrate(:up) } - assert_equal 1, @connection.foreign_keys("houses").size - ensure - silence_stream($stdout) { migration.migrate(:down) } - end + def test_add_foreign_key_is_reversible + migration = CreateCitiesAndHousesMigration.new + silence_stream($stdout) { migration.migrate(:up) } + assert_equal 1, @connection.foreign_keys("houses").size + ensure + silence_stream($stdout) { migration.migrate(:down) } + end + + def test_foreign_key_constraint_is_not_cached_incorrectly + migration = CreateCitiesAndHousesMigration.new + silence_stream($stdout) { migration.migrate(:up) } + output = dump_table_schema "houses" + assert_match %r{\s+add_foreign_key "houses",.+on_delete: :cascade$}, output + ensure + silence_stream($stdout) { migration.migrate(:down) } + end - class CreateSchoolsAndClassesMigration < ActiveRecord::Migration::Current - def change - create_table(:schools) + class CreateSchoolsAndClassesMigration < ActiveRecord::Migration::Current + def change + create_table(:schools) - create_table(:classes) do |t| - t.column :school_id, :integer + create_table(:classes) do |t| + t.column :school_id, :integer + end + add_foreign_key :classes, :schools end - add_foreign_key :classes, :schools end - end - def test_add_foreign_key_with_prefix - ActiveRecord::Base.table_name_prefix = 'p_' - migration = CreateSchoolsAndClassesMigration.new - silence_stream($stdout) { migration.migrate(:up) } - assert_equal 1, @connection.foreign_keys("p_classes").size - ensure - silence_stream($stdout) { migration.migrate(:down) } - ActiveRecord::Base.table_name_prefix = nil - end + def test_add_foreign_key_with_prefix + ActiveRecord::Base.table_name_prefix = "p_" + migration = CreateSchoolsAndClassesMigration.new + silence_stream($stdout) { migration.migrate(:up) } + assert_equal 1, @connection.foreign_keys("p_classes").size + ensure + silence_stream($stdout) { migration.migrate(:down) } + ActiveRecord::Base.table_name_prefix = nil + end - def test_add_foreign_key_with_suffix - ActiveRecord::Base.table_name_suffix = '_s' - migration = CreateSchoolsAndClassesMigration.new - silence_stream($stdout) { migration.migrate(:up) } - assert_equal 1, @connection.foreign_keys("classes_s").size - ensure - silence_stream($stdout) { migration.migrate(:down) } - ActiveRecord::Base.table_name_suffix = nil + def test_add_foreign_key_with_suffix + ActiveRecord::Base.table_name_suffix = "_s" + migration = CreateSchoolsAndClassesMigration.new + silence_stream($stdout) { migration.migrate(:up) } + assert_equal 1, @connection.foreign_keys("classes_s").size + ensure + silence_stream($stdout) { migration.migrate(:down) } + ActiveRecord::Base.table_name_suffix = nil + end end - end end -end else -module ActiveRecord - class Migration - class NoForeignKeySupportTest < ActiveRecord::TestCase - setup do - @connection = ActiveRecord::Base.connection - end + module ActiveRecord + class Migration + class NoForeignKeySupportTest < ActiveRecord::TestCase + setup do + @connection = ActiveRecord::Base.connection + end - def test_add_foreign_key_should_be_noop - @connection.add_foreign_key :clubs, :categories - end + def test_add_foreign_key_should_be_noop + @connection.add_foreign_key :clubs, :categories + end - def test_remove_foreign_key_should_be_noop - @connection.remove_foreign_key :clubs, :categories - end + def test_remove_foreign_key_should_be_noop + @connection.remove_foreign_key :clubs, :categories + end - def test_foreign_keys_should_raise_not_implemented - assert_raises NotImplementedError do - @connection.foreign_keys("clubs") + def test_foreign_keys_should_raise_not_implemented + assert_raises NotImplementedError do + @connection.foreign_keys("clubs") + end end end end end end -end diff --git a/activerecord/test/cases/migration/helper.rb b/activerecord/test/cases/migration/helper.rb index ad85684c0b..9c0fa7339d 100644 --- a/activerecord/test/cases/migration/helper.rb +++ b/activerecord/test/cases/migration/helper.rb @@ -33,7 +33,7 @@ module ActiveRecord private - delegate(*CONNECTION_METHODS, to: :connection) + delegate(*CONNECTION_METHODS, to: :connection) end end end diff --git a/activerecord/test/cases/migration/index_test.rb b/activerecord/test/cases/migration/index_test.rb index 5abd37bfa2..0f975026b8 100644 --- a/activerecord/test/cases/migration/index_test.rb +++ b/activerecord/test/cases/migration/index_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class Migration @@ -11,12 +11,12 @@ module ActiveRecord @table_name = :testings connection.create_table table_name do |t| - t.column :foo, :string, :limit => 100 - t.column :bar, :string, :limit => 100 + t.column :foo, :string, limit: 100 + t.column :bar, :string, limit: 100 t.string :first_name - t.string :last_name, :limit => 100 - t.string :key, :limit => 100 + t.string :last_name, limit: 100 + t.string :key, limit: 100 t.boolean :administrator end end @@ -28,32 +28,31 @@ module ActiveRecord def test_rename_index # keep the names short to make Oracle and similar behave - connection.add_index(table_name, [:foo], :name => 'old_idx') - connection.rename_index(table_name, 'old_idx', 'new_idx') + connection.add_index(table_name, [:foo], name: "old_idx") + connection.rename_index(table_name, "old_idx", "new_idx") # if the adapter doesn't support the indexes call, pick defaults that let the test pass - assert_not connection.index_name_exists?(table_name, 'old_idx', false) - assert connection.index_name_exists?(table_name, 'new_idx', true) + assert_not connection.index_name_exists?(table_name, "old_idx", false) + assert connection.index_name_exists?(table_name, "new_idx", true) end def test_rename_index_too_long - too_long_index_name = good_index_name + 'x' + too_long_index_name = good_index_name + "x" # keep the names short to make Oracle and similar behave - connection.add_index(table_name, [:foo], :name => 'old_idx') + connection.add_index(table_name, [:foo], name: "old_idx") e = assert_raises(ArgumentError) { - connection.rename_index(table_name, 'old_idx', too_long_index_name) + connection.rename_index(table_name, "old_idx", too_long_index_name) } assert_match(/too long; the limit is #{connection.allowed_index_name_length} characters/, e.message) # if the adapter doesn't support the indexes call, pick defaults that let the test pass - assert connection.index_name_exists?(table_name, 'old_idx', false) + assert connection.index_name_exists?(table_name, "old_idx", false) end - def test_double_add_index - connection.add_index(table_name, [:foo], :name => 'some_idx') + connection.add_index(table_name, [:foo], name: "some_idx") assert_raises(ArgumentError) { - connection.add_index(table_name, [:foo], :name => 'some_idx') + connection.add_index(table_name, [:foo], name: "some_idx") } end @@ -69,7 +68,7 @@ module ActiveRecord end def test_add_index_does_not_accept_too_long_index_names - too_long_index_name = good_index_name + 'x' + too_long_index_name = good_index_name + "x" e = assert_raises(ArgumentError) { connection.add_index(table_name, "foo", name: too_long_index_name) @@ -77,11 +76,11 @@ module ActiveRecord assert_match(/too long; the limit is #{connection.allowed_index_name_length} characters/, e.message) assert_not connection.index_name_exists?(table_name, too_long_index_name, false) - connection.add_index(table_name, "foo", :name => good_index_name) + connection.add_index(table_name, "foo", name: good_index_name) end def test_internal_index_with_name_matching_database_limit - good_index_name = 'x' * connection.index_name_length + good_index_name = "x" * connection.index_name_length connection.add_index(table_name, "foo", name: good_index_name, internal: true) assert connection.index_name_exists?(table_name, good_index_name, false) @@ -89,11 +88,11 @@ module ActiveRecord end def test_index_symbol_names - connection.add_index table_name, :foo, :name => :symbol_index_name - assert connection.index_exists?(table_name, :foo, :name => :symbol_index_name) + connection.add_index table_name, :foo, name: :symbol_index_name + assert connection.index_exists?(table_name, :foo, name: :symbol_index_name) - connection.remove_index table_name, :name => :symbol_index_name - assert_not connection.index_exists?(table_name, :foo, :name => :symbol_index_name) + connection.remove_index table_name, name: :symbol_index_name + assert_not connection.index_exists?(table_name, :foo, name: :symbol_index_name) end def test_index_exists @@ -122,21 +121,21 @@ module ActiveRecord end def test_unique_index_exists - connection.add_index :testings, :foo, :unique => true + connection.add_index :testings, :foo, unique: true - assert connection.index_exists?(:testings, :foo, :unique => true) + assert connection.index_exists?(:testings, :foo, unique: true) end def test_named_index_exists - connection.add_index :testings, :foo, :name => "custom_index_name" + connection.add_index :testings, :foo, name: "custom_index_name" assert connection.index_exists?(:testings, :foo) - assert connection.index_exists?(:testings, :foo, :name => "custom_index_name") - assert !connection.index_exists?(:testings, :foo, :name => "other_index_name") + assert connection.index_exists?(:testings, :foo, name: "custom_index_name") + assert !connection.index_exists?(:testings, :foo, name: "other_index_name") end def test_remove_named_index - connection.add_index :testings, :foo, :name => "custom_index_name" + connection.add_index :testings, :foo, name: "custom_index_name" assert connection.index_exists?(:testings, :foo) connection.remove_index :testings, :foo @@ -144,7 +143,7 @@ module ActiveRecord end def test_add_index_attribute_length_limit - connection.add_index :testings, [:foo, :bar], :length => {:foo => 10, :bar => nil} + connection.add_index :testings, [:foo, :bar], length: { foo: 10, bar: nil } assert connection.index_exists?(:testings, [:foo, :bar]) end @@ -154,53 +153,53 @@ module ActiveRecord connection.remove_index("testings", "last_name") connection.add_index("testings", ["last_name", "first_name"]) - connection.remove_index("testings", :column => ["last_name", "first_name"]) + connection.remove_index("testings", column: ["last_name", "first_name"]) # Oracle adapter cannot have specified index name larger than 30 characters # Oracle adapter is shortening index name when just column list is given unless current_adapter?(:OracleAdapter) connection.add_index("testings", ["last_name", "first_name"]) - connection.remove_index("testings", :name => :index_testings_on_last_name_and_first_name) + connection.remove_index("testings", name: :index_testings_on_last_name_and_first_name) connection.add_index("testings", ["last_name", "first_name"]) connection.remove_index("testings", "last_name_and_first_name") end connection.add_index("testings", ["last_name", "first_name"]) connection.remove_index("testings", ["last_name", "first_name"]) - connection.add_index("testings", ["last_name"], :length => 10) + connection.add_index("testings", ["last_name"], length: 10) connection.remove_index("testings", "last_name") - connection.add_index("testings", ["last_name"], :length => {:last_name => 10}) + connection.add_index("testings", ["last_name"], length: { last_name: 10 }) connection.remove_index("testings", ["last_name"]) - connection.add_index("testings", ["last_name", "first_name"], :length => 10) + connection.add_index("testings", ["last_name", "first_name"], length: 10) connection.remove_index("testings", ["last_name", "first_name"]) - connection.add_index("testings", ["last_name", "first_name"], :length => {:last_name => 10, :first_name => 20}) + connection.add_index("testings", ["last_name", "first_name"], length: { last_name: 10, first_name: 20 }) connection.remove_index("testings", ["last_name", "first_name"]) - connection.add_index("testings", ["key"], :name => "key_idx", :unique => true) - connection.remove_index("testings", :name => "key_idx", :unique => true) + connection.add_index("testings", ["key"], name: "key_idx", unique: true) + connection.remove_index("testings", name: "key_idx", unique: true) - connection.add_index("testings", %w(last_name first_name administrator), :name => "named_admin") - connection.remove_index("testings", :name => "named_admin") + connection.add_index("testings", %w(last_name first_name administrator), name: "named_admin") + connection.remove_index("testings", name: "named_admin") # Selected adapters support index sort order if current_adapter?(:SQLite3Adapter, :Mysql2Adapter, :PostgreSQLAdapter) - connection.add_index("testings", ["last_name"], :order => {:last_name => :desc}) + connection.add_index("testings", ["last_name"], order: { last_name: :desc }) connection.remove_index("testings", ["last_name"]) - connection.add_index("testings", ["last_name", "first_name"], :order => {:last_name => :desc}) + connection.add_index("testings", ["last_name", "first_name"], order: { last_name: :desc }) connection.remove_index("testings", ["last_name", "first_name"]) - connection.add_index("testings", ["last_name", "first_name"], :order => {:last_name => :desc, :first_name => :asc}) + connection.add_index("testings", ["last_name", "first_name"], order: { last_name: :desc, first_name: :asc }) connection.remove_index("testings", ["last_name", "first_name"]) - connection.add_index("testings", ["last_name", "first_name"], :order => :desc) + connection.add_index("testings", ["last_name", "first_name"], order: :desc) connection.remove_index("testings", ["last_name", "first_name"]) end end if current_adapter?(:PostgreSQLAdapter) def test_add_partial_index - connection.add_index("testings", "last_name", :where => "first_name = 'john doe'") + connection.add_index("testings", "last_name", where: "first_name = 'john doe'") assert connection.index_exists?("testings", "last_name") connection.remove_index("testings", "last_name") @@ -210,9 +209,8 @@ module ActiveRecord private def good_index_name - 'x' * connection.allowed_index_name_length + "x" * connection.allowed_index_name_length end - end end end diff --git a/activerecord/test/cases/migration/logger_test.rb b/activerecord/test/cases/migration/logger_test.rb index bf6e684887..3d7c7ad469 100644 --- a/activerecord/test/cases/migration/logger_test.rb +++ b/activerecord/test/cases/migration/logger_test.rb @@ -8,7 +8,7 @@ module ActiveRecord Migration = Struct.new(:name, :version) do def disable_ddl_transaction; false end - def migrate direction + def migrate(direction) # do nothing end end @@ -26,7 +26,7 @@ module ActiveRecord def test_migration_should_be_run_without_logger previous_logger = ActiveRecord::Base.logger ActiveRecord::Base.logger = nil - migrations = [Migration.new('a', 1), Migration.new('b', 2), Migration.new('c', 3)] + migrations = [Migration.new("a", 1), Migration.new("b", 2), Migration.new("c", 3)] ActiveRecord::Migrator.new(:up, migrations).migrate ensure ActiveRecord::Base.logger = previous_logger diff --git a/activerecord/test/cases/migration/pending_migrations_test.rb b/activerecord/test/cases/migration/pending_migrations_test.rb index 4f5589f32a..61f5a061b0 100644 --- a/activerecord/test/cases/migration/pending_migrations_test.rb +++ b/activerecord/test/cases/migration/pending_migrations_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class Migration diff --git a/activerecord/test/cases/migration/references_foreign_key_test.rb b/activerecord/test/cases/migration/references_foreign_key_test.rb index 9e19eb9f73..528811db49 100644 --- a/activerecord/test/cases/migration/references_foreign_key_test.rb +++ b/activerecord/test/cases/migration/references_foreign_key_test.rb @@ -1,216 +1,216 @@ -require 'cases/helper' +require "cases/helper" if ActiveRecord::Base.connection.supports_foreign_keys? -module ActiveRecord - class Migration - class ReferencesForeignKeyTest < ActiveRecord::TestCase - setup do - @connection = ActiveRecord::Base.connection - @connection.create_table(:testing_parents, force: true) - end - - teardown do - @connection.drop_table "testings", if_exists: true - @connection.drop_table "testing_parents", if_exists: true - end + module ActiveRecord + class Migration + class ReferencesForeignKeyTest < ActiveRecord::TestCase + setup do + @connection = ActiveRecord::Base.connection + @connection.create_table(:testing_parents, force: true) + end - test "foreign keys can be created with the table" do - @connection.create_table :testings do |t| - t.references :testing_parent, foreign_key: true + teardown do + @connection.drop_table "testings", if_exists: true + @connection.drop_table "testing_parents", if_exists: true end - fk = @connection.foreign_keys("testings").first - assert_equal "testings", fk.from_table - assert_equal "testing_parents", fk.to_table - end + test "foreign keys can be created with the table" do + @connection.create_table :testings do |t| + t.references :testing_parent, foreign_key: true + end - test "no foreign key is created by default" do - @connection.create_table :testings do |t| - t.references :testing_parent + fk = @connection.foreign_keys("testings").first + assert_equal "testings", fk.from_table + assert_equal "testing_parents", fk.to_table end - assert_equal [], @connection.foreign_keys("testings") - end - - test "foreign keys can be created in one query when index is not added" do - assert_queries(1) do + test "no foreign key is created by default" do @connection.create_table :testings do |t| - t.references :testing_parent, foreign_key: true, index: false + t.references :testing_parent end - end - end - test "options hash can be passed" do - @connection.change_table :testing_parents do |t| - t.integer :other_id - t.index :other_id, unique: true + assert_equal [], @connection.foreign_keys("testings") end - @connection.create_table :testings do |t| - t.references :testing_parent, foreign_key: { primary_key: :other_id } + + test "foreign keys can be created in one query when index is not added" do + assert_queries(1) do + @connection.create_table :testings do |t| + t.references :testing_parent, foreign_key: true, index: false + end + end end - fk = @connection.foreign_keys("testings").find { |k| k.to_table == "testing_parents" } - assert_equal "other_id", fk.primary_key - end + test "options hash can be passed" do + @connection.change_table :testing_parents do |t| + t.integer :other_id + t.index :other_id, unique: true + end + @connection.create_table :testings do |t| + t.references :testing_parent, foreign_key: { primary_key: :other_id } + end - test "to_table option can be passed" do - @connection.create_table :testings do |t| - t.references :parent, foreign_key: { to_table: :testing_parents } + fk = @connection.foreign_keys("testings").find { |k| k.to_table == "testing_parents" } + assert_equal "other_id", fk.primary_key end - fks = @connection.foreign_keys("testings") - assert_equal([["testings", "testing_parents", "parent_id"]], - fks.map {|fk| [fk.from_table, fk.to_table, fk.column] }) - end - test "foreign keys cannot be added to polymorphic relations when creating the table" do - @connection.create_table :testings do |t| - assert_raises(ArgumentError) do - t.references :testing_parent, polymorphic: true, foreign_key: true + test "to_table option can be passed" do + @connection.create_table :testings do |t| + t.references :parent, foreign_key: { to_table: :testing_parents } end + fks = @connection.foreign_keys("testings") + assert_equal([["testings", "testing_parents", "parent_id"]], + fks.map { |fk| [fk.from_table, fk.to_table, fk.column] }) end - end - test "foreign keys can be created while changing the table" do - @connection.create_table :testings - @connection.change_table :testings do |t| - t.references :testing_parent, foreign_key: true + test "foreign keys cannot be added to polymorphic relations when creating the table" do + @connection.create_table :testings do |t| + assert_raises(ArgumentError) do + t.references :testing_parent, polymorphic: true, foreign_key: true + end + end end - fk = @connection.foreign_keys("testings").first - assert_equal "testings", fk.from_table - assert_equal "testing_parents", fk.to_table - end + test "foreign keys can be created while changing the table" do + @connection.create_table :testings + @connection.change_table :testings do |t| + t.references :testing_parent, foreign_key: true + end - test "foreign keys are not added by default when changing the table" do - @connection.create_table :testings - @connection.change_table :testings do |t| - t.references :testing_parent + fk = @connection.foreign_keys("testings").first + assert_equal "testings", fk.from_table + assert_equal "testing_parents", fk.to_table end - assert_equal [], @connection.foreign_keys("testings") - end + test "foreign keys are not added by default when changing the table" do + @connection.create_table :testings + @connection.change_table :testings do |t| + t.references :testing_parent + end - test "foreign keys accept options when changing the table" do - @connection.change_table :testing_parents do |t| - t.integer :other_id - t.index :other_id, unique: true - end - @connection.create_table :testings - @connection.change_table :testings do |t| - t.references :testing_parent, foreign_key: { primary_key: :other_id } + assert_equal [], @connection.foreign_keys("testings") end - fk = @connection.foreign_keys("testings").find { |k| k.to_table == "testing_parents" } - assert_equal "other_id", fk.primary_key - end - - test "foreign keys cannot be added to polymorphic relations when changing the table" do - @connection.create_table :testings - @connection.change_table :testings do |t| - assert_raises(ArgumentError) do - t.references :testing_parent, polymorphic: true, foreign_key: true + test "foreign keys accept options when changing the table" do + @connection.change_table :testing_parents do |t| + t.integer :other_id + t.index :other_id, unique: true + end + @connection.create_table :testings + @connection.change_table :testings do |t| + t.references :testing_parent, foreign_key: { primary_key: :other_id } end - end - end - test "foreign key column can be removed" do - @connection.create_table :testings do |t| - t.references :testing_parent, index: true, foreign_key: true + fk = @connection.foreign_keys("testings").find { |k| k.to_table == "testing_parents" } + assert_equal "other_id", fk.primary_key end - assert_difference "@connection.foreign_keys('testings').size", -1 do - @connection.remove_reference :testings, :testing_parent, foreign_key: true + test "foreign keys cannot be added to polymorphic relations when changing the table" do + @connection.create_table :testings + @connection.change_table :testings do |t| + assert_raises(ArgumentError) do + t.references :testing_parent, polymorphic: true, foreign_key: true + end + end end - end - test "foreign key methods respect pluralize_table_names" do - begin - original_pluralize_table_names = ActiveRecord::Base.pluralize_table_names - ActiveRecord::Base.pluralize_table_names = false - @connection.create_table :testing - @connection.change_table :testing_parents do |t| - t.references :testing, foreign_key: true + test "foreign key column can be removed" do + @connection.create_table :testings do |t| + t.references :testing_parent, index: true, foreign_key: true end - fk = @connection.foreign_keys("testing_parents").first - assert_equal "testing_parents", fk.from_table - assert_equal "testing", fk.to_table + assert_difference "@connection.foreign_keys('testings').size", -1 do + @connection.remove_reference :testings, :testing_parent, foreign_key: true + end + end - assert_difference "@connection.foreign_keys('testing_parents').size", -1 do - @connection.remove_reference :testing_parents, :testing, foreign_key: true + test "foreign key methods respect pluralize_table_names" do + begin + original_pluralize_table_names = ActiveRecord::Base.pluralize_table_names + ActiveRecord::Base.pluralize_table_names = false + @connection.create_table :testing + @connection.change_table :testing_parents do |t| + t.references :testing, foreign_key: true + end + + fk = @connection.foreign_keys("testing_parents").first + assert_equal "testing_parents", fk.from_table + assert_equal "testing", fk.to_table + + assert_difference "@connection.foreign_keys('testing_parents').size", -1 do + @connection.remove_reference :testing_parents, :testing, foreign_key: true + end + ensure + ActiveRecord::Base.pluralize_table_names = original_pluralize_table_names + @connection.drop_table "testing", if_exists: true end - ensure - ActiveRecord::Base.pluralize_table_names = original_pluralize_table_names - @connection.drop_table "testing", if_exists: true end - end - class CreateDogsMigration < ActiveRecord::Migration::Current - def change - create_table :dog_owners + class CreateDogsMigration < ActiveRecord::Migration::Current + def change + create_table :dog_owners - create_table :dogs do |t| - t.references :dog_owner, foreign_key: true + create_table :dogs do |t| + t.references :dog_owner, foreign_key: true + end end end - end - def test_references_foreign_key_with_prefix - ActiveRecord::Base.table_name_prefix = 'p_' - migration = CreateDogsMigration.new - silence_stream($stdout) { migration.migrate(:up) } - assert_equal 1, @connection.foreign_keys("p_dogs").size - ensure - silence_stream($stdout) { migration.migrate(:down) } - ActiveRecord::Base.table_name_prefix = nil - end + def test_references_foreign_key_with_prefix + ActiveRecord::Base.table_name_prefix = "p_" + migration = CreateDogsMigration.new + silence_stream($stdout) { migration.migrate(:up) } + assert_equal 1, @connection.foreign_keys("p_dogs").size + ensure + silence_stream($stdout) { migration.migrate(:down) } + ActiveRecord::Base.table_name_prefix = nil + end - def test_references_foreign_key_with_suffix - ActiveRecord::Base.table_name_suffix = '_s' - migration = CreateDogsMigration.new - silence_stream($stdout) { migration.migrate(:up) } - assert_equal 1, @connection.foreign_keys("dogs_s").size - ensure - silence_stream($stdout) { migration.migrate(:down) } - ActiveRecord::Base.table_name_suffix = nil - end + def test_references_foreign_key_with_suffix + ActiveRecord::Base.table_name_suffix = "_s" + migration = CreateDogsMigration.new + silence_stream($stdout) { migration.migrate(:up) } + assert_equal 1, @connection.foreign_keys("dogs_s").size + ensure + silence_stream($stdout) { migration.migrate(:down) } + ActiveRecord::Base.table_name_suffix = nil + end - test "multiple foreign keys can be added to the same table" do - @connection.create_table :testings do |t| - t.integer :col_1 - t.integer :col_2 + test "multiple foreign keys can be added to the same table" do + @connection.create_table :testings do |t| + t.integer :col_1 + t.integer :col_2 - t.foreign_key :testing_parents, column: :col_1 - t.foreign_key :testing_parents, column: :col_2 - end + t.foreign_key :testing_parents, column: :col_1 + t.foreign_key :testing_parents, column: :col_2 + end - fks = @connection.foreign_keys("testings") + fks = @connection.foreign_keys("testings") - fk_definitions = fks.map {|fk| [fk.from_table, fk.to_table, fk.column] } - assert_equal([["testings", "testing_parents", "col_1"], - ["testings", "testing_parents", "col_2"]], fk_definitions) + fk_definitions = fks.map { |fk| [fk.from_table, fk.to_table, fk.column] } + assert_equal([["testings", "testing_parents", "col_1"], + ["testings", "testing_parents", "col_2"]], fk_definitions) + end end end end -end else -class ReferencesWithoutForeignKeySupportTest < ActiveRecord::TestCase - setup do - @connection = ActiveRecord::Base.connection - @connection.create_table(:testing_parents, force: true) - end - - teardown do - @connection.drop_table("testings", if_exists: true) - @connection.drop_table("testing_parents", if_exists: true) - end + class ReferencesWithoutForeignKeySupportTest < ActiveRecord::TestCase + setup do + @connection = ActiveRecord::Base.connection + @connection.create_table(:testing_parents, force: true) + end - test "ignores foreign keys defined with the table" do - @connection.create_table :testings do |t| - t.references :testing_parent, foreign_key: true + teardown do + @connection.drop_table("testings", if_exists: true) + @connection.drop_table("testing_parents", if_exists: true) end - assert_includes @connection.data_sources, "testings" + test "ignores foreign keys defined with the table" do + @connection.create_table :testings do |t| + t.references :testing_parent, foreign_key: true + end + + assert_includes @connection.data_sources, "testings" + end end end -end diff --git a/activerecord/test/cases/migration/references_index_test.rb b/activerecord/test/cases/migration/references_index_test.rb index a9a7f0f4c4..2866cabab6 100644 --- a/activerecord/test/cases/migration/references_index_test.rb +++ b/activerecord/test/cases/migration/references_index_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class Migration @@ -17,10 +17,10 @@ module ActiveRecord def test_creates_index connection.create_table table_name do |t| - t.references :foo, :index => true + t.references :foo, index: true end - assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + assert connection.index_exists?(table_name, :foo_id, name: :index_testings_on_foo_id) end def test_creates_index_by_default_even_if_index_option_is_not_passed @@ -28,31 +28,31 @@ module ActiveRecord t.references :foo end - assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + assert connection.index_exists?(table_name, :foo_id, name: :index_testings_on_foo_id) end def test_does_not_create_index_explicit connection.create_table table_name do |t| - t.references :foo, :index => false + t.references :foo, index: false end - assert_not connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + assert_not connection.index_exists?(table_name, :foo_id, name: :index_testings_on_foo_id) end def test_creates_index_with_options connection.create_table table_name do |t| - t.references :foo, :index => {:name => :index_testings_on_yo_momma} - t.references :bar, :index => {:unique => true} + t.references :foo, index: { name: :index_testings_on_yo_momma } + t.references :bar, index: { unique: true } end - assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_yo_momma) - assert connection.index_exists?(table_name, :bar_id, :name => :index_testings_on_bar_id, :unique => true) + assert connection.index_exists?(table_name, :foo_id, name: :index_testings_on_yo_momma) + assert connection.index_exists?(table_name, :bar_id, name: :index_testings_on_bar_id, unique: true) end unless current_adapter? :OracleAdapter def test_creates_polymorphic_index connection.create_table table_name do |t| - t.references :foo, :polymorphic => true, :index => true + t.references :foo, polymorphic: true, index: true end assert connection.index_exists?(table_name, [:foo_type, :foo_id], name: :index_testings_on_foo_type_and_foo_id) @@ -62,10 +62,10 @@ module ActiveRecord def test_creates_index_for_existing_table connection.create_table table_name connection.change_table table_name do |t| - t.references :foo, :index => true + t.references :foo, index: true end - assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + assert connection.index_exists?(table_name, :foo_id, name: :index_testings_on_foo_id) end def test_creates_index_for_existing_table_even_if_index_option_is_not_passed @@ -74,23 +74,23 @@ module ActiveRecord t.references :foo end - assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + assert connection.index_exists?(table_name, :foo_id, name: :index_testings_on_foo_id) end def test_does_not_create_index_for_existing_table_explicit connection.create_table table_name connection.change_table table_name do |t| - t.references :foo, :index => false + t.references :foo, index: false end - assert_not connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id) + assert_not connection.index_exists?(table_name, :foo_id, name: :index_testings_on_foo_id) end unless current_adapter? :OracleAdapter def test_creates_polymorphic_index_for_existing_table connection.create_table table_name connection.change_table table_name do |t| - t.references :foo, :polymorphic => true, :index => true + t.references :foo, polymorphic: true, index: true end assert connection.index_exists?(table_name, [:foo_type, :foo_id], name: :index_testings_on_foo_type_and_foo_id) diff --git a/activerecord/test/cases/migration/references_statements_test.rb b/activerecord/test/cases/migration/references_statements_test.rb index 70c64f3e71..8fbe60f24e 100644 --- a/activerecord/test/cases/migration/references_statements_test.rb +++ b/activerecord/test/cases/migration/references_statements_test.rb @@ -35,7 +35,7 @@ module ActiveRecord assert_not index_exists?(table_name, :user_id) end - def test_create_reference_id_index_even_if_index_option_is_passed + def test_create_reference_id_index_even_if_index_option_is_not_passed add_reference table_name, :user assert index_exists?(table_name, :user_id) end @@ -46,18 +46,18 @@ module ActiveRecord end def test_creates_reference_type_column_with_default - add_reference table_name, :taggable, polymorphic: { default: 'Photo' }, index: true - assert column_exists?(table_name, :taggable_type, :string, default: 'Photo') + add_reference table_name, :taggable, polymorphic: { default: "Photo" }, index: true + assert column_exists?(table_name, :taggable_type, :string, default: "Photo") end def test_creates_named_index - add_reference table_name, :tag, index: { name: 'index_taggings_on_tag_id' } - assert index_exists?(table_name, :tag_id, name: 'index_taggings_on_tag_id') + add_reference table_name, :tag, index: { name: "index_taggings_on_tag_id" } + assert index_exists?(table_name, :tag_id, name: "index_taggings_on_tag_id") end def test_creates_named_unique_index - add_reference table_name, :tag, index: { name: 'index_taggings_on_tag_id', unique: true } - assert index_exists?(table_name, :tag_id, name: 'index_taggings_on_tag_id', unique: true ) + add_reference table_name, :tag, index: { name: "index_taggings_on_tag_id", unique: true } + assert index_exists?(table_name, :tag_id, name: "index_taggings_on_tag_id", unique: true ) end def test_creates_reference_id_with_specified_type @@ -110,12 +110,12 @@ module ActiveRecord private - def with_polymorphic_column - add_column table_name, :supplier_type, :string - add_index table_name, [:supplier_id, :supplier_type] + def with_polymorphic_column + add_column table_name, :supplier_type, :string + add_index table_name, [:supplier_id, :supplier_type] - yield - end + yield + end end end end diff --git a/activerecord/test/cases/migration/rename_table_test.rb b/activerecord/test/cases/migration/rename_table_test.rb index b926a92849..fc4f700916 100644 --- a/activerecord/test/cases/migration/rename_table_test.rb +++ b/activerecord/test/cases/migration/rename_table_test.rb @@ -9,9 +9,9 @@ module ActiveRecord def setup super - add_column 'test_models', :url, :string - remove_column 'test_models', :created_at - remove_column 'test_models', :updated_at + add_column "test_models", :url, :string + remove_column "test_models", :created_at + remove_column "test_models", :updated_at end def teardown @@ -31,7 +31,7 @@ module ActiveRecord # Using explicit id in insert for compatibility across all databases connection.execute "INSERT INTO 'references' (url, created_at, updated_at) VALUES ('http://rubyonrails.com', 0, 0)" - assert_equal 'http://rubyonrails.com', connection.select_value("SELECT url FROM 'references' WHERE id=1") + assert_equal "http://rubyonrails.com", connection.select_value("SELECT url FROM 'references' WHERE id=1") ensure return unless renamed connection.rename_table :references, :test_models @@ -45,7 +45,7 @@ module ActiveRecord connection.execute "INSERT INTO octopi (#{connection.quote_column_name('id')}, #{connection.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')" - assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', connection.select_value("SELECT url FROM octopi WHERE id=1") + assert_equal "http://www.foreverflying.com/octopus-black7.jpg", connection.select_value("SELECT url FROM octopi WHERE id=1") end def test_rename_table_with_an_index @@ -55,18 +55,18 @@ module ActiveRecord connection.execute "INSERT INTO octopi (#{connection.quote_column_name('id')}, #{connection.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')" - assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', connection.select_value("SELECT url FROM octopi WHERE id=1") + assert_equal "http://www.foreverflying.com/octopus-black7.jpg", connection.select_value("SELECT url FROM octopi WHERE id=1") index = connection.indexes(:octopi).first - assert index.columns.include?("url") - assert_equal 'index_octopi_on_url', index.name + assert_includes index.columns, "url" + assert_equal "index_octopi_on_url", index.name end def test_rename_table_does_not_rename_custom_named_index - add_index :test_models, :url, name: 'special_url_idx' + add_index :test_models, :url, name: "special_url_idx" rename_table :test_models, :octopi - assert_equal ['special_url_idx'], connection.indexes(:octopi).map(&:name) + assert_equal ["special_url_idx"], connection.indexes(:octopi).map(&:name) end end @@ -74,7 +74,7 @@ module ActiveRecord def test_rename_table_for_postgresql_should_also_rename_default_sequence rename_table :test_models, :octopi - pk, seq = connection.pk_and_sequence_for('octopi') + pk, seq = connection.pk_and_sequence_for("octopi") assert_equal ConnectionAdapters::PostgreSQL::Name.new("public", "octopi_#{pk}_seq"), seq end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 5a6d2ce80c..151f3c8efd 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -1,12 +1,12 @@ -require 'cases/helper' -require 'cases/migration/helper' -require 'bigdecimal/util' -require 'concurrent/atomic/count_down_latch' +require "cases/helper" +require "cases/migration/helper" +require "bigdecimal/util" +require "concurrent/atomic/count_down_latch" -require 'models/person' -require 'models/topic' -require 'models/developer' -require 'models/computer' +require "models/person" +require "models/topic" +require "models/developer" +require "models/computer" require MIGRATIONS_ROOT + "/valid/2_we_need_reminders" require MIGRATIONS_ROOT + "/rename/1_we_need_things" @@ -59,7 +59,7 @@ class MigrationTest < ActiveRecord::TestCase %w(last_name key bio age height wealth birthday favorite_day moment_of_truth male administrator funny).each do |column| - Person.connection.remove_column('people', column) rescue nil + Person.connection.remove_column("people", column) rescue nil end Person.connection.remove_column("people", "first_name") rescue nil Person.connection.remove_column("people", "middle_name") rescue nil @@ -69,6 +69,10 @@ class MigrationTest < ActiveRecord::TestCase ActiveRecord::Migration.verbose = @verbose_was end + def test_migration_version_matches_component_version + assert_equal ActiveRecord::VERSION::STRING.to_f, ActiveRecord::Migration.current_version + end + def test_migrator_versions migrations_path = MIGRATIONS_ROOT + "/valid" old_path = ActiveRecord::Migrator.migrations_paths @@ -89,7 +93,7 @@ class MigrationTest < ActiveRecord::TestCase end def test_migration_detection_without_schema_migration_table - ActiveRecord::Base.connection.drop_table 'schema_migrations', if_exists: true + ActiveRecord::Base.connection.drop_table "schema_migrations", if_exists: true migrations_path = MIGRATIONS_ROOT + "/valid" old_path = ActiveRecord::Migrator.migrations_paths @@ -124,7 +128,7 @@ class MigrationTest < ActiveRecord::TestCase assert_not_equal temp_conn, Person.connection - temp_conn.create_table :testings2, :force => true do |t| + temp_conn.create_table :testings2, force: true do |t| t.column :foo, :string end ensure @@ -156,11 +160,11 @@ class MigrationTest < ActiveRecord::TestCase BigNumber.reset_column_information assert BigNumber.create( - :bank_balance => 1586.43, - :big_bank_balance => BigDecimal("1000234000567.95"), - :world_population => 6000000000, - :my_house_population => 3, - :value_of_e => BigDecimal("2.7182818284590452353602875") + bank_balance: 1586.43, + big_bank_balance: BigDecimal("1000234000567.95"), + world_population: 6000000000, + my_house_population: 3, + value_of_e: BigDecimal("2.7182818284590452353602875") ) b = BigNumber.first @@ -176,7 +180,7 @@ class MigrationTest < ActiveRecord::TestCase # is_a?(Bignum) assert_kind_of Integer, b.world_population assert_equal 6000000000, b.world_population - assert_kind_of Fixnum, b.my_house_population + assert_kind_of Integer, b.my_house_population assert_equal 3, b.my_house_population assert_kind_of BigDecimal, b.bank_balance assert_equal BigDecimal("1586.43"), b.bank_balance @@ -200,7 +204,7 @@ class MigrationTest < ActiveRecord::TestCase assert_in_delta BigDecimal("2.71828182845905"), b.value_of_e, 0.00000000000001 else # - SQL standard is an integer - assert_kind_of Fixnum, b.value_of_e + assert_kind_of Integer, b.value_of_e assert_equal 2, b.value_of_e end @@ -244,22 +248,22 @@ class MigrationTest < ActiveRecord::TestCase def test_instance_based_migration_up migration = MockMigration.new - assert !migration.went_up, 'have not gone up' - assert !migration.went_down, 'have not gone down' + assert !migration.went_up, "have not gone up" + assert !migration.went_down, "have not gone down" migration.migrate :up - assert migration.went_up, 'have gone up' - assert !migration.went_down, 'have not gone down' + assert migration.went_up, "have gone up" + assert !migration.went_down, "have not gone down" end def test_instance_based_migration_down migration = MockMigration.new - assert !migration.went_up, 'have not gone up' - assert !migration.went_down, 'have not gone down' + assert !migration.went_up, "have not gone up" + assert !migration.went_down, "have not gone down" migration.migrate :down - assert !migration.went_up, 'have gone up' - assert migration.went_down, 'have not gone down' + assert !migration.went_up, "have gone up" + assert migration.went_down, "have not gone down" end if ActiveRecord::Base.connection.supports_ddl_transactions? @@ -270,7 +274,7 @@ class MigrationTest < ActiveRecord::TestCase def version; 100 end def migrate(x) add_column "people", "last_name", :string - raise 'Something broke' + raise "Something broke" end }.new @@ -291,7 +295,7 @@ class MigrationTest < ActiveRecord::TestCase def version; 100 end def migrate(x) add_column "people", "last_name", :string - raise 'Something broke' + raise "Something broke" end }.new @@ -309,12 +313,12 @@ class MigrationTest < ActiveRecord::TestCase assert_no_column Person, :last_name migration = Class.new(ActiveRecord::Migration::Current) { - self.disable_ddl_transaction! + disable_ddl_transaction! def version; 101 end def migrate(x) add_column "people", "last_name", :string - raise 'Something broke' + raise "Something broke" end }.new @@ -326,8 +330,8 @@ class MigrationTest < ActiveRecord::TestCase "without ddl transactions, the Migrator should not rollback on error but it did." ensure Person.reset_column_information - if Person.column_names.include?('last_name') - Person.connection.remove_column('people', 'last_name') + if Person.column_names.include?("last_name") + Person.connection.remove_column("people", "last_name") end end end @@ -397,7 +401,6 @@ class MigrationTest < ActiveRecord::TestCase ENV["RACK_ENV"] = original_rack_env end - def test_migration_sets_internal_metadata_even_when_fully_migrated current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call migrations_path = MIGRATIONS_ROOT + "/valid" @@ -424,25 +427,27 @@ class MigrationTest < ActiveRecord::TestCase ENV["RACK_ENV"] = original_rack_env end - def test_rename_internal_metadata_table - original_internal_metadata_table_name = ActiveRecord::Base.internal_metadata_table_name - - ActiveRecord::Base.internal_metadata_table_name = "active_record_internal_metadatas" - Reminder.reset_table_name + def test_internal_metadata_stores_environment_when_other_data_exists + ActiveRecord::InternalMetadata.delete_all + ActiveRecord::InternalMetadata[:foo] = "bar" - ActiveRecord::Base.internal_metadata_table_name = original_internal_metadata_table_name - Reminder.reset_table_name + current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call + migrations_path = MIGRATIONS_ROOT + "/valid" + old_path = ActiveRecord::Migrator.migrations_paths + ActiveRecord::Migrator.migrations_paths = migrations_path - assert_equal "ar_internal_metadata", ActiveRecord::InternalMetadata.table_name + current_env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call + ActiveRecord::Migrator.up(migrations_path) + assert_equal current_env, ActiveRecord::InternalMetadata[:environment] + assert_equal "bar", ActiveRecord::InternalMetadata[:foo] ensure - ActiveRecord::Base.internal_metadata_table_name = original_internal_metadata_table_name - Reminder.reset_table_name + ActiveRecord::Migrator.migrations_paths = old_path end def test_proper_table_name_on_migration reminder_class = new_isolated_reminder_class migration = ActiveRecord::Migration.new - assert_equal "table", migration.proper_table_name('table') + assert_equal "table", migration.proper_table_name("table") assert_equal "table", migration.proper_table_name(:table) assert_equal "reminders", migration.proper_table_name(reminder_class) reminder_class.reset_table_name @@ -451,26 +456,26 @@ class MigrationTest < ActiveRecord::TestCase # Use the model's own prefix/suffix if a model is given ActiveRecord::Base.table_name_prefix = "ARprefix_" ActiveRecord::Base.table_name_suffix = "_ARsuffix" - reminder_class.table_name_prefix = 'prefix_' - reminder_class.table_name_suffix = '_suffix' + reminder_class.table_name_prefix = "prefix_" + reminder_class.table_name_suffix = "_suffix" reminder_class.reset_table_name assert_equal "prefix_reminders_suffix", migration.proper_table_name(reminder_class) - reminder_class.table_name_prefix = '' - reminder_class.table_name_suffix = '' + reminder_class.table_name_prefix = "" + reminder_class.table_name_suffix = "" reminder_class.reset_table_name # Use AR::Base's prefix/suffix if string or symbol is given ActiveRecord::Base.table_name_prefix = "prefix_" ActiveRecord::Base.table_name_suffix = "_suffix" reminder_class.reset_table_name - assert_equal "prefix_table_suffix", migration.proper_table_name('table', migration.table_name_options) + assert_equal "prefix_table_suffix", migration.proper_table_name("table", migration.table_name_options) assert_equal "prefix_table_suffix", migration.proper_table_name(:table, migration.table_name_options) end def test_rename_table_with_prefix_and_suffix assert !Thing.table_exists? - ActiveRecord::Base.table_name_prefix = 'p_' - ActiveRecord::Base.table_name_suffix = '_s' + ActiveRecord::Base.table_name_prefix = "p_" + ActiveRecord::Base.table_name_suffix = "_s" Thing.reset_table_name Thing.reset_sequence_name WeNeedThings.up @@ -490,8 +495,8 @@ class MigrationTest < ActiveRecord::TestCase def test_add_drop_table_with_prefix_and_suffix assert !Reminder.table_exists? - ActiveRecord::Base.table_name_prefix = 'prefix_' - ActiveRecord::Base.table_name_suffix = '_suffix' + ActiveRecord::Base.table_name_prefix = "prefix_" + ActiveRecord::Base.table_name_suffix = "_suffix" Reminder.reset_table_name Reminder.reset_sequence_name Reminder.reset_column_information @@ -508,7 +513,7 @@ class MigrationTest < ActiveRecord::TestCase def test_create_table_with_binary_column assert_nothing_raised { Person.connection.create_table :binary_testings do |t| - t.column "data", :binary, :null => false + t.column "data", :binary, null: false end } @@ -546,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 @@ -553,7 +575,7 @@ class MigrationTest < ActiveRecord::TestCase assert_nothing_raised do begin Person.connection.create_table :table_with_name_thats_just_ok do |t| - t.column :foo, :string, :null => false + t.column :foo, :string, null: false end ensure Person.connection.drop_table :table_with_name_thats_just_ok rescue nil @@ -564,15 +586,15 @@ class MigrationTest < ActiveRecord::TestCase assert_nothing_raised do begin Person.connection.create_table :table_with_name_thats_just_ok, - :sequence_name => 'suitably_short_seq' do |t| - t.column :foo, :string, :null => false + sequence_name: "suitably_short_seq" do |t| + t.column :foo, :string, null: false end Person.connection.execute("select suitably_short_seq.nextval from dual") ensure Person.connection.drop_table :table_with_name_thats_just_ok, - :sequence_name => 'suitably_short_seq' rescue nil + sequence_name: "suitably_short_seq" rescue nil end end @@ -586,8 +608,8 @@ class MigrationTest < ActiveRecord::TestCase if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter) def test_out_of_range_integer_limit_should_raise e = assert_raise(ActiveRecord::ActiveRecordError, "integer limit didn't raise") do - Person.connection.create_table :test_integer_limits, :force => true do |t| - t.column :bigone, :integer, :limit => 10 + Person.connection.create_table :test_integer_limits, force: true do |t| + t.column :bigone, :integer, limit: 10 end end @@ -721,13 +743,13 @@ end class ReservedWordsMigrationTest < ActiveRecord::TestCase def test_drop_index_from_table_named_values connection = Person.connection - connection.create_table :values, :force => true do |t| + connection.create_table :values, force: true do |t| t.integer :value end assert_nothing_raised do connection.add_index :values, :value - connection.remove_index :values, :column => :value + connection.remove_index :values, column: :value end ensure connection.drop_table :values rescue nil @@ -742,8 +764,8 @@ class ExplicitlyNamedIndexMigrationTest < ActiveRecord::TestCase end assert_nothing_raised do - connection.add_index :values, :value, name: 'a_different_name' - connection.remove_index :values, column: :value, name: 'a_different_name' + connection.add_index :values, :value, name: "a_different_name" + connection.remove_index :values, column: :value, name: "a_different_name" end ensure connection.drop_table :values rescue nil @@ -754,7 +776,7 @@ if ActiveRecord::Base.connection.supports_bulk_alter? class BulkAlterTableMigrationsTest < ActiveRecord::TestCase def setup @connection = Person.connection - @connection.create_table(:delete_me, :force => true) {|t| } + @connection.create_table(:delete_me, force: true) { |t| } Person.reset_column_information Person.reset_sequence_name end @@ -768,15 +790,15 @@ if ActiveRecord::Base.connection.supports_bulk_alter? with_bulk_change_table do |t| t.column :name, :string t.string :qualification, :experience - t.integer :age, :default => 0 + t.integer :age, default: 0 t.date :birthdate t.timestamps null: true end end assert_equal 8, columns.size - [:name, :qualification, :experience].each {|s| assert_equal :string, column(s).type } - assert_equal '0', column(:age).default + [:name, :qualification, :experience].each { |s| assert_equal :string, column(s).type } + assert_equal "0", column(:age).default end def test_removing_columns @@ -784,7 +806,7 @@ if ActiveRecord::Base.connection.supports_bulk_alter? t.string :qualification, :experience end - [:qualification, :experience].each {|c| assert column(c) } + [:qualification, :experience].each { |c| assert column(c) } assert_queries(1) do with_bulk_change_table do |t| @@ -793,7 +815,7 @@ if ActiveRecord::Base.connection.supports_bulk_alter? end end - [:qualification, :experience].each {|c| assert ! column(c) } + [:qualification, :experience].each { |c| assert ! column(c) } assert column(:qualification_experience) end @@ -807,7 +829,7 @@ if ActiveRecord::Base.connection.supports_bulk_alter? # Adding an index fires a query every time to check if an index already exists or not assert_queries(3) do with_bulk_change_table do |t| - t.index :username, :unique => true, :name => :awesome_username_index + t.index :username, unique: true, name: :awesome_username_index t.index [:name, :age] end end @@ -815,7 +837,7 @@ if ActiveRecord::Base.connection.supports_bulk_alter? assert_equal 2, indexes.size name_age_index = index(:index_delete_me_on_name_and_age) - assert_equal ['name', 'age'].sort, name_age_index.columns.sort + assert_equal ["name", "age"].sort, name_age_index.columns.sort assert ! name_age_index.unique assert index(:awesome_username_index).unique @@ -832,7 +854,7 @@ if ActiveRecord::Base.connection.supports_bulk_alter? assert_queries(3) do with_bulk_change_table do |t| t.remove_index :name - t.index :name, :name => :new_name_index, :unique => true + t.index :name, name: :new_name_index, unique: true end end @@ -854,43 +876,43 @@ if ActiveRecord::Base.connection.supports_bulk_alter? # One query for columns (delete_me table) # One query for primary key (delete_me table) # One query to do the bulk change - assert_queries(3, :ignore_none => true) do + assert_queries(3, ignore_none: true) do with_bulk_change_table do |t| - t.change :name, :string, :default => 'NONAME' + t.change :name, :string, default: "NONAME" t.change :birthdate, :datetime end end - assert_equal 'NONAME', column(:name).default + assert_equal "NONAME", column(:name).default assert_equal :datetime, column(:birthdate).type end protected - def with_bulk_change_table - # Reset columns/indexes cache as we're changing the table - @columns = @indexes = nil + def with_bulk_change_table + # Reset columns/indexes cache as we're changing the table + @columns = @indexes = nil - Person.connection.change_table(:delete_me, :bulk => true) do |t| - yield t + Person.connection.change_table(:delete_me, bulk: true) do |t| + yield t + end end - end - def column(name) - columns.detect {|c| c.name == name.to_s } - end + def column(name) + columns.detect { |c| c.name == name.to_s } + end - def columns - @columns ||= Person.connection.columns('delete_me') - end + def columns + @columns ||= Person.connection.columns("delete_me") + end - def index(name) - indexes.detect {|i| i.name == name.to_s } - end + def index(name) + indexes.detect { |i| i.name == name.to_s } + end - def indexes - @indexes ||= Person.connection.indexes('delete_me') - end + def indexes + @indexes ||= Person.connection.indexes("delete_me") + end end # AlterTableMigrationsTest end @@ -912,7 +934,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase @migrations_path = MIGRATIONS_ROOT + "/valid" @existing_migrations = Dir[@migrations_path + "/*.rb"] - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/to_copy") assert File.exist?(@migrations_path + "/4_people_have_hobbies.bukkits.rb") assert File.exist?(@migrations_path + "/5_people_have_descriptions.bukkits.rb") assert_equal [@migrations_path + "/4_people_have_hobbies.bukkits.rb", @migrations_path + "/5_people_have_descriptions.bukkits.rb"], copied.map(&:filename) @@ -921,7 +943,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase assert_equal expected, IO.readlines(@migrations_path + "/4_people_have_hobbies.bukkits.rb")[0].chomp files_count = Dir[@migrations_path + "/*.rb"].length - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/to_copy") assert_equal files_count, Dir[@migrations_path + "/*.rb"].length assert copied.empty? ensure @@ -954,7 +976,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase @existing_migrations = Dir[@migrations_path + "/*.rb"] travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/to_copy_with_timestamps") assert File.exist?(@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb") assert File.exist?(@migrations_path + "/20100726101011_people_have_descriptions.bukkits.rb") expected = [@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb", @@ -962,7 +984,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase assert_equal expected, copied.map(&:filename) files_count = Dir[@migrations_path + "/*.rb"].length - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/to_copy_with_timestamps") assert_equal files_count, Dir[@migrations_path + "/*.rb"].length assert copied.empty? end @@ -999,12 +1021,12 @@ class CopyMigrationsTest < ActiveRecord::TestCase @existing_migrations = Dir[@migrations_path + "/*.rb"] travel_to(Time.utc(2010, 2, 20, 10, 10, 10)) do - ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"}) + ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/to_copy_with_timestamps") assert File.exist?(@migrations_path + "/20100301010102_people_have_hobbies.bukkits.rb") assert File.exist?(@migrations_path + "/20100301010103_people_have_descriptions.bukkits.rb") files_count = Dir[@migrations_path + "/*.rb"].length - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/to_copy_with_timestamps") assert_equal files_count, Dir[@migrations_path + "/*.rb"].length assert copied.empty? end @@ -1017,7 +1039,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase @migrations_path = MIGRATIONS_ROOT + "/valid" @existing_migrations = Dir[@migrations_path + "/*.rb"] - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/magic"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/magic") assert File.exist?(@migrations_path + "/4_currencies_have_symbols.bukkits.rb") assert_equal [@migrations_path + "/4_currencies_have_symbols.bukkits.rb"], copied.map(&:filename) @@ -1025,7 +1047,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase assert_equal expected, IO.readlines(@migrations_path + "/4_currencies_have_symbols.bukkits.rb")[0..1].join.chomp files_count = Dir[@migrations_path + "/*.rb"].length - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/magic"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/magic") assert_equal files_count, Dir[@migrations_path + "/*.rb"].length assert copied.empty? ensure @@ -1042,7 +1064,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase skipped = [] on_skip = Proc.new { |name, migration| skipped << "#{name} #{migration.name}" } - copied = ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip) + copied = ActiveRecord::Migration.copy(@migrations_path, sources, on_skip: on_skip) assert_equal 2, copied.length assert_equal 1, skipped.length @@ -1060,8 +1082,8 @@ class CopyMigrationsTest < ActiveRecord::TestCase skipped = [] on_skip = Proc.new { |name, migration| skipped << "#{name} #{migration.name}" } - copied = ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip) - ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip) + copied = ActiveRecord::Migration.copy(@migrations_path, sources, on_skip: on_skip) + ActiveRecord::Migration.copy(@migrations_path, sources, on_skip: on_skip) assert_equal 2, copied.length assert_equal 0, skipped.length @@ -1074,7 +1096,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase @existing_migrations = [] travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/to_copy_with_timestamps") assert File.exist?(@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb") assert File.exist?(@migrations_path + "/20100726101011_people_have_descriptions.bukkits.rb") assert_equal 2, copied.length @@ -1089,7 +1111,7 @@ class CopyMigrationsTest < ActiveRecord::TestCase @existing_migrations = [] travel_to(Time.utc(2010, 7, 26, 10, 10, 10)) do - copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/to_copy_with_timestamps"}) + copied = ActiveRecord::Migration.copy(@migrations_path, bukkits: MIGRATIONS_ROOT + "/to_copy_with_timestamps") assert File.exist?(@migrations_path + "/20100726101010_people_have_hobbies.bukkits.rb") assert File.exist?(@migrations_path + "/20100726101011_people_have_descriptions.bukkits.rb") assert_equal 2, copied.length diff --git a/activerecord/test/cases/migrator_test.rb b/activerecord/test/cases/migrator_test.rb index 86eca53141..1ba18bc9c2 100644 --- a/activerecord/test/cases/migrator_test.rb +++ b/activerecord/test/cases/migrator_test.rb @@ -9,7 +9,7 @@ class MigratorTest < ActiveRecord::TestCase class Sensor < ActiveRecord::Migration::Current attr_reader :went_up, :went_down - def initialize name = self.class.name, version = nil + def initialize(name = self.class.name, version = nil) super @went_up = false @went_down = false @@ -46,21 +46,21 @@ class MigratorTest < ActiveRecord::TestCase def test_migrator_with_duplicate_names assert_raises(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do - list = [ActiveRecord::Migration.new('Chunky'), ActiveRecord::Migration.new('Chunky')] + list = [ActiveRecord::Migration.new("Chunky"), ActiveRecord::Migration.new("Chunky")] ActiveRecord::Migrator.new(:up, list) end end def test_migrator_with_duplicate_versions assert_raises(ActiveRecord::DuplicateMigrationVersionError) do - list = [ActiveRecord::Migration.new('Foo', 1), ActiveRecord::Migration.new('Bar', 1)] + list = [ActiveRecord::Migration.new("Foo", 1), ActiveRecord::Migration.new("Bar", 1)] ActiveRecord::Migrator.new(:up, list) end end def test_migrator_with_missing_version_numbers assert_raises(ActiveRecord::UnknownMigrationVersionError) do - list = [ActiveRecord::Migration.new('Foo', 1), ActiveRecord::Migration.new('Bar', 2)] + list = [ActiveRecord::Migration.new("Foo", 1), ActiveRecord::Migration.new("Bar", 2)] ActiveRecord::Migrator.new(:up, list, 3).run end end @@ -68,7 +68,7 @@ class MigratorTest < ActiveRecord::TestCase def test_finds_migrations migrations = ActiveRecord::Migrator.migrations(MIGRATIONS_ROOT + "/valid") - [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i| + [[1, "ValidPeopleHaveLastNames"], [2, "WeNeedReminders"], [3, "InnocentJointable"]].each_with_index do |pair, i| assert_equal migrations[i].version, pair.first assert_equal migrations[i].name, pair.last end @@ -77,14 +77,14 @@ class MigratorTest < ActiveRecord::TestCase def test_finds_migrations_in_subdirectories migrations = ActiveRecord::Migrator.migrations(MIGRATIONS_ROOT + "/valid_with_subdirectories") - [[1, 'ValidPeopleHaveLastNames'], [2, 'WeNeedReminders'], [3, 'InnocentJointable']].each_with_index do |pair, i| + [[1, "ValidPeopleHaveLastNames"], [2, "WeNeedReminders"], [3, "InnocentJointable"]].each_with_index do |pair, i| assert_equal migrations[i].version, pair.first assert_equal migrations[i].name, pair.last end end def test_finds_migrations_from_two_directories - directories = [MIGRATIONS_ROOT + '/valid_with_timestamps', MIGRATIONS_ROOT + '/to_copy_with_timestamps'] + directories = [MIGRATIONS_ROOT + "/valid_with_timestamps", MIGRATIONS_ROOT + "/to_copy_with_timestamps"] migrations = ActiveRecord::Migrator.migrations directories [[20090101010101, "PeopleHaveHobbies"], @@ -92,15 +92,15 @@ class MigratorTest < ActiveRecord::TestCase [20100101010101, "ValidWithTimestampsPeopleHaveLastNames"], [20100201010101, "ValidWithTimestampsWeNeedReminders"], [20100301010101, "ValidWithTimestampsInnocentJointable"]].each_with_index do |pair, i| - assert_equal pair.first, migrations[i].version - assert_equal pair.last, migrations[i].name + assert_equal pair.first, migrations[i].version + assert_equal pair.last, migrations[i].name end end def test_finds_migrations_in_numbered_directory - migrations = ActiveRecord::Migrator.migrations [MIGRATIONS_ROOT + '/10_urban'] + migrations = ActiveRecord::Migrator.migrations [MIGRATIONS_ROOT + "/10_urban"] assert_equal 9, migrations[0].version - assert_equal 'AddExpressions', migrations[0].name + assert_equal "AddExpressions", migrations[0].name end def test_relative_migrations @@ -109,14 +109,14 @@ class MigratorTest < ActiveRecord::TestCase end migration_proxy = list.find { |item| - item.name == 'ValidPeopleHaveLastNames' + item.name == "ValidPeopleHaveLastNames" } - assert migration_proxy, 'should find pending migration' + assert migration_proxy, "should find pending migration" end def test_finds_pending_migrations - ActiveRecord::SchemaMigration.create!(:version => '1') - migration_list = [ActiveRecord::Migration.new('foo', 1), ActiveRecord::Migration.new('bar', 3)] + ActiveRecord::SchemaMigration.create!(version: "1") + migration_list = [ActiveRecord::Migration.new("foo", 1), ActiveRecord::Migration.new("bar", 3)] migrations = ActiveRecord::Migrator.new(:up, migration_list).pending_migrations assert_equal 1, migrations.size @@ -124,21 +124,21 @@ class MigratorTest < ActiveRecord::TestCase end def test_migrator_interleaved_migrations - pass_one = [Sensor.new('One', 1)] + pass_one = [Sensor.new("One", 1)] ActiveRecord::Migrator.new(:up, pass_one).migrate assert pass_one.first.went_up assert_not pass_one.first.went_down - pass_two = [Sensor.new('One', 1), Sensor.new('Three', 3)] + pass_two = [Sensor.new("One", 1), Sensor.new("Three", 3)] ActiveRecord::Migrator.new(:up, pass_two).migrate assert_not pass_two[0].went_up assert pass_two[1].went_up assert pass_two.all? { |x| !x.went_down } - pass_three = [Sensor.new('One', 1), - Sensor.new('Two', 2), - Sensor.new('Three', 3)] + pass_three = [Sensor.new("One", 1), + Sensor.new("Two", 2), + Sensor.new("Three", 3)] ActiveRecord::Migrator.new(:down, pass_three).migrate assert pass_three[0].went_down @@ -165,7 +165,7 @@ class MigratorTest < ActiveRecord::TestCase end def test_current_version - ActiveRecord::SchemaMigration.create!(:version => '1000') + ActiveRecord::SchemaMigration.create!(version: "1000") assert_equal 1000, ActiveRecord::Migrator.current_version end @@ -313,9 +313,9 @@ class MigratorTest < ActiveRecord::TestCase _, migrator = migrator_class(3) ActiveRecord::Base.connection.drop_table "schema_migrations", if_exists: true - ActiveSupport::Deprecation.silence { assert_not ActiveRecord::Base.connection.table_exists?('schema_migrations') } + ActiveSupport::Deprecation.silence { assert_not ActiveRecord::Base.connection.table_exists?("schema_migrations") } migrator.migrate("valid", 1) - ActiveSupport::Deprecation.silence { assert ActiveRecord::Base.connection.table_exists?('schema_migrations') } + ActiveSupport::Deprecation.silence { assert ActiveRecord::Base.connection.table_exists?("schema_migrations") } end def test_migrator_forward @@ -332,7 +332,7 @@ class MigratorTest < ActiveRecord::TestCase def test_only_loads_pending_migrations # migrate up to 1 - ActiveRecord::SchemaMigration.create!(:version => '1') + ActiveRecord::SchemaMigration.create!(version: "1") calls, migrator = migrator_class(3) migrator.migrate("valid", nil) @@ -357,32 +357,32 @@ class MigratorTest < ActiveRecord::TestCase end private - def m(name, version) - x = Sensor.new name, version - x.extend(Module.new { - define_method(:up) { yield(:up, x); super() } - define_method(:down) { yield(:down, x); super() } - }) if block_given? - end + def m(name, version) + x = Sensor.new name, version + x.extend(Module.new { + define_method(:up) { yield(:up, x); super() } + define_method(:down) { yield(:down, x); super() } + }) if block_given? + end - def sensors(count) - calls = [] - migrations = count.times.map { |i| - m(nil, i + 1) { |c,migration| - calls << [c, migration.version] + def sensors(count) + calls = [] + migrations = count.times.map { |i| + m(nil, i + 1) { |c,migration| + calls << [c, migration.version] + } } - } - [calls, migrations] - end + [calls, migrations] + end - def migrator_class(count) - calls, migrations = sensors(count) + def migrator_class(count) + calls, migrations = sensors(count) - migrator = Class.new(ActiveRecord::Migrator).extend(Module.new { - define_method(:migrations) { |paths| - migrations - } - }) - [calls, migrator] - end + migrator = Class.new(ActiveRecord::Migrator).extend(Module.new { + define_method(:migrations) { |paths| + migrations + } + }) + [calls, migrator] + end end diff --git a/activerecord/test/cases/mixin_test.rb b/activerecord/test/cases/mixin_test.rb index 7ebdcac711..a8af8e30f7 100644 --- a/activerecord/test/cases/mixin_test.rb +++ b/activerecord/test/cases/mixin_test.rb @@ -41,13 +41,12 @@ class TouchTest < ActiveRecord::TestCase old_updated_at = stamped.updated_at - travel 5.minutes do - stamped.lft_will_change! - stamped.save + travel 5.minutes + stamped.lft_will_change! + stamped.save - assert_equal Time.now, stamped.updated_at - assert_equal old_updated_at, stamped.created_at - end + assert_equal Time.now, stamped.updated_at + assert_equal old_updated_at, stamped.created_at end def test_create_turned_off @@ -64,5 +63,4 @@ class TouchTest < ActiveRecord::TestCase ensure Mixin.record_timestamps = true end - end diff --git a/activerecord/test/cases/modules_test.rb b/activerecord/test/cases/modules_test.rb index 486bcc22df..f8a7bab35f 100644 --- a/activerecord/test/cases/modules_test.rb +++ b/activerecord/test/cases/modules_test.rb @@ -1,8 +1,8 @@ require "cases/helper" -require 'models/company_in_module' -require 'models/shop' -require 'models/developer' -require 'models/computer' +require "models/company_in_module" +require "models/shop" +require "models/developer" +require "models/computer" class ModulesTest < ActiveRecord::TestCase fixtures :accounts, :companies, :projects, :developers, :collections, :products, :variants @@ -31,7 +31,7 @@ class ModulesTest < ActiveRecord::TestCase def test_module_spanning_associations firm = MyApplication::Business::Firm.first assert !firm.clients.empty?, "Firm should have clients" - assert_nil firm.class.table_name.match('::'), "Firm shouldn't have the module appear in its table name" + assert_nil firm.class.table_name.match("::"), "Firm shouldn't have the module appear in its table name" end def test_module_spanning_has_and_belongs_to_many_associations @@ -41,7 +41,7 @@ class ModulesTest < ActiveRecord::TestCase end def test_associations_spanning_cross_modules - account = MyApplication::Billing::Account.all.merge!(:order => 'id').first + account = MyApplication::Billing::Account.all.merge!(order: "id").first assert_kind_of MyApplication::Business::Firm, account.firm assert_kind_of MyApplication::Billing::Firm, account.qualified_billing_firm assert_kind_of MyApplication::Billing::Firm, account.unqualified_billing_firm @@ -50,14 +50,14 @@ class ModulesTest < ActiveRecord::TestCase end def test_find_account_and_include_company - account = MyApplication::Billing::Account.all.merge!(:includes => :firm).find(1) + account = MyApplication::Billing::Account.all.merge!(includes: :firm).find(1) assert_kind_of MyApplication::Business::Firm, account.firm end def test_table_name - assert_equal 'accounts', MyApplication::Billing::Account.table_name, 'table_name for ActiveRecord model in module' - assert_equal 'companies', MyApplication::Business::Client.table_name, 'table_name for ActiveRecord model subclass' - assert_equal 'company_contacts', MyApplication::Business::Client::Contact.table_name, 'table_name for ActiveRecord model enclosed by another ActiveRecord model' + assert_equal "accounts", MyApplication::Billing::Account.table_name, "table_name for ActiveRecord model in module" + assert_equal "companies", MyApplication::Business::Client.table_name, "table_name for ActiveRecord model subclass" + assert_equal "company_contacts", MyApplication::Business::Client::Contact.table_name, "table_name for ActiveRecord model enclosed by another ActiveRecord model" end def test_assign_ids @@ -73,8 +73,8 @@ class ModulesTest < ActiveRecord::TestCase clients = [] assert_nothing_raised do - clients << MyApplication::Business::Client.references(:accounts).merge!(:includes => {:firm => :account}, :where => 'accounts.id IS NOT NULL').find(3) - clients << MyApplication::Business::Client.includes(:firm => :account).find(3) + clients << MyApplication::Business::Client.references(:accounts).merge!(includes: { firm: :account }, where: "accounts.id IS NOT NULL").find(3) + clients << MyApplication::Business::Client.includes(firm: :account).find(3) end clients.each do |client| @@ -85,9 +85,9 @@ class ModulesTest < ActiveRecord::TestCase end def test_module_table_name_prefix - assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Company.table_name, 'inferred table_name for ActiveRecord model in module with table_name_prefix' - assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Nested::Company.table_name, 'table_name for ActiveRecord model in nested module with a parent table_name_prefix' - assert_equal 'companies', MyApplication::Business::Prefixed::Firm.table_name, 'explicit table_name for ActiveRecord model in module with table_name_prefix should not be prefixed' + assert_equal "prefixed_companies", MyApplication::Business::Prefixed::Company.table_name, "inferred table_name for ActiveRecord model in module with table_name_prefix" + assert_equal "prefixed_companies", MyApplication::Business::Prefixed::Nested::Company.table_name, "table_name for ActiveRecord model in nested module with a parent table_name_prefix" + assert_equal "companies", MyApplication::Business::Prefixed::Firm.table_name, "explicit table_name for ActiveRecord model in module with table_name_prefix should not be prefixed" end def test_module_table_name_prefix_with_global_prefix @@ -101,21 +101,21 @@ class ModulesTest < ActiveRecord::TestCase MyApplication::Business::Prefixed::Nested::Company, MyApplication::Billing::Account ] - ActiveRecord::Base.table_name_prefix = 'global_' + ActiveRecord::Base.table_name_prefix = "global_" classes.each(&:reset_table_name) - assert_equal 'global_companies', MyApplication::Business::Company.table_name, 'inferred table_name for ActiveRecord model in module without table_name_prefix' - assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Company.table_name, 'inferred table_name for ActiveRecord model in module with table_name_prefix' - assert_equal 'prefixed_companies', MyApplication::Business::Prefixed::Nested::Company.table_name, 'table_name for ActiveRecord model in nested module with a parent table_name_prefix' - assert_equal 'companies', MyApplication::Business::Prefixed::Firm.table_name, 'explicit table_name for ActiveRecord model in module with table_name_prefix should not be prefixed' + assert_equal "global_companies", MyApplication::Business::Company.table_name, "inferred table_name for ActiveRecord model in module without table_name_prefix" + assert_equal "prefixed_companies", MyApplication::Business::Prefixed::Company.table_name, "inferred table_name for ActiveRecord model in module with table_name_prefix" + assert_equal "prefixed_companies", MyApplication::Business::Prefixed::Nested::Company.table_name, "table_name for ActiveRecord model in nested module with a parent table_name_prefix" + assert_equal "companies", MyApplication::Business::Prefixed::Firm.table_name, "explicit table_name for ActiveRecord model in module with table_name_prefix should not be prefixed" ensure - ActiveRecord::Base.table_name_prefix = '' + ActiveRecord::Base.table_name_prefix = "" classes.each(&:reset_table_name) end def test_module_table_name_suffix - assert_equal 'companies_suffixed', MyApplication::Business::Suffixed::Company.table_name, 'inferred table_name for ActiveRecord model in module with table_name_suffix' - assert_equal 'companies_suffixed', MyApplication::Business::Suffixed::Nested::Company.table_name, 'table_name for ActiveRecord model in nested module with a parent table_name_suffix' - assert_equal 'companies', MyApplication::Business::Suffixed::Firm.table_name, 'explicit table_name for ActiveRecord model in module with table_name_suffix should not be suffixed' + assert_equal "companies_suffixed", MyApplication::Business::Suffixed::Company.table_name, "inferred table_name for ActiveRecord model in module with table_name_suffix" + assert_equal "companies_suffixed", MyApplication::Business::Suffixed::Nested::Company.table_name, "table_name for ActiveRecord model in nested module with a parent table_name_suffix" + assert_equal "companies", MyApplication::Business::Suffixed::Firm.table_name, "explicit table_name for ActiveRecord model in module with table_name_suffix should not be suffixed" end def test_module_table_name_suffix_with_global_suffix @@ -129,14 +129,14 @@ class ModulesTest < ActiveRecord::TestCase MyApplication::Business::Suffixed::Nested::Company, MyApplication::Billing::Account ] - ActiveRecord::Base.table_name_suffix = '_global' + ActiveRecord::Base.table_name_suffix = "_global" classes.each(&:reset_table_name) - assert_equal 'companies_global', MyApplication::Business::Company.table_name, 'inferred table_name for ActiveRecord model in module without table_name_suffix' - assert_equal 'companies_suffixed', MyApplication::Business::Suffixed::Company.table_name, 'inferred table_name for ActiveRecord model in module with table_name_suffix' - assert_equal 'companies_suffixed', MyApplication::Business::Suffixed::Nested::Company.table_name, 'table_name for ActiveRecord model in nested module with a parent table_name_suffix' - assert_equal 'companies', MyApplication::Business::Suffixed::Firm.table_name, 'explicit table_name for ActiveRecord model in module with table_name_suffix should not be suffixed' + assert_equal "companies_global", MyApplication::Business::Company.table_name, "inferred table_name for ActiveRecord model in module without table_name_suffix" + assert_equal "companies_suffixed", MyApplication::Business::Suffixed::Company.table_name, "inferred table_name for ActiveRecord model in module with table_name_suffix" + assert_equal "companies_suffixed", MyApplication::Business::Suffixed::Nested::Company.table_name, "table_name for ActiveRecord model in nested module with a parent table_name_suffix" + assert_equal "companies", MyApplication::Business::Suffixed::Firm.table_name, "explicit table_name for ActiveRecord model in module with table_name_suffix should not be suffixed" ensure - ActiveRecord::Base.table_name_suffix = '' + ActiveRecord::Base.table_name_suffix = "" classes.each(&:reset_table_name) end diff --git a/activerecord/test/cases/multiparameter_attributes_test.rb b/activerecord/test/cases/multiparameter_attributes_test.rb index ae18573126..b2f76398df 100644 --- a/activerecord/test/cases/multiparameter_attributes_test.rb +++ b/activerecord/test/cases/multiparameter_attributes_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'models/topic' -require 'models/customer' +require "models/topic" +require "models/customer" class MultiParameterAttributeTest < ActiveRecord::TestCase fixtures :topics @@ -11,15 +11,13 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase topic.attributes = attributes # note that extra #to_date call allows test to pass for Oracle, which # treats dates/times the same - assert_date_from_db Date.new(2004, 6, 24), topic.last_read.to_date + assert_equal Date.new(2004, 6, 24), topic.last_read.to_date end def test_multiparameter_attributes_on_date_with_empty_year attributes = { "last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "24" } topic = Topic.find(1) topic.attributes = attributes - # note that extra #to_date call allows test to pass for Oracle, which - # treats dates/times the same assert_nil topic.last_read end @@ -27,8 +25,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "24" } topic = Topic.find(1) topic.attributes = attributes - # note that extra #to_date call allows test to pass for Oracle, which - # treats dates/times the same assert_nil topic.last_read end @@ -36,8 +32,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "" } topic = Topic.find(1) topic.attributes = attributes - # note that extra #to_date call allows test to pass for Oracle, which - # treats dates/times the same assert_nil topic.last_read end @@ -45,8 +39,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase attributes = { "last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "" } topic = Topic.find(1) topic.attributes = attributes - # note that extra #to_date call allows test to pass for Oracle, which - # treats dates/times the same assert_nil topic.last_read end @@ -54,8 +46,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "" } topic = Topic.find(1) topic.attributes = attributes - # note that extra #to_date call allows test to pass for Oracle, which - # treats dates/times the same assert_nil topic.last_read end @@ -63,8 +53,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase attributes = { "last_read(1i)" => "", "last_read(2i)" => "", "last_read(3i)" => "24" } topic = Topic.find(1) topic.attributes = attributes - # note that extra #to_date call allows test to pass for Oracle, which - # treats dates/times the same assert_nil topic.last_read end @@ -214,6 +202,20 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase Topic.reset_column_information end + def test_multiparameter_attributes_on_time_with_time_zone_aware_attributes_and_invalid_time_params + with_timezone_config aware_attributes: true do + Topic.reset_column_information + attributes = { + "written_on(1i)" => "2004", "written_on(2i)" => "", "written_on(3i)" => "" + } + topic = Topic.find(1) + topic.attributes = attributes + assert_nil topic.written_on + end + ensure + Topic.reset_column_information + end + def test_multiparameter_attributes_on_time_with_time_zone_aware_attributes_false with_timezone_config default: :local, aware_attributes: false, zone: -28800 do attributes = { diff --git a/activerecord/test/cases/multiple_db_test.rb b/activerecord/test/cases/multiple_db_test.rb index af4183a601..e3bb51bd77 100644 --- a/activerecord/test/cases/multiple_db_test.rb +++ b/activerecord/test/cases/multiple_db_test.rb @@ -1,7 +1,7 @@ require "cases/helper" -require 'models/entrant' -require 'models/bird' -require 'models/course' +require "models/entrant" +require "models/bird" +require "models/course" class MultipleDbTest < ActiveRecord::TestCase self.use_transactional_tests = false @@ -24,6 +24,13 @@ class MultipleDbTest < ActiveRecord::TestCase assert_equal(ActiveRecord::Base.connection, Entrant.connection) end + def test_swapping_the_connection + old_spec_name, Course.connection_specification_name = Course.connection_specification_name, "primary" + assert_equal(Entrant.connection, Course.connection) + ensure + Course.connection_specification_name = old_spec_name + end + def test_find c1 = Course.find(1) assert_equal "Ruby Development", c1.name @@ -53,7 +60,7 @@ class MultipleDbTest < ActiveRecord::TestCase ActiveSupport::Dependencies.clear Object.send(:remove_const, :Course) - require_dependency 'models/course' + require_dependency "models/course" assert Course.connection end @@ -89,8 +96,8 @@ class MultipleDbTest < ActiveRecord::TestCase end def test_connection - assert_equal Entrant.arel_engine.connection, Bird.arel_engine.connection - assert_not_equal Entrant.arel_engine.connection, Course.arel_engine.connection + assert_equal Entrant.arel_engine.connection.object_id, Bird.arel_engine.connection.object_id + assert_not_equal Entrant.arel_engine.connection.object_id, Course.arel_engine.connection.object_id end unless in_memory_db? diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 11fb164d50..a9c3733c20 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -9,11 +9,11 @@ require "models/man" require "models/interest" require "models/owner" require "models/pet" -require 'active_support/hash_with_indifferent_access' +require "active_support/hash_with_indifferent_access" class TestNestedAttributesInGeneral < ActiveRecord::TestCase teardown do - Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc(&:empty?) + Pirate.accepts_nested_attributes_for :ship, allow_destroy: true, reject_if: proc(&:empty?) end def test_base_should_have_an_empty_nested_attributes_options @@ -30,28 +30,28 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase end def test_should_not_build_a_new_record_using_reject_all_even_if_destroy_is_given - pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") - pirate.birds_with_reject_all_blank_attributes = [{:name => '', :color => '', :_destroy => '0'}] + pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") + pirate.birds_with_reject_all_blank_attributes = [{ name: "", color: "", _destroy: "0" }] pirate.save! assert pirate.birds_with_reject_all_blank.empty? end def test_should_not_build_a_new_record_if_reject_all_blank_returns_false - pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") - pirate.birds_with_reject_all_blank_attributes = [{:name => '', :color => ''}] + pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") + pirate.birds_with_reject_all_blank_attributes = [{ name: "", color: "" }] pirate.save! assert pirate.birds_with_reject_all_blank.empty? end def test_should_build_a_new_record_if_reject_all_blank_does_not_return_false - pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") - pirate.birds_with_reject_all_blank_attributes = [{:name => 'Tweetie', :color => ''}] + pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") + pirate.birds_with_reject_all_blank_attributes = [{ name: "Tweetie", color: "" }] pirate.save! assert_equal 1, pirate.birds_with_reject_all_blank.count - assert_equal 'Tweetie', pirate.birds_with_reject_all_blank.first.name + assert_equal "Tweetie", pirate.birds_with_reject_all_blank.first.name end def test_should_raise_an_ArgumentError_for_non_existing_associations @@ -63,7 +63,7 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase def test_should_raise_an_UnknownAttributeError_for_non_existing_nested_attributes exception = assert_raise ActiveModel::UnknownAttributeError do - Pirate.new(:ship_attributes => { :sail => true }) + Pirate.new(ship_attributes: { sail: true }) end assert_equal "unknown attribute 'sail' for Ship.", exception.message end @@ -72,84 +72,84 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase Pirate.accepts_nested_attributes_for :ship pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") - ship = pirate.create_ship(name: 'Nights Dirty Lightning') + ship = pirate.create_ship(name: "Nights Dirty Lightning") - pirate.update(ship_attributes: { '_destroy' => true, :id => ship.id }) + pirate.update(ship_attributes: { "_destroy" => true, :id => ship.id }) assert_nothing_raised { pirate.ship.reload } end def test_a_model_should_respond_to_underscore_destroy_and_return_if_it_is_marked_for_destruction - ship = Ship.create!(:name => 'Nights Dirty Lightning') + ship = Ship.create!(name: "Nights Dirty Lightning") assert !ship._destroy ship.mark_for_destruction assert ship._destroy end def test_reject_if_method_without_arguments - Pirate.accepts_nested_attributes_for :ship, :reject_if => :new_record? + Pirate.accepts_nested_attributes_for :ship, reject_if: :new_record? - pirate = Pirate.new(:catchphrase => "Stop wastin' me time") - pirate.ship_attributes = { :name => 'Black Pearl' } - assert_no_difference('Ship.count') { pirate.save! } + pirate = Pirate.new(catchphrase: "Stop wastin' me time") + pirate.ship_attributes = { name: "Black Pearl" } + assert_no_difference("Ship.count") { pirate.save! } end def test_reject_if_method_with_arguments - Pirate.accepts_nested_attributes_for :ship, :reject_if => :reject_empty_ships_on_create + Pirate.accepts_nested_attributes_for :ship, reject_if: :reject_empty_ships_on_create - pirate = Pirate.new(:catchphrase => "Stop wastin' me time") - pirate.ship_attributes = { :name => 'Red Pearl', :_reject_me_if_new => true } - assert_no_difference('Ship.count') { pirate.save! } + pirate = Pirate.new(catchphrase: "Stop wastin' me time") + pirate.ship_attributes = { name: "Red Pearl", _reject_me_if_new: true } + assert_no_difference("Ship.count") { pirate.save! } # pirate.reject_empty_ships_on_create returns false for saved pirate records # in the previous step note that pirate gets saved but ship fails - pirate.ship_attributes = { :name => 'Red Pearl', :_reject_me_if_new => true } - assert_difference('Ship.count') { pirate.save! } + pirate.ship_attributes = { name: "Red Pearl", _reject_me_if_new: true } + assert_difference("Ship.count") { pirate.save! } end def test_reject_if_with_indifferent_keys - Pirate.accepts_nested_attributes_for :ship, :reject_if => proc {|attributes| attributes[:name].blank? } + Pirate.accepts_nested_attributes_for :ship, reject_if: proc { |attributes| attributes[:name].blank? } - pirate = Pirate.new(:catchphrase => "Stop wastin' me time") - pirate.ship_attributes = { :name => 'Hello Pearl' } - assert_difference('Ship.count') { pirate.save! } + pirate = Pirate.new(catchphrase: "Stop wastin' me time") + pirate.ship_attributes = { name: "Hello Pearl" } + assert_difference("Ship.count") { pirate.save! } end def test_reject_if_with_a_proc_which_returns_true_always_for_has_one - Pirate.accepts_nested_attributes_for :ship, :reject_if => proc {|attributes| true } + Pirate.accepts_nested_attributes_for :ship, reject_if: proc { |attributes| true } pirate = Pirate.new(catchphrase: "Stop wastin' me time") - ship = pirate.create_ship(name: 's1') - pirate.update({ship_attributes: { name: 's2', id: ship.id } }) - assert_equal 's1', ship.reload.name + ship = pirate.create_ship(name: "s1") + pirate.update(ship_attributes: { name: "s2", id: ship.id }) + assert_equal "s1", ship.reload.name end def test_reuse_already_built_new_record pirate = Pirate.new ship_built_first = pirate.build_ship - pirate.ship_attributes = { name: 'Ship 1' } + pirate.ship_attributes = { name: "Ship 1" } assert_equal ship_built_first.object_id, pirate.ship.object_id end def test_do_not_allow_assigning_foreign_key_when_reusing_existing_new_record pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") pirate.build_ship - pirate.ship_attributes = { name: 'Ship 1', pirate_id: pirate.id + 1 } + pirate.ship_attributes = { name: "Ship 1", pirate_id: pirate.id + 1 } assert_equal pirate.id, pirate.ship.pirate_id end def test_reject_if_with_a_proc_which_returns_true_always_for_has_many - Man.accepts_nested_attributes_for :interests, :reject_if => proc {|attributes| true } + Man.accepts_nested_attributes_for :interests, reject_if: proc { |attributes| true } man = Man.create(name: "John") - interest = man.interests.create(topic: 'photography') - man.update({interests_attributes: { topic: 'gardening', id: interest.id } }) - assert_equal 'photography', interest.reload.topic + interest = man.interests.create(topic: "photography") + man.update(interests_attributes: { topic: "gardening", id: interest.id }) + assert_equal "photography", interest.reload.topic end def test_destroy_works_independent_of_reject_if - Man.accepts_nested_attributes_for :interests, :reject_if => proc {|attributes| true }, :allow_destroy => true + Man.accepts_nested_attributes_for :interests, reject_if: proc { |attributes| true }, allow_destroy: true man = Man.create(name: "Jon") - interest = man.interests.create(topic: 'the ladies') - man.update({interests_attributes: { _destroy: "1", id: interest.id } }) + interest = man.interests.create(topic: "the ladies") + man.update(interests_attributes: { _destroy: "1", id: interest.id }) assert man.reload.interests.empty? end @@ -168,27 +168,27 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase def test_has_many_association_updating_a_single_record Man.accepts_nested_attributes_for(:interests) - man = Man.create(name: 'John') - interest = man.interests.create(topic: 'photography') - man.update({interests_attributes: {topic: 'gardening', id: interest.id}}) - assert_equal 'gardening', interest.reload.topic + man = Man.create(name: "John") + interest = man.interests.create(topic: "photography") + man.update(interests_attributes: { topic: "gardening", id: interest.id }) + assert_equal "gardening", interest.reload.topic end def test_reject_if_with_blank_nested_attributes_id # When using a select list to choose an existing 'ship' id, with include_blank: true - Pirate.accepts_nested_attributes_for :ship, :reject_if => proc {|attributes| attributes[:id].blank? } + Pirate.accepts_nested_attributes_for :ship, reject_if: proc { |attributes| attributes[:id].blank? } - pirate = Pirate.new(:catchphrase => "Stop wastin' me time") - pirate.ship_attributes = { :id => "" } + pirate = Pirate.new(catchphrase: "Stop wastin' me time") + pirate.ship_attributes = { id: "" } assert_nothing_raised { pirate.save! } end def test_first_and_array_index_zero_methods_return_the_same_value_when_nested_attributes_are_set_to_update_existing_record Man.accepts_nested_attributes_for(:interests) - man = Man.create(:name => "John") - interest = man.interests.create :topic => 'gardening' + man = Man.create(name: "John") + interest = man.interests.create topic: "gardening" man = Man.find man.id - man.interests_attributes = [{:id => interest.id, :topic => 'gardening'}] + man.interests_attributes = [{ id: interest.id, topic: "gardening" }] assert_equal man.interests.first.topic, man.interests[0].topic end @@ -196,11 +196,11 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase mean_pirate_class = Class.new(Pirate) do accepts_nested_attributes_for :parrot def parrot_attributes=(attrs) - super(attrs.merge(:color => "blue")) + super(attrs.merge(color: "blue")) end end mean_pirate = mean_pirate_class.new - mean_pirate.parrot_attributes = { :name => "James" } + mean_pirate.parrot_attributes = { name: "James" } assert_equal "James", mean_pirate.parrot.name assert_equal "blue", mean_pirate.parrot.color end @@ -212,20 +212,20 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase accepts_nested_attributes_for :parrot end mean_pirate = mean_pirate_class.new - mean_pirate.parrot_attributes = { :name => "James" } + mean_pirate.parrot_attributes = { name: "James" } assert_equal "James", mean_pirate.parrot.name end end class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase def setup - @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @ship = @pirate.create_ship(:name => 'Nights Dirty Lightning') + @pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") + @ship = @pirate.create_ship(name: "Nights Dirty Lightning") end def test_should_raise_argument_error_if_trying_to_build_polymorphic_belongs_to exception = assert_raise ArgumentError do - Treasure.new(:name => 'pearl', :looter_attributes => {:catchphrase => "Arrr"}) + Treasure.new(name: "pearl", looter_attributes: { catchphrase: "Arrr" }) end assert_equal "Cannot build association `looter'. Are you trying to build a polymorphic one-to-one association?", exception.message end @@ -236,15 +236,15 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase def test_should_build_a_new_record_if_there_is_no_id @ship.destroy - @pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger' } + @pirate.reload.ship_attributes = { name: "Davy Jones Gold Dagger" } assert !@pirate.ship.persisted? - assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name + assert_equal "Davy Jones Gold Dagger", @pirate.ship.name end def test_should_not_build_a_new_record_if_there_is_no_id_and_destroy_is_truthy @ship.destroy - @pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger', :_destroy => '1' } + @pirate.reload.ship_attributes = { name: "Davy Jones Gold Dagger", _destroy: "1" } assert_nil @pirate.ship end @@ -257,54 +257,54 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_replace_an_existing_record_if_there_is_no_id - @pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger' } + @pirate.reload.ship_attributes = { name: "Davy Jones Gold Dagger" } assert !@pirate.ship.persisted? - assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name - assert_equal 'Nights Dirty Lightning', @ship.name + assert_equal "Davy Jones Gold Dagger", @pirate.ship.name + assert_equal "Nights Dirty Lightning", @ship.name end def test_should_not_replace_an_existing_record_if_there_is_no_id_and_destroy_is_truthy - @pirate.reload.ship_attributes = { :name => 'Davy Jones Gold Dagger', :_destroy => '1' } + @pirate.reload.ship_attributes = { name: "Davy Jones Gold Dagger", _destroy: "1" } assert_equal @ship, @pirate.ship - assert_equal 'Nights Dirty Lightning', @pirate.ship.name + assert_equal "Nights Dirty Lightning", @pirate.ship.name end def test_should_modify_an_existing_record_if_there_is_a_matching_id - @pirate.reload.ship_attributes = { :id => @ship.id, :name => 'Davy Jones Gold Dagger' } + @pirate.reload.ship_attributes = { id: @ship.id, name: "Davy Jones Gold Dagger" } assert_equal @ship, @pirate.ship - assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name + assert_equal "Davy Jones Gold Dagger", @pirate.ship.name end def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record exception = assert_raise ActiveRecord::RecordNotFound do - @pirate.ship_attributes = { :id => 1234567890 } + @pirate.ship_attributes = { id: 1234567890 } end assert_equal "Couldn't find Ship with ID=1234567890 for Pirate with ID=#{@pirate.id}", exception.message end def test_should_take_a_hash_with_string_keys_and_update_the_associated_model - @pirate.reload.ship_attributes = { 'id' => @ship.id, 'name' => 'Davy Jones Gold Dagger' } + @pirate.reload.ship_attributes = { "id" => @ship.id, "name" => "Davy Jones Gold Dagger" } assert_equal @ship, @pirate.ship - assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name + assert_equal "Davy Jones Gold Dagger", @pirate.ship.name end def test_should_modify_an_existing_record_if_there_is_a_matching_composite_id - @ship.stub(:id, 'ABC1X') do - @pirate.ship_attributes = { :id => @ship.id, :name => 'Davy Jones Gold Dagger' } + @ship.stub(:id, "ABC1X") do + @pirate.ship_attributes = { id: @ship.id, name: "Davy Jones Gold Dagger" } - assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name + assert_equal "Davy Jones Gold Dagger", @pirate.ship.name end end def test_should_destroy_an_existing_record_if_there_is_a_matching_id_and_destroy_is_truthy @pirate.ship.destroy - [1, '1', true, 'true'].each do |truth| - ship = @pirate.reload.create_ship(name: 'Mister Pablo') + [1, "1", true, "true"].each do |truth| + ship = @pirate.reload.create_ship(name: "Mister Pablo") @pirate.update(ship_attributes: { id: ship.id, _destroy: truth }) assert_nil @pirate.reload.ship @@ -313,7 +313,7 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_not_destroy_an_existing_record_if_destroy_is_not_truthy - [nil, '0', 0, 'false', false].each do |not_truth| + [nil, "0", 0, "false", false].each do |not_truth| @pirate.update(ship_attributes: { id: @pirate.ship.id, _destroy: not_truth }) assert_equal @ship, @pirate.reload.ship @@ -321,32 +321,32 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_not_destroy_an_existing_record_if_allow_destroy_is_false - Pirate.accepts_nested_attributes_for :ship, :allow_destroy => false, :reject_if => proc(&:empty?) + Pirate.accepts_nested_attributes_for :ship, allow_destroy: false, reject_if: proc(&:empty?) - @pirate.update(ship_attributes: { id: @pirate.ship.id, _destroy: '1' }) + @pirate.update(ship_attributes: { id: @pirate.ship.id, _destroy: "1" }) assert_equal @ship, @pirate.reload.ship - Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc(&:empty?) + Pirate.accepts_nested_attributes_for :ship, allow_destroy: true, reject_if: proc(&:empty?) end def test_should_also_work_with_a_HashWithIndifferentAccess - @pirate.ship_attributes = ActiveSupport::HashWithIndifferentAccess.new(:id => @ship.id, :name => 'Davy Jones Gold Dagger') + @pirate.ship_attributes = ActiveSupport::HashWithIndifferentAccess.new(id: @ship.id, name: "Davy Jones Gold Dagger") assert @pirate.ship.persisted? - assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name + assert_equal "Davy Jones Gold Dagger", @pirate.ship.name end def test_should_work_with_update_as_well - @pirate.update({ catchphrase: 'Arr', ship_attributes: { id: @ship.id, name: 'Mister Pablo' } }) + @pirate.update(catchphrase: "Arr", ship_attributes: { id: @ship.id, name: "Mister Pablo" }) @pirate.reload - assert_equal 'Arr', @pirate.catchphrase - assert_equal 'Mister Pablo', @pirate.ship.name + assert_equal "Arr", @pirate.catchphrase + assert_equal "Mister Pablo", @pirate.ship.name end def test_should_not_destroy_the_associated_model_until_the_parent_is_saved - @pirate.attributes = { :ship_attributes => { :id => @ship.id, :_destroy => '1' } } + @pirate.attributes = { ship_attributes: { id: @ship.id, _destroy: "1" } } assert !@pirate.ship.destroyed? assert @pirate.ship.marked_for_destruction? @@ -362,56 +362,55 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase end def test_should_accept_update_only_option - @pirate.update(update_only_ship_attributes: { id: @pirate.ship.id, name: 'Mayflower' }) + @pirate.update(update_only_ship_attributes: { id: @pirate.ship.id, name: "Mayflower" }) end def test_should_create_new_model_when_nothing_is_there_and_update_only_is_true @ship.delete - @pirate.reload.update(update_only_ship_attributes: { name: 'Mayflower' }) + @pirate.reload.update(update_only_ship_attributes: { name: "Mayflower" }) assert_not_nil @pirate.ship end def test_should_update_existing_when_update_only_is_true_and_no_id_is_given @ship.delete - @ship = @pirate.create_update_only_ship(name: 'Nights Dirty Lightning') + @ship = @pirate.create_update_only_ship(name: "Nights Dirty Lightning") - @pirate.update(update_only_ship_attributes: { name: 'Mayflower' }) + @pirate.update(update_only_ship_attributes: { name: "Mayflower" }) - assert_equal 'Mayflower', @ship.reload.name + assert_equal "Mayflower", @ship.reload.name assert_equal @ship, @pirate.reload.ship end def test_should_update_existing_when_update_only_is_true_and_id_is_given @ship.delete - @ship = @pirate.create_update_only_ship(name: 'Nights Dirty Lightning') + @ship = @pirate.create_update_only_ship(name: "Nights Dirty Lightning") - @pirate.update(update_only_ship_attributes: { name: 'Mayflower', id: @ship.id }) + @pirate.update(update_only_ship_attributes: { name: "Mayflower", id: @ship.id }) - assert_equal 'Mayflower', @ship.reload.name + assert_equal "Mayflower", @ship.reload.name assert_equal @ship, @pirate.reload.ship end def test_should_destroy_existing_when_update_only_is_true_and_id_is_given_and_is_marked_for_destruction - Pirate.accepts_nested_attributes_for :update_only_ship, :update_only => true, :allow_destroy => true + Pirate.accepts_nested_attributes_for :update_only_ship, update_only: true, allow_destroy: true @ship.delete - @ship = @pirate.create_update_only_ship(name: 'Nights Dirty Lightning') + @ship = @pirate.create_update_only_ship(name: "Nights Dirty Lightning") - @pirate.update(update_only_ship_attributes: { name: 'Mayflower', id: @ship.id, _destroy: true }) + @pirate.update(update_only_ship_attributes: { name: "Mayflower", id: @ship.id, _destroy: true }) assert_nil @pirate.reload.ship assert_raise(ActiveRecord::RecordNotFound) { Ship.find(@ship.id) } - Pirate.accepts_nested_attributes_for :update_only_ship, :update_only => true, :allow_destroy => false + Pirate.accepts_nested_attributes_for :update_only_ship, update_only: true, allow_destroy: false end - end class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase def setup - @ship = Ship.new(:name => 'Nights Dirty Lightning') - @pirate = @ship.build_pirate(:catchphrase => 'Aye') + @ship = Ship.new(name: "Nights Dirty Lightning") + @pirate = @ship.build_pirate(catchphrase: "Aye") @ship.save! end @@ -421,15 +420,15 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase def test_should_build_a_new_record_if_there_is_no_id @pirate.destroy - @ship.reload.pirate_attributes = { :catchphrase => 'Arr' } + @ship.reload.pirate_attributes = { catchphrase: "Arr" } assert !@ship.pirate.persisted? - assert_equal 'Arr', @ship.pirate.catchphrase + assert_equal "Arr", @ship.pirate.catchphrase end def test_should_not_build_a_new_record_if_there_is_no_id_and_destroy_is_truthy @pirate.destroy - @ship.reload.pirate_attributes = { :catchphrase => 'Arr', :_destroy => '1' } + @ship.reload.pirate_attributes = { catchphrase: "Arr", _destroy: "1" } assert_nil @ship.pirate end @@ -442,53 +441,53 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase end def test_should_replace_an_existing_record_if_there_is_no_id - @ship.reload.pirate_attributes = { :catchphrase => 'Arr' } + @ship.reload.pirate_attributes = { catchphrase: "Arr" } assert !@ship.pirate.persisted? - assert_equal 'Arr', @ship.pirate.catchphrase - assert_equal 'Aye', @pirate.catchphrase + assert_equal "Arr", @ship.pirate.catchphrase + assert_equal "Aye", @pirate.catchphrase end def test_should_not_replace_an_existing_record_if_there_is_no_id_and_destroy_is_truthy - @ship.reload.pirate_attributes = { :catchphrase => 'Arr', :_destroy => '1' } + @ship.reload.pirate_attributes = { catchphrase: "Arr", _destroy: "1" } assert_equal @pirate, @ship.pirate - assert_equal 'Aye', @ship.pirate.catchphrase + assert_equal "Aye", @ship.pirate.catchphrase end def test_should_modify_an_existing_record_if_there_is_a_matching_id - @ship.reload.pirate_attributes = { :id => @pirate.id, :catchphrase => 'Arr' } + @ship.reload.pirate_attributes = { id: @pirate.id, catchphrase: "Arr" } assert_equal @pirate, @ship.pirate - assert_equal 'Arr', @ship.pirate.catchphrase + assert_equal "Arr", @ship.pirate.catchphrase end def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record exception = assert_raise ActiveRecord::RecordNotFound do - @ship.pirate_attributes = { :id => 1234567890 } + @ship.pirate_attributes = { id: 1234567890 } end assert_equal "Couldn't find Pirate with ID=1234567890 for Ship with ID=#{@ship.id}", exception.message end def test_should_take_a_hash_with_string_keys_and_update_the_associated_model - @ship.reload.pirate_attributes = { 'id' => @pirate.id, 'catchphrase' => 'Arr' } + @ship.reload.pirate_attributes = { "id" => @pirate.id, "catchphrase" => "Arr" } assert_equal @pirate, @ship.pirate - assert_equal 'Arr', @ship.pirate.catchphrase + assert_equal "Arr", @ship.pirate.catchphrase end def test_should_modify_an_existing_record_if_there_is_a_matching_composite_id - @pirate.stub(:id, 'ABC1X') do - @ship.pirate_attributes = { :id => @pirate.id, :catchphrase => 'Arr' } + @pirate.stub(:id, "ABC1X") do + @ship.pirate_attributes = { id: @pirate.id, catchphrase: "Arr" } - assert_equal 'Arr', @ship.pirate.catchphrase + assert_equal "Arr", @ship.pirate.catchphrase end end def test_should_destroy_an_existing_record_if_there_is_a_matching_id_and_destroy_is_truthy @ship.pirate.destroy - [1, '1', true, 'true'].each do |truth| - pirate = @ship.reload.create_pirate(catchphrase: 'Arr') + [1, "1", true, "true"].each do |truth| + pirate = @ship.reload.create_pirate(catchphrase: "Arr") @ship.update(pirate_attributes: { id: pirate.id, _destroy: truth }) assert_raise(ActiveRecord::RecordNotFound) { pirate.reload } end @@ -509,33 +508,33 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase end def test_should_not_destroy_an_existing_record_if_destroy_is_not_truthy - [nil, '0', 0, 'false', false].each do |not_truth| + [nil, "0", 0, "false", false].each do |not_truth| @ship.update(pirate_attributes: { id: @ship.pirate.id, _destroy: not_truth }) assert_nothing_raised { @ship.pirate.reload } end end def test_should_not_destroy_an_existing_record_if_allow_destroy_is_false - Ship.accepts_nested_attributes_for :pirate, :allow_destroy => false, :reject_if => proc(&:empty?) + Ship.accepts_nested_attributes_for :pirate, allow_destroy: false, reject_if: proc(&:empty?) - @ship.update(pirate_attributes: { id: @ship.pirate.id, _destroy: '1' }) + @ship.update(pirate_attributes: { id: @ship.pirate.id, _destroy: "1" }) assert_nothing_raised { @ship.pirate.reload } ensure - Ship.accepts_nested_attributes_for :pirate, :allow_destroy => true, :reject_if => proc(&:empty?) + Ship.accepts_nested_attributes_for :pirate, allow_destroy: true, reject_if: proc(&:empty?) end def test_should_work_with_update_as_well - @ship.update({ name: 'Mister Pablo', pirate_attributes: { catchphrase: 'Arr' } }) + @ship.update(name: "Mister Pablo", pirate_attributes: { catchphrase: "Arr" }) @ship.reload - assert_equal 'Mister Pablo', @ship.name - assert_equal 'Arr', @ship.pirate.catchphrase + assert_equal "Mister Pablo", @ship.name + assert_equal "Arr", @ship.pirate.catchphrase end def test_should_not_destroy_the_associated_model_until_the_parent_is_saved pirate = @ship.pirate - @ship.attributes = { :pirate_attributes => { :id => pirate.id, '_destroy' => true } } + @ship.attributes = { pirate_attributes: { :id => pirate.id, "_destroy" => true } } assert_nothing_raised { Pirate.find(pirate.id) } @ship.save assert_raise(ActiveRecord::RecordNotFound) { Pirate.find(pirate.id) } @@ -547,40 +546,40 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase def test_should_create_new_model_when_nothing_is_there_and_update_only_is_true @pirate.delete - @ship.reload.attributes = { :update_only_pirate_attributes => { :catchphrase => 'Arr' } } + @ship.reload.attributes = { update_only_pirate_attributes: { catchphrase: "Arr" } } assert !@ship.update_only_pirate.persisted? end def test_should_update_existing_when_update_only_is_true_and_no_id_is_given @pirate.delete - @pirate = @ship.create_update_only_pirate(catchphrase: 'Aye') + @pirate = @ship.create_update_only_pirate(catchphrase: "Aye") - @ship.update(update_only_pirate_attributes: { catchphrase: 'Arr' }) - assert_equal 'Arr', @pirate.reload.catchphrase + @ship.update(update_only_pirate_attributes: { catchphrase: "Arr" }) + assert_equal "Arr", @pirate.reload.catchphrase assert_equal @pirate, @ship.reload.update_only_pirate end def test_should_update_existing_when_update_only_is_true_and_id_is_given @pirate.delete - @pirate = @ship.create_update_only_pirate(catchphrase: 'Aye') + @pirate = @ship.create_update_only_pirate(catchphrase: "Aye") - @ship.update(update_only_pirate_attributes: { catchphrase: 'Arr', id: @pirate.id }) + @ship.update(update_only_pirate_attributes: { catchphrase: "Arr", id: @pirate.id }) - assert_equal 'Arr', @pirate.reload.catchphrase + assert_equal "Arr", @pirate.reload.catchphrase assert_equal @pirate, @ship.reload.update_only_pirate end def test_should_destroy_existing_when_update_only_is_true_and_id_is_given_and_is_marked_for_destruction - Ship.accepts_nested_attributes_for :update_only_pirate, :update_only => true, :allow_destroy => true + Ship.accepts_nested_attributes_for :update_only_pirate, update_only: true, allow_destroy: true @pirate.delete - @pirate = @ship.create_update_only_pirate(catchphrase: 'Aye') + @pirate = @ship.create_update_only_pirate(catchphrase: "Aye") - @ship.update(update_only_pirate_attributes: { catchphrase: 'Arr', id: @pirate.id, _destroy: true }) + @ship.update(update_only_pirate_attributes: { catchphrase: "Arr", id: @pirate.id, _destroy: true }) assert_raise(ActiveRecord::RecordNotFound) { @pirate.reload } - Ship.accepts_nested_attributes_for :update_only_pirate, :update_only => true, :allow_destroy => false + Ship.accepts_nested_attributes_for :update_only_pirate, update_only: true, allow_destroy: false end end @@ -597,10 +596,9 @@ module NestedAttributesOnACollectionAssociationTests end def test_should_save_only_one_association_on_create - pirate = Pirate.create!({ - :catchphrase => 'Arr', - association_getter => { 'foo' => { :name => 'Grace OMalley' } } - }) + pirate = Pirate.create!( + :catchphrase => "Arr", + association_getter => { "foo" => { name: "Grace OMalley" } }) assert_equal 1, pirate.reload.send(@association_name).count end @@ -608,90 +606,90 @@ module NestedAttributesOnACollectionAssociationTests def test_should_take_a_hash_with_string_keys_and_assign_the_attributes_to_the_associated_models @alternate_params[association_getter].stringify_keys! @pirate.update @alternate_params - assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.reload.name, @child_2.reload.name] + assert_equal ["Grace OMalley", "Privateers Greed"], [@child_1.reload.name, @child_2.reload.name] end def test_should_take_an_array_and_assign_the_attributes_to_the_associated_models @pirate.send(association_setter, @alternate_params[association_getter].values) @pirate.save - assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.reload.name, @child_2.reload.name] + assert_equal ["Grace OMalley", "Privateers Greed"], [@child_1.reload.name, @child_2.reload.name] end def test_should_also_work_with_a_HashWithIndifferentAccess - @pirate.send(association_setter, ActiveSupport::HashWithIndifferentAccess.new('foo' => ActiveSupport::HashWithIndifferentAccess.new(:id => @child_1.id, :name => 'Grace OMalley'))) + @pirate.send(association_setter, ActiveSupport::HashWithIndifferentAccess.new("foo" => ActiveSupport::HashWithIndifferentAccess.new(id: @child_1.id, name: "Grace OMalley"))) @pirate.save - assert_equal 'Grace OMalley', @child_1.reload.name + assert_equal "Grace OMalley", @child_1.reload.name end def test_should_take_a_hash_and_assign_the_attributes_to_the_associated_models @pirate.attributes = @alternate_params - assert_equal 'Grace OMalley', @pirate.send(@association_name).first.name - assert_equal 'Privateers Greed', @pirate.send(@association_name).last.name + assert_equal "Grace OMalley", @pirate.send(@association_name).first.name + assert_equal "Privateers Greed", @pirate.send(@association_name).last.name end def test_should_not_load_association_when_updating_existing_records @pirate.reload - @pirate.send(association_setter, [{ :id => @child_1.id, :name => 'Grace OMalley' }]) + @pirate.send(association_setter, [{ id: @child_1.id, name: "Grace OMalley" }]) assert ! @pirate.send(@association_name).loaded? @pirate.save assert ! @pirate.send(@association_name).loaded? - assert_equal 'Grace OMalley', @child_1.reload.name + assert_equal "Grace OMalley", @child_1.reload.name end def test_should_not_overwrite_unsaved_updates_when_loading_association @pirate.reload - @pirate.send(association_setter, [{ :id => @child_1.id, :name => 'Grace OMalley' }]) - assert_equal 'Grace OMalley', @pirate.send(@association_name).send(:load_target).find { |r| r.id == @child_1.id }.name + @pirate.send(association_setter, [{ id: @child_1.id, name: "Grace OMalley" }]) + assert_equal "Grace OMalley", @pirate.send(@association_name).load_target.find { |r| r.id == @child_1.id }.name end def test_should_preserve_order_when_not_overwriting_unsaved_updates @pirate.reload - @pirate.send(association_setter, [{ :id => @child_1.id, :name => 'Grace OMalley' }]) - assert_equal @child_1.id, @pirate.send(@association_name).send(:load_target).first.id + @pirate.send(association_setter, [{ id: @child_1.id, name: "Grace OMalley" }]) + assert_equal @child_1.id, @pirate.send(@association_name).load_target.first.id end def test_should_refresh_saved_records_when_not_overwriting_unsaved_updates @pirate.reload - record = @pirate.class.reflect_on_association(@association_name).klass.new(name: 'Grace OMalley') + record = @pirate.class.reflect_on_association(@association_name).klass.new(name: "Grace OMalley") @pirate.send(@association_name) << record record.save! - @pirate.send(@association_name).last.update!(name: 'Polly') - assert_equal 'Polly', @pirate.send(@association_name).send(:load_target).last.name + @pirate.send(@association_name).last.update!(name: "Polly") + assert_equal "Polly", @pirate.send(@association_name).load_target.last.name end def test_should_not_remove_scheduled_destroys_when_loading_association @pirate.reload - @pirate.send(association_setter, [{ :id => @child_1.id, :_destroy => '1' }]) - assert @pirate.send(@association_name).send(:load_target).find { |r| r.id == @child_1.id }.marked_for_destruction? + @pirate.send(association_setter, [{ id: @child_1.id, _destroy: "1" }]) + assert @pirate.send(@association_name).load_target.find { |r| r.id == @child_1.id }.marked_for_destruction? end def test_should_take_a_hash_with_composite_id_keys_and_assign_the_attributes_to_the_associated_models - @child_1.stub(:id, 'ABC1X') do - @child_2.stub(:id, 'ABC2X') do + @child_1.stub(:id, "ABC1X") do + @child_2.stub(:id, "ABC2X") do @pirate.attributes = { association_getter => [ - { :id => @child_1.id, :name => 'Grace OMalley' }, - { :id => @child_2.id, :name => 'Privateers Greed' } + { id: @child_1.id, name: "Grace OMalley" }, + { id: @child_2.id, name: "Privateers Greed" } ] } - assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.name, @child_2.name] + assert_equal ["Grace OMalley", "Privateers Greed"], [@child_1.name, @child_2.name] end end end def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record exception = assert_raise ActiveRecord::RecordNotFound do - @pirate.attributes = { association_getter => [{ :id => 1234567890 }] } + @pirate.attributes = { association_getter => [{ id: 1234567890 }] } end assert_equal "Couldn't find #{@child_1.class.name} with ID=1234567890 for Pirate with ID=#{@pirate.id}", exception.message end def test_should_raise_RecordNotFound_if_an_id_belonging_to_a_different_record_is_given - other_pirate = Pirate.create! catchphrase: 'Ahoy!' - other_child = other_pirate.send(@association_name).create! name: 'Buccaneers Servant' + other_pirate = Pirate.create! catchphrase: "Ahoy!" + other_child = other_pirate.send(@association_name).create! name: "Buccaneers Servant" exception = assert_raise ActiveRecord::RecordNotFound do @pirate.attributes = { association_getter => [{ id: other_child.id }] } @@ -702,19 +700,19 @@ module NestedAttributesOnACollectionAssociationTests def test_should_automatically_build_new_associated_models_for_each_entry_in_a_hash_where_the_id_is_missing @pirate.send(@association_name).destroy_all @pirate.reload.attributes = { - association_getter => { 'foo' => { :name => 'Grace OMalley' }, 'bar' => { :name => 'Privateers Greed' }} + association_getter => { "foo" => { name: "Grace OMalley" }, "bar" => { name: "Privateers Greed" } } } assert !@pirate.send(@association_name).first.persisted? - assert_equal 'Grace OMalley', @pirate.send(@association_name).first.name + assert_equal "Grace OMalley", @pirate.send(@association_name).first.name assert !@pirate.send(@association_name).last.persisted? - assert_equal 'Privateers Greed', @pirate.send(@association_name).last.name + assert_equal "Privateers Greed", @pirate.send(@association_name).last.name end def test_should_not_assign_destroy_key_to_a_record assert_nothing_raised do - @pirate.send(association_setter, { 'foo' => { '_destroy' => '0' }}) + @pirate.send(association_setter, "foo" => { "_destroy" => "0" }) end end @@ -722,17 +720,17 @@ module NestedAttributesOnACollectionAssociationTests @pirate.send(@association_name).destroy_all @pirate.reload.attributes = { association_getter => { - 'foo' => { :name => 'Grace OMalley' }, - 'bar' => { :name => 'Privateers Greed', '_destroy' => '1' } + "foo" => { name: "Grace OMalley" }, + "bar" => { :name => "Privateers Greed", "_destroy" => "1" } } } assert_equal 1, @pirate.send(@association_name).length - assert_equal 'Grace OMalley', @pirate.send(@association_name).first.name + assert_equal "Grace OMalley", @pirate.send(@association_name).first.name end def test_should_ignore_new_associated_records_if_a_reject_if_proc_returns_false - @alternate_params[association_getter]['baz'] = {} + @alternate_params[association_getter]["baz"] = {} assert_no_difference("@pirate.send(@association_name).count") do @pirate.attributes = @alternate_params end @@ -740,11 +738,11 @@ module NestedAttributesOnACollectionAssociationTests def test_should_sort_the_hash_by_the_keys_before_building_new_associated_models attributes = {} - attributes['123726353'] = { :name => 'Grace OMalley' } - attributes['2'] = { :name => 'Privateers Greed' } # 2 is lower then 123726353 + attributes["123726353"] = { name: "Grace OMalley" } + attributes["2"] = { name: "Privateers Greed" } # 2 is lower then 123726353 @pirate.send(association_setter, attributes) - assert_equal ['Posideons Killer', 'Killer bandita Dionne', 'Privateers Greed', 'Grace OMalley'].to_set, @pirate.send(@association_name).map(&:name).to_set + assert_equal ["Posideons Killer", "Killer bandita Dionne", "Privateers Greed", "Grace OMalley"].to_set, @pirate.send(@association_name).map(&:name).to_set end def test_should_raise_an_argument_error_if_something_else_than_a_hash_is_passed @@ -758,47 +756,47 @@ module NestedAttributesOnACollectionAssociationTests end def test_should_work_with_update_as_well - @pirate.update(catchphrase: 'Arr', - association_getter => { 'foo' => { :id => @child_1.id, :name => 'Grace OMalley' }}) + @pirate.update(catchphrase: "Arr", + association_getter => { "foo" => { id: @child_1.id, name: "Grace OMalley" } }) - assert_equal 'Grace OMalley', @child_1.reload.name + assert_equal "Grace OMalley", @child_1.reload.name end def test_should_update_existing_records_and_add_new_ones_that_have_no_id - @alternate_params[association_getter]['baz'] = { name: 'Buccaneers Servant' } - assert_difference('@pirate.send(@association_name).count', +1) do + @alternate_params[association_getter]["baz"] = { name: "Buccaneers Servant" } + assert_difference("@pirate.send(@association_name).count", +1) do @pirate.update @alternate_params end - assert_equal ['Grace OMalley', 'Privateers Greed', 'Buccaneers Servant'].to_set, @pirate.reload.send(@association_name).map(&:name).to_set + assert_equal ["Grace OMalley", "Privateers Greed", "Buccaneers Servant"].to_set, @pirate.reload.send(@association_name).map(&:name).to_set end def test_should_be_possible_to_destroy_a_record - ['1', 1, 'true', true].each do |true_variable| - record = @pirate.reload.send(@association_name).create!(:name => 'Grace OMalley') + ["1", 1, "true", true].each do |true_variable| + record = @pirate.reload.send(@association_name).create!(name: "Grace OMalley") @pirate.send(association_setter, - @alternate_params[association_getter].merge('baz' => { :id => record.id, '_destroy' => true_variable }) + @alternate_params[association_getter].merge("baz" => { :id => record.id, "_destroy" => true_variable }) ) - assert_difference('@pirate.send(@association_name).count', -1) do + assert_difference("@pirate.send(@association_name).count", -1) do @pirate.save end end end def test_should_not_destroy_the_associated_model_with_a_non_truthy_argument - [nil, '', '0', 0, 'false', false].each do |false_variable| - @alternate_params[association_getter]['foo']['_destroy'] = false_variable - assert_no_difference('@pirate.send(@association_name).count') do + [nil, "", "0", 0, "false", false].each do |false_variable| + @alternate_params[association_getter]["foo"]["_destroy"] = false_variable + assert_no_difference("@pirate.send(@association_name).count") do @pirate.update(@alternate_params) end end end def test_should_not_destroy_the_associated_model_until_the_parent_is_saved - assert_no_difference('@pirate.send(@association_name).count') do - @pirate.send(association_setter, @alternate_params[association_getter].merge('baz' => { :id => @child_1.id, '_destroy' => true })) + assert_no_difference("@pirate.send(@association_name).count") do + @pirate.send(association_setter, @alternate_params[association_getter].merge("baz" => { :id => @child_1.id, "_destroy" => true })) end - assert_difference('@pirate.send(@association_name).count', -1) { @pirate.save } + assert_difference("@pirate.send(@association_name).count", -1) { @pirate.save } end def test_should_automatically_enable_autosave_on_the_association @@ -812,10 +810,10 @@ module NestedAttributesOnACollectionAssociationTests repair_validations(Interest) do Interest.validates_presence_of(:man) - assert_difference 'Man.count' do - assert_difference 'Interest.count', 2 do - man = Man.create!(:name => 'John', - :interests_attributes => [{:topic=>'Cars'}, {:topic=>'Sports'}]) + assert_difference "Man.count" do + assert_difference "Interest.count", 2 do + man = Man.create!(name: "John", + interests_attributes: [{ topic: "Cars" }, { topic: "Sports" }]) assert_equal 2, man.interests.count end end @@ -823,7 +821,7 @@ module NestedAttributesOnACollectionAssociationTests end def test_can_use_symbols_as_object_identifier - @pirate.attributes = { :parrots_attributes => { :foo => { :name => 'Lovely Day' }, :bar => { :name => 'Blown Away' } } } + @pirate.attributes = { parrots_attributes: { foo: { name: "Lovely Day" }, bar: { name: "Blown Away" } } } assert_nothing_raised { @pirate.save! } end @@ -832,22 +830,22 @@ module NestedAttributesOnACollectionAssociationTests repair_validations(Interest) do Interest.validates_numericality_of(:zine_id) - man = Man.create(name: 'John') - interest = man.interests.create(topic: 'bar', zine_id: 0) + man = Man.create(name: "John") + interest = man.interests.create(topic: "bar", zine_id: 0) assert interest.save - assert !man.update({interests_attributes: { id: interest.id, zine_id: 'foo' }}) + assert !man.update(interests_attributes: { id: interest.id, zine_id: "foo" }) end end private - def association_setter - @association_setter ||= "#{@association_name}_attributes=".to_sym - end + def association_setter + @association_setter ||= "#{@association_name}_attributes=".to_sym + end - def association_getter - @association_getter ||= "#{@association_name}_attributes".to_sym - end + def association_getter + @association_getter ||= "#{@association_name}_attributes".to_sym + end end class TestNestedAttributesOnAHasManyAssociation < ActiveRecord::TestCase @@ -855,16 +853,16 @@ class TestNestedAttributesOnAHasManyAssociation < ActiveRecord::TestCase @association_type = :has_many @association_name = :birds - @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @pirate.birds.create!(:name => 'Posideons Killer') - @pirate.birds.create!(:name => 'Killer bandita Dionne') + @pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") + @pirate.birds.create!(name: "Posideons Killer") + @pirate.birds.create!(name: "Killer bandita Dionne") @child_1, @child_2 = @pirate.birds @alternate_params = { - :birds_attributes => { - 'foo' => { :id => @child_1.id, :name => 'Grace OMalley' }, - 'bar' => { :id => @child_2.id, :name => 'Privateers Greed' } + birds_attributes: { + "foo" => { id: @child_1.id, name: "Grace OMalley" }, + "bar" => { id: @child_2.id, name: "Privateers Greed" } } } end @@ -877,16 +875,16 @@ class TestNestedAttributesOnAHasAndBelongsToManyAssociation < ActiveRecord::Test @association_type = :has_and_belongs_to_many @association_name = :parrots - @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") - @pirate.parrots.create!(:name => 'Posideons Killer') - @pirate.parrots.create!(:name => 'Killer bandita Dionne') + @pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") + @pirate.parrots.create!(name: "Posideons Killer") + @pirate.parrots.create!(name: "Killer bandita Dionne") @child_1, @child_2 = @pirate.parrots @alternate_params = { - :parrots_attributes => { - 'foo' => { :id => @child_1.id, :name => 'Grace OMalley' }, - 'bar' => { :id => @child_2.id, :name => 'Privateers Greed' } + parrots_attributes: { + "foo" => { id: @child_1.id, name: "Grace OMalley" }, + "bar" => { id: @child_2.id, name: "Privateers Greed" } } } end @@ -896,33 +894,33 @@ end module NestedAttributesLimitTests def teardown - Pirate.accepts_nested_attributes_for :parrots, :allow_destroy => true, :reject_if => proc(&:empty?) + Pirate.accepts_nested_attributes_for :parrots, allow_destroy: true, reject_if: proc(&:empty?) end def test_limit_with_less_records - @pirate.attributes = { :parrots_attributes => { 'foo' => { :name => 'Big Big Love' } } } - assert_difference('Parrot.count') { @pirate.save! } + @pirate.attributes = { parrots_attributes: { "foo" => { name: "Big Big Love" } } } + assert_difference("Parrot.count") { @pirate.save! } end def test_limit_with_number_exact_records - @pirate.attributes = { :parrots_attributes => { 'foo' => { :name => 'Lovely Day' }, 'bar' => { :name => 'Blown Away' } } } - assert_difference('Parrot.count', 2) { @pirate.save! } + @pirate.attributes = { parrots_attributes: { "foo" => { name: "Lovely Day" }, "bar" => { name: "Blown Away" } } } + assert_difference("Parrot.count", 2) { @pirate.save! } end def test_limit_with_exceeding_records assert_raises(ActiveRecord::NestedAttributes::TooManyRecords) do - @pirate.attributes = { :parrots_attributes => { 'foo' => { :name => 'Lovely Day' }, - 'bar' => { :name => 'Blown Away' }, - 'car' => { :name => 'The Happening' }} } + @pirate.attributes = { parrots_attributes: { "foo" => { name: "Lovely Day" }, + "bar" => { name: "Blown Away" }, + "car" => { name: "The Happening" } } } end end end class TestNestedAttributesLimitNumeric < ActiveRecord::TestCase def setup - Pirate.accepts_nested_attributes_for :parrots, :limit => 2 + Pirate.accepts_nested_attributes_for :parrots, limit: 2 - @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") + @pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") end include NestedAttributesLimitTests @@ -930,9 +928,9 @@ end class TestNestedAttributesLimitSymbol < ActiveRecord::TestCase def setup - Pirate.accepts_nested_attributes_for :parrots, :limit => :parrots_limit + Pirate.accepts_nested_attributes_for :parrots, limit: :parrots_limit - @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?", :parrots_limit => 2) + @pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?", parrots_limit: 2) end include NestedAttributesLimitTests @@ -940,9 +938,9 @@ end class TestNestedAttributesLimitProc < ActiveRecord::TestCase def setup - Pirate.accepts_nested_attributes_for :parrots, :limit => proc { 2 } + Pirate.accepts_nested_attributes_for :parrots, limit: proc { 2 } - @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") + @pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?") end include NestedAttributesLimitTests @@ -952,45 +950,44 @@ class TestNestedAttributesWithNonStandardPrimaryKeys < ActiveRecord::TestCase fixtures :owners, :pets def setup - Owner.accepts_nested_attributes_for :pets, :allow_destroy => true + Owner.accepts_nested_attributes_for :pets, allow_destroy: true @owner = owners(:ashley) @pet1, @pet2 = pets(:chew), pets(:mochi) @params = { - :pets_attributes => { - '0' => { :id => @pet1.id, :name => 'Foo' }, - '1' => { :id => @pet2.id, :name => 'Bar' } + pets_attributes: { + "0" => { id: @pet1.id, name: "Foo" }, + "1" => { id: @pet2.id, name: "Bar" } } } end def test_should_update_existing_records_with_non_standard_primary_key @owner.update(@params) - assert_equal ['Foo', 'Bar'], @owner.pets.map(&:name) + assert_equal ["Foo", "Bar"], @owner.pets.map(&:name) end def test_attr_accessor_of_child_should_be_value_provided_during_update @owner = owners(:ashley) @pet1 = pets(:chew) - attributes = {:pets_attributes => { "1"=> { :id => @pet1.id, - :name => "Foo2", - :current_user => "John", - :_destroy=>true }}} + attributes = { pets_attributes: { "1"=> { id: @pet1.id, + name: "Foo2", + current_user: "John", + _destroy: true } } } @owner.update(attributes) - assert_equal 'John', Pet.after_destroy_output + assert_equal "John", Pet.after_destroy_output end - end class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRecord::TestCase self.use_transactional_tests = false unless supports_savepoints? def setup - @pirate = Pirate.create!(:catchphrase => "My baby takes tha mornin' train!") - @ship = @pirate.create_ship(:name => "The good ship Dollypop") - @part = @ship.parts.create!(:name => "Mast") - @trinket = @part.trinkets.create!(:name => "Necklace") + @pirate = Pirate.create!(catchphrase: "My baby takes tha mornin' train!") + @ship = @pirate.create_ship(name: "The good ship Dollypop") + @part = @ship.parts.create!(name: "Mast") + @trinket = @part.trinkets.create!(name: "Necklace") end test "when great-grandchild changed in memory, saving parent should save great-grandchild" do @@ -1000,25 +997,25 @@ class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRe end test "when great-grandchild changed via attributes, saving parent should save great-grandchild" do - @pirate.attributes = {:ship_attributes => {:id => @ship.id, :parts_attributes => [{:id => @part.id, :trinkets_attributes => [{:id => @trinket.id, :name => "changed"}]}]}} + @pirate.attributes = { ship_attributes: { id: @ship.id, parts_attributes: [{ id: @part.id, trinkets_attributes: [{ id: @trinket.id, name: "changed" }] }] } } @pirate.save assert_equal "changed", @trinket.reload.name end test "when great-grandchild marked_for_destruction via attributes, saving parent should destroy great-grandchild" do - @pirate.attributes = {:ship_attributes => {:id => @ship.id, :parts_attributes => [{:id => @part.id, :trinkets_attributes => [{:id => @trinket.id, :_destroy => true}]}]}} - assert_difference('@part.trinkets.count', -1) { @pirate.save } + @pirate.attributes = { ship_attributes: { id: @ship.id, parts_attributes: [{ id: @part.id, trinkets_attributes: [{ id: @trinket.id, _destroy: true }] }] } } + assert_difference("@part.trinkets.count", -1) { @pirate.save } end test "when great-grandchild added via attributes, saving parent should create great-grandchild" do - @pirate.attributes = {:ship_attributes => {:id => @ship.id, :parts_attributes => [{:id => @part.id, :trinkets_attributes => [{:name => "created"}]}]}} - assert_difference('@part.trinkets.count', 1) { @pirate.save } + @pirate.attributes = { ship_attributes: { id: @ship.id, parts_attributes: [{ id: @part.id, trinkets_attributes: [{ name: "created" }] }] } } + assert_difference("@part.trinkets.count", 1) { @pirate.save } end test "when extra records exist for associations, validate (which calls nested_records_changed_for_autosave?) should not load them up" do @trinket.name = "changed" - Ship.create!(:pirate => @pirate, :name => "The Black Rock") - ShipPart.create!(:ship => @ship, :name => "Stern") + Ship.create!(pirate: @pirate, name: "The Black Rock") + ShipPart.create!(ship: @ship, name: "Stern") assert_no_queries { @pirate.valid? } end end @@ -1027,27 +1024,27 @@ class TestHasManyAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveR self.use_transactional_tests = false unless supports_savepoints? def setup - @ship = Ship.create!(:name => "The good ship Dollypop") - @part = @ship.parts.create!(:name => "Mast") - @trinket = @part.trinkets.create!(:name => "Necklace") + @ship = Ship.create!(name: "The good ship Dollypop") + @part = @ship.parts.create!(name: "Mast") + @trinket = @part.trinkets.create!(name: "Necklace") end test "if association is not loaded and association record is saved and then in memory record attributes should be saved" do - @ship.parts_attributes=[{:id => @part.id,:name =>'Deck'}] + @ship.parts_attributes=[{ id: @part.id,name: "Deck" }] assert_equal 1, @ship.association(:parts).target.size - assert_equal 'Deck', @ship.parts[0].name + assert_equal "Deck", @ship.parts[0].name end test "if association is not loaded and child doesn't change and I am saving a grandchild then in memory record should be used" do - @ship.parts_attributes=[{:id => @part.id,:trinkets_attributes =>[{:id => @trinket.id, :name => 'Ruby'}]}] + @ship.parts_attributes=[{ id: @part.id,trinkets_attributes: [{ id: @trinket.id, name: "Ruby" }] }] assert_equal 1, @ship.association(:parts).target.size - assert_equal 'Mast', @ship.parts[0].name + assert_equal "Mast", @ship.parts[0].name assert_no_difference("@ship.parts[0].association(:trinkets).target.size") do @ship.parts[0].association(:trinkets).target.size end - assert_equal 'Ruby', @ship.parts[0].trinkets[0].name + assert_equal "Ruby", @ship.parts[0].trinkets[0].name @ship.save - assert_equal 'Ruby', @ship.parts[0].trinkets[0].name + assert_equal "Ruby", @ship.parts[0].trinkets[0].name end test "when grandchild changed in memory, saving parent should save grandchild" do @@ -1057,25 +1054,25 @@ class TestHasManyAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveR end test "when grandchild changed via attributes, saving parent should save grandchild" do - @ship.attributes = {:parts_attributes => [{:id => @part.id, :trinkets_attributes => [{:id => @trinket.id, :name => "changed"}]}]} + @ship.attributes = { parts_attributes: [{ id: @part.id, trinkets_attributes: [{ id: @trinket.id, name: "changed" }] }] } @ship.save assert_equal "changed", @trinket.reload.name end test "when grandchild marked_for_destruction via attributes, saving parent should destroy grandchild" do - @ship.attributes = {:parts_attributes => [{:id => @part.id, :trinkets_attributes => [{:id => @trinket.id, :_destroy => true}]}]} - assert_difference('@part.trinkets.count', -1) { @ship.save } + @ship.attributes = { parts_attributes: [{ id: @part.id, trinkets_attributes: [{ id: @trinket.id, _destroy: true }] }] } + assert_difference("@part.trinkets.count", -1) { @ship.save } end test "when grandchild added via attributes, saving parent should create grandchild" do - @ship.attributes = {:parts_attributes => [{:id => @part.id, :trinkets_attributes => [{:name => "created"}]}]} - assert_difference('@part.trinkets.count', 1) { @ship.save } + @ship.attributes = { parts_attributes: [{ id: @part.id, trinkets_attributes: [{ name: "created" }] }] } + assert_difference("@part.trinkets.count", 1) { @ship.save } end test "when extra records exist for associations, validate (which calls nested_records_changed_for_autosave?) should not load them up" do @trinket.name = "changed" - Ship.create!(:name => "The Black Rock") - ShipPart.create!(:ship => @ship, :name => "Stern") + Ship.create!(name: "The Black Rock") + ShipPart.create!(ship: @ship, name: "Stern") assert_no_queries { @ship.valid? } end diff --git a/activerecord/test/cases/nested_attributes_with_callbacks_test.rb b/activerecord/test/cases/nested_attributes_with_callbacks_test.rb index 43a69928b6..8954e8c7e3 100644 --- a/activerecord/test/cases/nested_attributes_with_callbacks_test.rb +++ b/activerecord/test/cases/nested_attributes_with_callbacks_test.rb @@ -4,24 +4,24 @@ require "models/bird" class NestedAttributesWithCallbacksTest < ActiveRecord::TestCase Pirate.has_many(:birds_with_add_load, - :class_name => "Bird", - :before_add => proc { |p,b| + class_name: "Bird", + before_add: proc { |p,b| @@add_callback_called << b p.birds_with_add_load.to_a }) Pirate.has_many(:birds_with_add, - :class_name => "Bird", - :before_add => proc { |p,b| @@add_callback_called << b }) + class_name: "Bird", + before_add: proc { |p,b| @@add_callback_called << b }) Pirate.accepts_nested_attributes_for(:birds_with_add_load, :birds_with_add, - :allow_destroy => true) + allow_destroy: true) def setup @@add_callback_called = [] @pirate = Pirate.new.tap do |pirate| pirate.catchphrase = "Don't call me!" - pirate.birds_attributes = [{:name => 'Bird1'},{:name => 'Bird2'}] + pirate.birds_attributes = [{ name: "Bird1" },{ name: "Bird2" }] pirate.save! end @birds = @pirate.birds.to_a @@ -46,17 +46,17 @@ class NestedAttributesWithCallbacksTest < ActiveRecord::TestCase end def new_bird_attributes - [{'name' => "New Bird"}] + [{ "name" => "New Bird" }] end def destroy_bird_attributes - [{'id' => bird_to_destroy.id.to_s, "_destroy" => true}] + [{ "id" => bird_to_destroy.id.to_s, "_destroy" => true }] end def update_new_and_destroy_bird_attributes - [{'id' => @birds[0].id.to_s, 'name' => 'New Name'}, - {'name' => "New Bird"}, - {'id' => bird_to_destroy.id.to_s, "_destroy" => true}] + [{ "id" => @birds[0].id.to_s, "name" => "New Name" }, + { "name" => "New Bird" }, + { "id" => bird_to_destroy.id.to_s, "_destroy" => true }] end # Characterizing when :before_add callback is called @@ -136,9 +136,9 @@ class NestedAttributesWithCallbacksTest < ActiveRecord::TestCase def assert_assignment_affects_records_in_target(association_name) association = @pirate.send(association_name) - assert association.detect {|b| b == bird_to_update }.name_changed?, - 'Update record not updated' - assert association.detect {|b| b == bird_to_destroy }.marked_for_destruction?, - 'Destroy record not marked for destruction' + assert association.detect { |b| b == bird_to_update }.name_changed?, + "Update record not updated" + assert association.detect { |b| b == bird_to_destroy }.marked_for_destruction?, + "Destroy record not marked for destruction" end end diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 56092aaa0c..688c3ed2b1 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -1,30 +1,30 @@ require "cases/helper" -require 'models/aircraft' -require 'models/post' -require 'models/comment' -require 'models/author' -require 'models/topic' -require 'models/reply' -require 'models/category' -require 'models/company' -require 'models/developer' -require 'models/computer' -require 'models/project' -require 'models/minimalistic' -require 'models/warehouse_thing' -require 'models/parrot' -require 'models/minivan' -require 'models/owner' -require 'models/person' -require 'models/pet' -require 'models/ship' -require 'models/toy' -require 'models/admin' -require 'models/admin/user' -require 'rexml/document' +require "models/aircraft" +require "models/post" +require "models/comment" +require "models/author" +require "models/topic" +require "models/reply" +require "models/category" +require "models/company" +require "models/developer" +require "models/computer" +require "models/project" +require "models/minimalistic" +require "models/warehouse_thing" +require "models/parrot" +require "models/minivan" +require "models/owner" +require "models/person" +require "models/pet" +require "models/ship" +require "models/toy" +require "models/admin" +require "models/admin/user" +require "rexml/document" class PersistenceTest < ActiveRecord::TestCase - fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :author_addresses, :categorizations, :categories, :posts, :minivans, :pets, :toys + fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, "warehouse-things", :authors, :author_addresses, :categorizations, :categories, :posts, :minivans, :pets, :toys # Oracle UPDATE does not support ORDER BY unless current_adapter?(:OracleAdapter) @@ -39,18 +39,18 @@ class PersistenceTest < ActiveRecord::TestCase assert_equal authors(:david).id + 1, authors(:mary).id # make sure there is going to be a duplicate PK error test_update_with_order_succeeds = lambda do |order| begin - Author.order(order).update_all('id = id + 1') + Author.order(order).update_all("id = id + 1") rescue ActiveRecord::ActiveRecordError false end end - if test_update_with_order_succeeds.call('id DESC') - assert !test_update_with_order_succeeds.call('id ASC') # test that this wasn't a fluke and using an incorrect order results in an exception + if test_update_with_order_succeeds.call("id DESC") + assert !test_update_with_order_succeeds.call("id ASC") # test that this wasn't a fluke and using an incorrect order results in an exception else # test that we're failing because the current Arel's engine doesn't support UPDATE ORDER BY queries is using subselects instead assert_sql(/\AUPDATE .+ \(SELECT .* ORDER BY id DESC\)\Z/i) do - test_update_with_order_succeeds.call('id DESC') + test_update_with_order_succeeds.call("id DESC") end end end @@ -83,7 +83,7 @@ class PersistenceTest < ActiveRecord::TestCase end def test_delete_all_with_joins_and_where_part_is_hash - where_args = {:toys => {:name => 'Bone'}} + where_args = { toys: { name: "Bone" } } count = Pet.joins(:toys).where(where_args).count assert_equal count, 1 @@ -91,7 +91,7 @@ class PersistenceTest < ActiveRecord::TestCase end def test_delete_all_with_joins_and_where_part_is_not_hash - where_args = ['toys.name = ?', 'Bone'] + where_args = ["toys.name = ?", "Bone"] count = Pet.joins(:toys).where(where_args).count assert_equal count, 1 @@ -133,10 +133,10 @@ class PersistenceTest < ActiveRecord::TestCase def test_destroy_all conditions = "author_name = 'Mary'" - topics_by_mary = Topic.all.merge!(:where => conditions, :order => 'id').to_a + topics_by_mary = Topic.all.merge!(where: conditions, order: "id").to_a assert ! topics_by_mary.empty? - assert_difference('Topic.count', -topics_by_mary.size) do + assert_difference("Topic.count", -topics_by_mary.size) do destroyed = Topic.where(conditions).destroy_all.sort_by(&:id) assert_equal topics_by_mary, destroyed assert destroyed.all?(&:frozen?), "destroyed topics should be frozen" @@ -144,9 +144,9 @@ class PersistenceTest < ActiveRecord::TestCase end def test_destroy_many - clients = Client.all.merge!(:order => 'id').find([2, 3]) + clients = Client.all.merge!(order: "id").find([2, 3]) - assert_difference('Client.count', -2) do + assert_difference("Client.count", -2) do destroyed = Client.destroy([2, 3]).sort_by(&:id) assert_equal clients, destroyed assert destroyed.all?(&:frozen?), "destroyed clients should be frozen" @@ -159,7 +159,7 @@ class PersistenceTest < ActiveRecord::TestCase end def test_becomes_includes_errors - company = Company.new(:name => nil) + company = Company.new(name: nil) assert !company.valid? original_errors = company.errors client = company.becomes(Client) @@ -170,7 +170,7 @@ class PersistenceTest < ActiveRecord::TestCase child_class = Class.new(Admin::User) do store_accessor :settings, :foo - def self.name; 'Admin::ChildUser'; end + def self.name; "Admin::ChildUser"; end end admin = Admin::User.new @@ -231,7 +231,7 @@ class PersistenceTest < ActiveRecord::TestCase end def test_save! - topic = Topic.new(:title => "New Topic") + topic = Topic.new(title: "New Topic") assert topic.save! reply = WrongReply.new @@ -261,7 +261,7 @@ class PersistenceTest < ActiveRecord::TestCase end def test_save_for_record_with_only_primary_key_that_is_provided - assert_nothing_raised { Minimalistic.create!(:id => 2) } + assert_nothing_raised { Minimalistic.create!(id: 2) } end def test_save_with_duping_of_destroyed_object @@ -281,9 +281,9 @@ class PersistenceTest < ActiveRecord::TestCase def test_create_columns_not_equal_attributes topic = Topic.instantiate( - 'attributes' => { - 'title' => 'Another New Topic', - 'does_not_exist' => 'test' + "attributes" => { + "title" => "Another New Topic", + "does_not_exist" => "test" } ) assert_nothing_raised { topic.save } @@ -330,8 +330,8 @@ class PersistenceTest < ActiveRecord::TestCase topic.title = "Still another topic" topic.save - topic_reloaded = Topic.instantiate(topic.attributes.merge('does_not_exist' => 'test')) - topic_reloaded.title = 'A New Topic' + topic_reloaded = Topic.instantiate(topic.attributes.merge("does_not_exist" => "test")) + topic_reloaded.title = "A New Topic" assert_nothing_raised { topic_reloaded.save } end @@ -371,7 +371,7 @@ class PersistenceTest < ActiveRecord::TestCase def test_update_after_create klass = Class.new(Topic) do - def self.name; 'Topic'; end + def self.name; "Topic"; end after_create do update_attribute("author_name", "David") end @@ -387,24 +387,24 @@ class PersistenceTest < ActiveRecord::TestCase def test_update_attribute_does_not_run_sql_if_attribute_is_not_changed klass = Class.new(Topic) do - def self.name; 'Topic'; end + def self.name; "Topic"; end end - topic = klass.create(title: 'Another New Topic') + topic = klass.create(title: "Another New Topic") assert_queries(0) do - topic.update_attribute(:title, 'Another New Topic') + assert topic.update_attribute(:title, "Another New Topic") end end def test_update_does_not_run_sql_if_record_has_not_changed - topic = Topic.create(title: 'Another New Topic') - assert_queries(0) { topic.update(title: 'Another New Topic') } - assert_queries(0) { topic.update_attributes(title: 'Another New Topic') } + topic = Topic.create(title: "Another New Topic") + assert_queries(0) { assert topic.update(title: "Another New Topic") } + assert_queries(0) { assert topic.update_attributes(title: "Another New Topic") } end def test_delete topic = Topic.find(1) - assert_equal topic, topic.delete, 'topic.delete did not return self' - assert topic.frozen?, 'topic not frozen after delete' + assert_equal topic, topic.delete, "topic.delete did not return self" + assert topic.frozen?, "topic not frozen after delete" assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) } end @@ -415,15 +415,15 @@ class PersistenceTest < ActiveRecord::TestCase def test_destroy topic = Topic.find(1) - assert_equal topic, topic.destroy, 'topic.destroy did not return self' - assert topic.frozen?, 'topic not frozen after destroy' + assert_equal topic, topic.destroy, "topic.destroy did not return self" + assert topic.frozen?, "topic not frozen after destroy" assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) } end def test_destroy! topic = Topic.find(1) - assert_equal topic, topic.destroy!, 'topic.destroy! did not return self' - assert topic.frozen?, 'topic not frozen after destroy!' + assert_equal topic, topic.destroy!, "topic.destroy! did not return self" + assert topic.frozen?, "topic not frozen after destroy!" assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) } end @@ -436,17 +436,17 @@ class PersistenceTest < ActiveRecord::TestCase assert_equal "bulk updated!", Topic.find(1).content assert_equal "bulk updated!", Topic.find(2).content - assert_equal Topic.count, Topic.update_all(['content = ?', 'bulk updated again!']) + assert_equal Topic.count, Topic.update_all(["content = ?", "bulk updated again!"]) assert_equal "bulk updated again!", Topic.find(1).content assert_equal "bulk updated again!", Topic.find(2).content - assert_equal Topic.count, Topic.update_all(['content = ?', nil]) + assert_equal Topic.count, Topic.update_all(["content = ?", nil]) assert_nil Topic.find(1).content end def test_update_all_with_hash assert_not_nil Topic.find(1).last_read - assert_equal Topic.count, Topic.update_all(:content => 'bulk updated with hash!', :last_read => nil) + assert_equal Topic.count, Topic.update_all(content: "bulk updated with hash!", last_read: nil) assert_equal "bulk updated with hash!", Topic.find(1).content assert_equal "bulk updated with hash!", Topic.find(2).content assert_nil Topic.find(1).last_read @@ -454,7 +454,7 @@ class PersistenceTest < ActiveRecord::TestCase end def test_update_all_with_non_standard_table_name - assert_equal 1, WarehouseThing.where(id: 1).update_all(['value = ?', 0]) + assert_equal 1, WarehouseThing.where(id: 1).update_all(["value = ?", 0]) assert_equal 0, WarehouseThing.find(1).value end @@ -496,20 +496,20 @@ class PersistenceTest < ActiveRecord::TestCase end def test_update_attribute_for_readonly_attribute - minivan = Minivan.find('m1') - assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_attribute(:color, 'black') } + minivan = Minivan.find("m1") + assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_attribute(:color, "black") } end def test_update_attribute_with_one_updated t = Topic.first - t.update_attribute(:title, 'super_title') - assert_equal 'super_title', t.title + t.update_attribute(:title, "super_title") + assert_equal "super_title", t.title assert !t.changed?, "topic should not have changed" assert !t.title_changed?, "title should not have changed" - assert_nil t.title_change, 'title change should be nil' + assert_nil t.title_change, "title change should be nil" t.reload - assert_equal 'super_title', t.title + assert_equal "super_title", t.title end def test_update_attribute_for_updated_at_on @@ -569,17 +569,17 @@ class PersistenceTest < ActiveRecord::TestCase end def test_update_column_with_model_having_primary_key_other_than_id - minivan = Minivan.find('m1') - new_name = 'sebavan' + minivan = Minivan.find("m1") + new_name = "sebavan" minivan.update_column(:name, new_name) assert_equal new_name, minivan.name end def test_update_column_for_readonly_attribute - minivan = Minivan.find('m1') + minivan = Minivan.find("m1") prev_color = minivan.color - assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_column(:color, 'black') } + assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_column(:color, "black") } assert_equal prev_color, minivan.color end @@ -598,31 +598,31 @@ class PersistenceTest < ActiveRecord::TestCase end def test_update_column_with_one_changed_and_one_updated - t = Topic.order('id').limit(1).first + t = Topic.order("id").limit(1).first author_name = t.author_name - t.author_name = 'John' - t.update_column(:title, 'super_title') - assert_equal 'John', t.author_name - assert_equal 'super_title', t.title + t.author_name = "John" + t.update_column(:title, "super_title") + assert_equal "John", t.author_name + assert_equal "super_title", t.title assert t.changed?, "topic should have changed" assert t.author_name_changed?, "author_name should have changed" t.reload assert_equal author_name, t.author_name - assert_equal 'super_title', t.title + assert_equal "super_title", t.title end def test_update_column_with_default_scope developer = DeveloperCalledDavid.first - developer.name = 'John' + developer.name = "John" developer.save! - assert developer.update_column(:name, 'Will'), 'did not update record due to default scope' + assert developer.update_column(:name, "Will"), "did not update record due to default scope" end def test_update_columns topic = Topic.find(1) - topic.update_columns({ "approved" => true, title: "Sebastian Topic" }) + topic.update_columns("approved" => true, title: "Sebastian Topic") assert topic.approved? assert_equal "Sebastian Topic", topic.title topic.reload @@ -643,35 +643,35 @@ class PersistenceTest < ActiveRecord::TestCase def test_update_columns_should_raise_exception_if_new_record topic = Topic.new - assert_raises(ActiveRecord::ActiveRecordError) { topic.update_columns({ approved: false }) } + assert_raises(ActiveRecord::ActiveRecordError) { topic.update_columns(approved: false) } end def test_update_columns_should_not_leave_the_object_dirty topic = Topic.find(1) - topic.update({ "content" => "--- Have a nice day\n...\n", :author_name => "Jose" }) + topic.update("content" => "--- Have a nice day\n...\n", :author_name => "Jose") topic.reload - topic.update_columns({ content: "--- You too\n...\n", "author_name" => "Sebastian" }) + topic.update_columns(content: "--- You too\n...\n", "author_name" => "Sebastian") assert_equal [], topic.changed topic.reload - topic.update_columns({ content: "--- Have a nice day\n...\n", author_name: "Jose" }) + topic.update_columns(content: "--- Have a nice day\n...\n", author_name: "Jose") assert_equal [], topic.changed end def test_update_columns_with_model_having_primary_key_other_than_id - minivan = Minivan.find('m1') - new_name = 'sebavan' + minivan = Minivan.find("m1") + new_name = "sebavan" minivan.update_columns(name: new_name) assert_equal new_name, minivan.name end def test_update_columns_with_one_readonly_attribute - minivan = Minivan.find('m1') + minivan = Minivan.find("m1") prev_color = minivan.color prev_name = minivan.name - assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_columns({ name: "My old minivan", color: 'black' }) } + assert_raises(ActiveRecord::ActiveRecordError) { minivan.update_columns(name: "My old minivan", color: "black") } assert_equal prev_color, minivan.color assert_equal prev_name, minivan.name @@ -697,18 +697,18 @@ class PersistenceTest < ActiveRecord::TestCase end def test_update_columns_with_one_changed_and_one_updated - t = Topic.order('id').limit(1).first + t = Topic.order("id").limit(1).first author_name = t.author_name - t.author_name = 'John' - t.update_columns(title: 'super_title') - assert_equal 'John', t.author_name - assert_equal 'super_title', t.title + t.author_name = "John" + t.update_columns(title: "super_title") + assert_equal "John", t.author_name + assert_equal "super_title", t.title assert t.changed?, "topic should have changed" assert t.author_name_changed?, "author_name should have changed" t.reload assert_equal author_name, t.author_name - assert_equal 'super_title', t.title + assert_equal "super_title", t.title end def test_update_columns_changing_id @@ -726,10 +726,10 @@ class PersistenceTest < ActiveRecord::TestCase def test_update_columns_with_default_scope developer = DeveloperCalledDavid.first - developer.name = 'John' + developer.name = "John" developer.save! - assert developer.update_columns(name: 'Will'), 'did not update record due to default scope' + assert developer.update_columns(name: "Will"), "did not update record due to default scope" end def test_update @@ -840,7 +840,7 @@ class PersistenceTest < ActiveRecord::TestCase end def test_persisted_returns_boolean - developer = Developer.new(:name => "Jose") + developer = Developer.new(name: "Jose") assert_equal false, developer.persisted? developer.save! assert_equal true, developer.persisted? @@ -909,7 +909,7 @@ class PersistenceTest < ActiveRecord::TestCase end def test_reload_removes_custom_selects - post = Post.select('posts.*, 1 as wibble').last! + post = Post.select("posts.*, 1 as wibble").last! assert_equal 1, post[:wibble] assert_nil post.reload[:wibble] @@ -930,8 +930,8 @@ class PersistenceTest < ActiveRecord::TestCase def test_reload_via_querycache ActiveRecord::Base.connection.enable_query_cache! ActiveRecord::Base.connection.clear_query_cache - assert ActiveRecord::Base.connection.query_cache_enabled, 'cache should be on' - parrot = Parrot.create(:name => 'Shane') + assert ActiveRecord::Base.connection.query_cache_enabled, "cache should be on" + parrot = Parrot.create(name: "Shane") # populate the cache with the SELECT result found_parrot = Parrot.find(parrot.id) @@ -940,16 +940,16 @@ class PersistenceTest < ActiveRecord::TestCase # Manually update the 'name' attribute in the DB directly assert_equal 1, ActiveRecord::Base.connection.query_cache.length ActiveRecord::Base.uncached do - found_parrot.name = 'Mary' + found_parrot.name = "Mary" found_parrot.save end # Now reload, and verify that it gets the DB version, and not the querycache version found_parrot.reload - assert_equal 'Mary', found_parrot.name + assert_equal "Mary", found_parrot.name found_parrot = Parrot.find(parrot.id) - assert_equal 'Mary', found_parrot.name + assert_equal "Mary", found_parrot.name ensure ActiveRecord::Base.connection.disable_query_cache! end @@ -967,16 +967,15 @@ class PersistenceTest < ActiveRecord::TestCase self.table_name = :widgets end - instance = widget.create!({ - name: 'Bob', + instance = widget.create!( + name: "Bob", created_at: 1.day.ago, - updated_at: 1.day.ago - }) + updated_at: 1.day.ago) created_at = instance.created_at updated_at = instance.updated_at - instance.name = 'Barb' + instance.name = "Barb" instance.save!(touch: false) assert_equal instance.created_at, created_at assert_equal instance.updated_at, updated_at diff --git a/activerecord/test/cases/pooled_connections_test.rb b/activerecord/test/cases/pooled_connections_test.rb index bca50dd008..f1b0d08765 100644 --- a/activerecord/test/cases/pooled_connections_test.rb +++ b/activerecord/test/cases/pooled_connections_test.rb @@ -18,7 +18,7 @@ class PooledConnectionsTest < ActiveRecord::TestCase # Will deadlock due to lack of Monitor timeouts in 1.9 def checkout_checkin_connections(pool_size, threads) - ActiveRecord::Base.establish_connection(@connection.merge({:pool => pool_size, :checkout_timeout => 0.5})) + ActiveRecord::Base.establish_connection(@connection.merge(pool: pool_size, checkout_timeout: 0.5)) @connection_count = 0 @timed_out = 0 threads.times do @@ -36,7 +36,7 @@ class PooledConnectionsTest < ActiveRecord::TestCase end def checkout_checkin_connections_loop(pool_size, loops) - ActiveRecord::Base.establish_connection(@connection.merge({:pool => pool_size, :checkout_timeout => 0.5})) + ActiveRecord::Base.establish_connection(@connection.merge(pool: pool_size, checkout_timeout: 0.5)) @connection_count = 0 @timed_out = 0 loops.times do @@ -66,7 +66,7 @@ class PooledConnectionsTest < ActiveRecord::TestCase end def test_pooled_connection_remove - ActiveRecord::Base.establish_connection(@connection.merge({:pool => 2, :checkout_timeout => 0.5})) + ActiveRecord::Base.establish_connection(@connection.merge(pool: 2, checkout_timeout: 0.5)) old_connection = ActiveRecord::Base.connection extra_connection = ActiveRecord::Base.connection_pool.checkout ActiveRecord::Base.connection_pool.remove(extra_connection) @@ -75,7 +75,7 @@ class PooledConnectionsTest < ActiveRecord::TestCase private - def add_record(name) - ActiveRecord::Base.connection_pool.with_connection { Project.create! :name => name } - end + def add_record(name) + ActiveRecord::Base.connection_pool.with_connection { Project.create! name: name } + end end unless in_memory_db? diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb index 52eac4a124..31d612abd1 100644 --- a/activerecord/test/cases/primary_keys_test.rb +++ b/activerecord/test/cases/primary_keys_test.rb @@ -1,12 +1,12 @@ require "cases/helper" -require 'support/schema_dumping_helper' -require 'models/topic' -require 'models/reply' -require 'models/subscriber' -require 'models/movie' -require 'models/keyboard' -require 'models/mixed_case_monkey' -require 'models/dashboard' +require "support/schema_dumping_helper" +require "models/topic" +require "models/reply" +require "models/subscriber" +require "models/movie" +require "models/keyboard" +require "models/mixed_case_monkey" +require "models/dashboard" class PrimaryKeysTest < ActiveRecord::TestCase fixtures :topics, :subscribers, :movies, :mixed_case_monkeys @@ -54,9 +54,9 @@ class PrimaryKeysTest < ActiveRecord::TestCase def test_customized_primary_key_auto_assigns_on_save Keyboard.delete_all - keyboard = Keyboard.new(:name => 'HHKB') + keyboard = Keyboard.new(name: "HHKB") assert_nothing_raised { keyboard.save! } - assert_equal keyboard.id, Keyboard.find_by_name('HHKB').id + assert_equal keyboard.id, Keyboard.find_by_name("HHKB").id end def test_customized_primary_key_can_be_get_before_saving @@ -67,9 +67,9 @@ class PrimaryKeysTest < ActiveRecord::TestCase def test_customized_string_primary_key_settable_before_save subscriber = Subscriber.new - assert_nothing_raised { subscriber.id = 'webster123' } - assert_equal 'webster123', subscriber.id - assert_equal 'webster123', subscriber.nick + assert_nothing_raised { subscriber.id = "webster123" } + assert_equal "webster123", subscriber.id + assert_equal "webster123", subscriber.nick end def test_string_key @@ -114,7 +114,7 @@ class PrimaryKeysTest < ActiveRecord::TestCase assert_nothing_raised { MixedCaseMonkey.delete(1) } end def test_update_counters_should_quote_pkey_and_quote_counter_columns - assert_nothing_raised { MixedCaseMonkey.update_counters(1, :fleaCount => 99) } + assert_nothing_raised { MixedCaseMonkey.update_counters(1, fleaCount: 99) } end def test_find_with_one_id_should_quote_pkey assert_nothing_raised { MixedCaseMonkey.find(1) } @@ -138,15 +138,15 @@ class PrimaryKeysTest < ActiveRecord::TestCase if ActiveRecord::Base.connection.supports_primary_key? def test_primary_key_returns_value_if_it_exists klass = Class.new(ActiveRecord::Base) do - self.table_name = 'developers' + self.table_name = "developers" end - assert_equal 'id', klass.primary_key + assert_equal "id", klass.primary_key end def test_primary_key_returns_nil_if_it_does_not_exist klass = Class.new(ActiveRecord::Base) do - self.table_name = 'developers_projects' + self.table_name = "developers_projects" end assert_nil klass.primary_key @@ -166,12 +166,20 @@ class PrimaryKeysTest < ActiveRecord::TestCase end def test_primary_key_update_with_custom_key_name - dashboard = Dashboard.create!(dashboard_id: '1') - dashboard.id = '2' + dashboard = Dashboard.create!(dashboard_id: "1") + dashboard.id = "2" dashboard.save! dashboard = Dashboard.first - assert_equal '2', dashboard.id + assert_equal "2", dashboard.id + end + + def test_create_without_primary_key_no_extra_query + klass = Class.new(ActiveRecord::Base) do + self.table_name = "dashboards" + end + klass.create! # warmup schema cache + assert_queries(3, ignore_none: true) { klass.create! } end if current_adapter?(:PostgreSQLAdapter) @@ -197,13 +205,13 @@ class PrimaryKeyWithNoConnectionTest < ActiveRecord::TestCase connection = ActiveRecord::Base.remove_connection model = Class.new(ActiveRecord::Base) - model.primary_key = 'foo' + model.primary_key = "foo" - assert_equal 'foo', model.primary_key + assert_equal "foo", model.primary_key ActiveRecord::Base.establish_connection(connection) - assert_equal 'foo', model.primary_key + assert_equal "foo", model.primary_key end end end @@ -247,6 +255,7 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase def setup @connection = ActiveRecord::Base.connection + @connection.schema_cache.clear! @connection.create_table(:barcodes, primary_key: ["region", "code"], force: true) do |t| t.string :region t.integer :code @@ -262,10 +271,15 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase end def test_primary_key_issues_warning + model = Class.new(ActiveRecord::Base) do + def self.table_name + "barcodes" + end + end warning = capture(:stderr) do - assert_nil @connection.primary_key("barcodes") + assert_nil model.primary_key end - assert_match(/WARNING: Rails does not support composite primary key\./, warning) + assert_match(/WARNING: Active Record does not support composite primary key\./, warning) end def test_collectly_dump_composite_primary_key @@ -275,18 +289,6 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase end if current_adapter?(:Mysql2Adapter) - class PrimaryKeyWithAnsiQuotesTest < ActiveRecord::TestCase - self.use_transactional_tests = false - - def test_primary_key_method_with_ansi_quotes - con = ActiveRecord::Base.connection - con.execute("SET SESSION sql_mode='ANSI_QUOTES'") - assert_equal "id", con.primary_key("topics") - ensure - con.reconnect! - end - end - class PrimaryKeyBigintNilDefaultTest < ActiveRecord::TestCase include SchemaDumpingHelper @@ -302,7 +304,7 @@ if current_adapter?(:Mysql2Adapter) end test "primary key with bigint allows default override via nil" do - column = @connection.columns(:bigint_defaults).find { |c| c.name == 'id' } + column = @connection.columns(:bigint_defaults).find { |c| c.name == "id" } assert column.bigint? assert_not column.auto_increment? end @@ -360,7 +362,7 @@ if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter) if current_adapter?(:Mysql2Adapter) test "primary key column type with options" do @connection.create_table(:widgets, id: :primary_key, limit: 8, unsigned: true, force: true) - column = @connection.columns(:widgets).find { |c| c.name == 'id' } + column = @connection.columns(:widgets).find { |c| c.name == "id" } assert column.auto_increment? assert_equal :integer, column.type assert_equal 8, column.limit diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index e53239cdee..7f7faca70d 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -1,11 +1,13 @@ require "cases/helper" -require 'models/topic' -require 'models/task' -require 'models/category' -require 'models/post' -require 'rack' +require "models/topic" +require "models/task" +require "models/category" +require "models/post" +require "rack" class QueryCacheTest < ActiveRecord::TestCase + self.use_transactional_tests = false + fixtures :tasks, :topics, :categories, :posts, :categories_posts teardown do @@ -14,7 +16,7 @@ class QueryCacheTest < ActiveRecord::TestCase end def test_exceptional_middleware_clears_and_disables_cache_on_error - assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache off' + assert !ActiveRecord::Base.connection.query_cache_enabled, "cache off" mw = middleware { |env| Task.find 1 @@ -25,7 +27,7 @@ class QueryCacheTest < ActiveRecord::TestCase assert_raises(RuntimeError) { mw.call({}) } assert_equal 0, ActiveRecord::Base.connection.query_cache.length - assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache off' + assert !ActiveRecord::Base.connection.query_cache_enabled, "cache off" end def test_exceptional_middleware_leaves_enabled_cache_alone @@ -36,19 +38,7 @@ class QueryCacheTest < ActiveRecord::TestCase } assert_raises(RuntimeError) { mw.call({}) } - assert ActiveRecord::Base.connection.query_cache_enabled, 'cache on' - end - - def test_exceptional_middleware_assigns_original_connection_id_on_error - connection_id = ActiveRecord::Base.connection_id - - mw = middleware { |env| - ActiveRecord::Base.connection_id = self.object_id - raise "lol borked" - } - assert_raises(RuntimeError) { mw.call({}) } - - assert_equal connection_id, ActiveRecord::Base.connection_id + assert ActiveRecord::Base.connection.query_cache_enabled, "cache on" end def test_middleware_delegates @@ -58,7 +48,7 @@ class QueryCacheTest < ActiveRecord::TestCase [200, {}, nil] } mw.call({}) - assert called, 'middleware should delegate' + assert called, "middleware should delegate" end def test_middleware_caches @@ -72,10 +62,10 @@ class QueryCacheTest < ActiveRecord::TestCase end def test_cache_enabled_during_call - assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache off' + assert !ActiveRecord::Base.connection.query_cache_enabled, "cache off" mw = middleware { |env| - assert ActiveRecord::Base.connection.query_cache_enabled, 'cache on' + assert ActiveRecord::Base.connection.query_cache_enabled, "cache on" [200, {}, nil] } mw.call({}) @@ -133,7 +123,6 @@ class QueryCacheTest < ActiveRecord::TestCase def test_cache_is_flat Task.cache do - Topic.columns # don't count this query assert_queries(1) { Topic.find(1); Topic.find(1); } end @@ -144,13 +133,12 @@ class QueryCacheTest < ActiveRecord::TestCase def test_cache_does_not_wrap_string_results_in_arrays Task.cache do - # Oracle adapter returns count() as Fixnum or Float + # Oracle adapter returns count() as Integer or Float if current_adapter?(:OracleAdapter) assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks") elsif current_adapter?(:SQLite3Adapter, :Mysql2Adapter, :PostgreSQLAdapter) # Future versions of the sqlite3 adapter will return numeric - assert_instance_of Fixnum, - Task.connection.select_value("SELECT count(*) AS count_all FROM tasks") + assert_instance_of Fixnum, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks") else assert_instance_of String, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks") end @@ -176,35 +164,71 @@ class QueryCacheTest < ActiveRecord::TestCase ActiveRecord::Base.configurations = conf end + def test_cache_is_not_available_when_using_a_not_connected_connection + spec_name = Task.connection_specification_name + conf = ActiveRecord::Base.configurations["arunit"].merge("name" => "test2") + ActiveRecord::Base.connection_handler.establish_connection(conf) + Task.connection_specification_name = "test2" + refute Task.connected? + + Task.cache do + Task.connection # warmup postgresql connection setup queries + assert_queries(2) { Task.find(1); Task.find(1) } + end + ensure + ActiveRecord::Base.connection_handler.remove_connection(Task.connection_specification_name) + Task.connection_specification_name = spec_name + end + def test_query_cache_doesnt_leak_cached_results_of_rolled_back_queries ActiveRecord::Base.connection.enable_query_cache! post = Post.first Post.transaction do - post.update_attributes(title: 'rollback') - assert_equal 1, Post.where(title: 'rollback').to_a.count + post.update_attributes(title: "rollback") + assert_equal 1, Post.where(title: "rollback").to_a.count raise ActiveRecord::Rollback end - assert_equal 0, Post.where(title: 'rollback').to_a.count + assert_equal 0, Post.where(title: "rollback").to_a.count ActiveRecord::Base.connection.uncached do - assert_equal 0, Post.where(title: 'rollback').to_a.count + assert_equal 0, Post.where(title: "rollback").to_a.count end begin Post.transaction do - post.update_attributes(title: 'rollback') - assert_equal 1, Post.where(title: 'rollback').to_a.count - raise 'broken' + post.update_attributes(title: "rollback") + assert_equal 1, Post.where(title: "rollback").to_a.count + raise "broken" end rescue Exception end - assert_equal 0, Post.where(title: 'rollback').to_a.count + assert_equal 0, Post.where(title: "rollback").to_a.count ActiveRecord::Base.connection.uncached do - assert_equal 0, Post.where(title: 'rollback').to_a.count + assert_equal 0, Post.where(title: "rollback").to_a.count + end + end + + def test_query_cached_even_when_types_are_reset + Task.cache do + # Warm the cache + Task.find(1) + + Task.connection.type_map.clear + + # Preload the type cache again (so we don't have those queries issued during our assertions) + Task.connection.send(:initialize_type_map, Task.connection.type_map) + + # Clear places where type information is cached + Task.reset_column_information + Task.initialize_find_by_cache + + assert_queries(0) do + Task.find(1) + end end end diff --git a/activerecord/test/cases/quoting_test.rb b/activerecord/test/cases/quoting_test.rb index 6d91f96bf6..296dafacc2 100644 --- a/activerecord/test/cases/quoting_test.rb +++ b/activerecord/test/cases/quoting_test.rb @@ -16,20 +16,20 @@ module ActiveRecord end def test_quote_column_name - assert_equal "foo", @quoter.quote_column_name('foo') + assert_equal "foo", @quoter.quote_column_name("foo") end def test_quote_table_name - assert_equal "foo", @quoter.quote_table_name('foo') + assert_equal "foo", @quoter.quote_table_name("foo") end def test_quote_table_name_calls_quote_column_name @quoter.extend(Module.new { def quote_column_name(string) - 'lol' + "lol" end }) - assert_equal 'lol', @quoter.quote_table_name('foo') + assert_equal "lol", @quoter.quote_table_name("foo") end def test_quote_string @@ -86,7 +86,7 @@ module ActiveRecord end def test_quote_nil - assert_equal 'NULL', @quoter.quote(nil, nil) + assert_equal "NULL", @quoter.quote(nil, nil) end def test_quote_true @@ -102,9 +102,9 @@ module ActiveRecord assert_equal float.to_s, @quoter.quote(float, nil) end - def test_quote_fixnum - fixnum = 1 - assert_equal fixnum.to_s, @quoter.quote(fixnum, nil) + def test_quote_integer + integer = 1 + assert_equal integer.to_s, @quoter.quote(integer, nil) end def test_quote_bignum @@ -114,11 +114,11 @@ module ActiveRecord def test_quote_bigdecimal bigdec = BigDecimal.new((1 << 100).to_s) - assert_equal bigdec.to_s('F'), @quoter.quote(bigdec, nil) + assert_equal bigdec.to_s("F"), @quoter.quote(bigdec, nil) end def test_dates_and_times - @quoter.extend(Module.new { def quoted_date(value) 'lol' end }) + @quoter.extend(Module.new { def quoted_date(value) "lol" end }) assert_equal "'lol'", @quoter.quote(Date.today, nil) assert_equal "'lol'", @quoter.quote(Time.now, nil) assert_equal "'lol'", @quoter.quote(DateTime.now, nil) @@ -133,21 +133,33 @@ module ActiveRecord end def test_quote_string_no_column - assert_equal "'lo\\\\l'", @quoter.quote('lo\l', nil) + assert_equal "'lo\\\\l'", @quoter.quote('lo\l') end def test_quote_as_mb_chars_no_column string = ActiveSupport::Multibyte::Chars.new('lo\l') - assert_equal "'lo\\\\l'", @quoter.quote(string, nil) - end - - def test_string_with_crazy_column - assert_equal "'lo\\\\l'", @quoter.quote('lo\l') + assert_equal "'lo\\\\l'", @quoter.quote(string) end def test_quote_duration assert_equal "1800", @quoter.quote(30.minutes) end end + + class QuoteBooleanTest < ActiveRecord::TestCase + def setup + @connection = ActiveRecord::Base.connection + end + + def test_quote_returns_frozen_string + assert_predicate @connection.quote(true), :frozen? + assert_predicate @connection.quote(false), :frozen? + end + + def test_type_cast_returns_frozen_value + assert_predicate @connection.type_cast(true), :frozen? + assert_predicate @connection.type_cast(false), :frozen? + end + end end end diff --git a/activerecord/test/cases/readonly_test.rb b/activerecord/test/cases/readonly_test.rb index 5f6eb41240..a93061b516 100644 --- a/activerecord/test/cases/readonly_test.rb +++ b/activerecord/test/cases/readonly_test.rb @@ -1,13 +1,13 @@ require "cases/helper" -require 'models/author' -require 'models/post' -require 'models/comment' -require 'models/developer' -require 'models/computer' -require 'models/project' -require 'models/reader' -require 'models/person' -require 'models/ship' +require "models/author" +require "models/post" +require "models/comment" +require "models/developer" +require "models/computer" +require "models/project" +require "models/reader" +require "models/person" +require "models/ship" class ReadOnlyTest < ActiveRecord::TestCase fixtures :authors, :posts, :comments, :developers, :projects, :developers_projects, :people, :readers @@ -20,9 +20,9 @@ class ReadOnlyTest < ActiveRecord::TestCase assert dev.readonly? assert_nothing_raised do - dev.name = 'Luscious forbidden fruit.' + dev.name = "Luscious forbidden fruit." assert !dev.save - dev.name = 'Forbidden.' + dev.name = "Forbidden." end e = assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save } @@ -35,7 +35,6 @@ class ReadOnlyTest < ActiveRecord::TestCase assert_equal "Developer is marked as readonly", e.message end - def test_find_with_readonly_option Developer.all.each { |d| assert !d.readonly? } Developer.readonly(false).each { |d| assert !d.readonly? } @@ -44,11 +43,11 @@ class ReadOnlyTest < ActiveRecord::TestCase end def test_find_with_joins_option_does_not_imply_readonly - Developer.joins(' ').each { |d| assert_not d.readonly? } - Developer.joins(' ').readonly(true).each { |d| assert d.readonly? } + Developer.joins(" ").each { |d| assert_not d.readonly? } + Developer.joins(" ").readonly(true).each { |d| assert d.readonly? } - Developer.joins(', projects').each { |d| assert_not d.readonly? } - Developer.joins(', projects').readonly(true).each { |d| assert d.readonly? } + Developer.joins(", projects").each { |d| assert_not d.readonly? } + Developer.joins(", projects").readonly(true).each { |d| assert d.readonly? } end def test_has_many_find_readonly @@ -77,13 +76,13 @@ class ReadOnlyTest < ActiveRecord::TestCase end def test_readonly_scoping - Post.where('1=1').scoping do + Post.where("1=1").scoping do assert !Post.find(1).readonly? assert Post.readonly(true).find(1).readonly? assert !Post.readonly(false).find(1).readonly? end - Post.joins(' ').scoping do + Post.joins(" ").scoping do assert !Post.find(1).readonly? assert Post.readonly.find(1).readonly? assert !Post.readonly(false).find(1).readonly? @@ -92,7 +91,7 @@ class ReadOnlyTest < ActiveRecord::TestCase # Oracle barfs on this because the join includes unqualified and # conflicting column names unless current_adapter?(:OracleAdapter) - Post.joins(', developers').scoping do + Post.joins(", developers").scoping do assert_not Post.find(1).readonly? assert Post.readonly.find(1).readonly? assert !Post.readonly(false).find(1).readonly? diff --git a/activerecord/test/cases/reaper_test.rb b/activerecord/test/cases/reaper_test.rb index cccfc6774e..249878b67d 100644 --- a/activerecord/test/cases/reaper_test.rb +++ b/activerecord/test/cases/reaper_test.rb @@ -60,7 +60,7 @@ module ActiveRecord def test_connection_pool_starts_reaper spec = ActiveRecord::Base.connection_pool.spec.dup - spec.config[:reaping_frequency] = '0.0001' + spec.config[:reaping_frequency] = "0.0001" pool = ConnectionPool.new spec diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index 710c86b151..5dac3d064b 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -1,30 +1,30 @@ require "cases/helper" -require 'models/topic' -require 'models/customer' -require 'models/company' -require 'models/company_in_module' -require 'models/ship' -require 'models/pirate' -require 'models/price_estimate' -require 'models/essay' -require 'models/author' -require 'models/organization' -require 'models/post' -require 'models/tagging' -require 'models/category' -require 'models/book' -require 'models/subscriber' -require 'models/subscription' -require 'models/tag' -require 'models/sponsor' -require 'models/edge' -require 'models/hotel' -require 'models/chef' -require 'models/department' -require 'models/cake_designer' -require 'models/drink_designer' -require 'models/mocktail_designer' -require 'models/recipe' +require "models/topic" +require "models/customer" +require "models/company" +require "models/company_in_module" +require "models/ship" +require "models/pirate" +require "models/price_estimate" +require "models/essay" +require "models/author" +require "models/organization" +require "models/post" +require "models/tagging" +require "models/category" +require "models/book" +require "models/subscriber" +require "models/subscription" +require "models/tag" +require "models/sponsor" +require "models/edge" +require "models/hotel" +require "models/chef" +require "models/department" +require "models/cake_designer" +require "models/drink_designer" +require "models/mocktail_designer" +require "models/recipe" class ReflectionTest < ActiveRecord::TestCase include ActiveRecord::Reflection @@ -100,7 +100,7 @@ class ReflectionTest < ActiveRecord::TestCase end def test_reflection_klass_for_nested_class_name - reflection = ActiveRecord::Reflection.create(:has_many, nil, nil, { :class_name => 'MyApplication::Business::Company' }, ActiveRecord::Base) + reflection = ActiveRecord::Reflection.create(:has_many, nil, nil, { class_name: "MyApplication::Business::Company" }, ActiveRecord::Base) assert_nothing_raised do assert_equal MyApplication::Business::Company, reflection.klass end @@ -108,28 +108,28 @@ class ReflectionTest < ActiveRecord::TestCase def test_irregular_reflection_class_name ActiveSupport::Inflector.inflections do |inflect| - inflect.irregular 'plural_irregular', 'plurales_irregulares' + inflect.irregular "plural_irregular", "plurales_irregulares" end - reflection = ActiveRecord::Reflection.create(:has_many, 'plurales_irregulares', nil, {}, ActiveRecord::Base) - assert_equal 'PluralIrregular', reflection.class_name + reflection = ActiveRecord::Reflection.create(:has_many, "plurales_irregulares", nil, {}, ActiveRecord::Base) + assert_equal "PluralIrregular", reflection.class_name end def test_aggregation_reflection reflection_for_address = AggregateReflection.new( - :address, nil, { :mapping => [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer + :address, nil, { mapping: [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer ) reflection_for_balance = AggregateReflection.new( - :balance, nil, { :class_name => "Money", :mapping => %w(balance amount) }, Customer + :balance, nil, { class_name: "Money", mapping: %w(balance amount) }, Customer ) reflection_for_gps_location = AggregateReflection.new( - :gps_location, nil, { }, Customer + :gps_location, nil, {}, Customer ) - assert Customer.reflect_on_all_aggregations.include?(reflection_for_gps_location) - assert Customer.reflect_on_all_aggregations.include?(reflection_for_balance) - assert Customer.reflect_on_all_aggregations.include?(reflection_for_address) + assert_includes Customer.reflect_on_all_aggregations, reflection_for_gps_location + assert_includes Customer.reflect_on_all_aggregations, reflection_for_balance + assert_includes Customer.reflect_on_all_aggregations, reflection_for_address assert_equal reflection_for_address, Customer.reflect_on_aggregation(:address) @@ -148,31 +148,31 @@ class ReflectionTest < ActiveRecord::TestCase end def test_has_many_reflection - reflection_for_clients = ActiveRecord::Reflection.create(:has_many, :clients, nil, { :order => "id", :dependent => :destroy }, Firm) + reflection_for_clients = ActiveRecord::Reflection.create(:has_many, :clients, nil, { order: "id", dependent: :destroy }, Firm) assert_equal reflection_for_clients, Firm.reflect_on_association(:clients) assert_equal Client, Firm.reflect_on_association(:clients).klass - assert_equal 'companies', Firm.reflect_on_association(:clients).table_name + assert_equal "companies", Firm.reflect_on_association(:clients).table_name assert_equal Client, Firm.reflect_on_association(:clients_of_firm).klass - assert_equal 'companies', Firm.reflect_on_association(:clients_of_firm).table_name + assert_equal "companies", Firm.reflect_on_association(:clients_of_firm).table_name end def test_has_one_reflection - reflection_for_account = ActiveRecord::Reflection.create(:has_one, :account, nil, { :foreign_key => "firm_id", :dependent => :destroy }, Firm) + reflection_for_account = ActiveRecord::Reflection.create(:has_one, :account, nil, { foreign_key: "firm_id", dependent: :destroy }, Firm) assert_equal reflection_for_account, Firm.reflect_on_association(:account) assert_equal Account, Firm.reflect_on_association(:account).klass - assert_equal 'accounts', Firm.reflect_on_association(:account).table_name + assert_equal "accounts", Firm.reflect_on_association(:account).table_name end def test_belongs_to_inferred_foreign_key_from_assoc_name Company.belongs_to :foo assert_equal "foo_id", Company.reflect_on_association(:foo).foreign_key - Company.belongs_to :bar, :class_name => "Xyzzy" + Company.belongs_to :bar, class_name: "Xyzzy" assert_equal "bar_id", Company.reflect_on_association(:bar).foreign_key - Company.belongs_to :baz, :class_name => "Xyzzy", :foreign_key => "xyzzy_id" + Company.belongs_to :baz, class_name: "Xyzzy", foreign_key: "xyzzy_id" assert_equal "xyzzy_id", Company.reflect_on_association(:baz).foreign_key end @@ -181,45 +181,45 @@ class ReflectionTest < ActiveRecord::TestCase assert_reflection MyApplication::Business::Firm, :clients_of_firm, - :klass => MyApplication::Business::Client, - :class_name => 'Client', - :table_name => 'companies' + klass: MyApplication::Business::Client, + class_name: "Client", + table_name: "companies" assert_reflection MyApplication::Billing::Account, :firm, - :klass => MyApplication::Business::Firm, - :class_name => 'MyApplication::Business::Firm', - :table_name => 'companies' + klass: MyApplication::Business::Firm, + class_name: "MyApplication::Business::Firm", + table_name: "companies" assert_reflection MyApplication::Billing::Account, :qualified_billing_firm, - :klass => MyApplication::Billing::Firm, - :class_name => 'MyApplication::Billing::Firm', - :table_name => 'companies' + klass: MyApplication::Billing::Firm, + class_name: "MyApplication::Billing::Firm", + table_name: "companies" assert_reflection MyApplication::Billing::Account, :unqualified_billing_firm, - :klass => MyApplication::Billing::Firm, - :class_name => 'Firm', - :table_name => 'companies' + klass: MyApplication::Billing::Firm, + class_name: "Firm", + table_name: "companies" assert_reflection MyApplication::Billing::Account, :nested_qualified_billing_firm, - :klass => MyApplication::Billing::Nested::Firm, - :class_name => 'MyApplication::Billing::Nested::Firm', - :table_name => 'companies' + klass: MyApplication::Billing::Nested::Firm, + class_name: "MyApplication::Billing::Nested::Firm", + table_name: "companies" assert_reflection MyApplication::Billing::Account, :nested_unqualified_billing_firm, - :klass => MyApplication::Billing::Nested::Firm, - :class_name => 'Nested::Firm', - :table_name => 'companies' + klass: MyApplication::Billing::Nested::Firm, + class_name: "Nested::Firm", + table_name: "companies" ensure ActiveRecord::Base.store_full_sti_class = true end def test_reflection_should_not_raise_error_when_compared_to_other_object - assert_not_equal Object.new, Firm._reflections['clients'] + assert_not_equal Object.new, Firm._reflections["clients"] end def test_reflections_should_return_keys_as_strings @@ -227,7 +227,7 @@ class ReflectionTest < ActiveRecord::TestCase end def test_has_and_belongs_to_many_reflection - assert_equal :has_and_belongs_to_many, Category.reflections['posts'].macro + assert_equal :has_and_belongs_to_many, Category.reflections["posts"].macro assert_equal :posts, Category.reflect_on_all_associations(:has_and_belongs_to_many).first.name end @@ -366,21 +366,21 @@ class ReflectionTest < ActiveRecord::TestCase end def test_always_validate_association_if_explicit - assert ActiveRecord::Reflection.create(:has_one, :client, nil, { :validate => true }, Firm).validate? - assert ActiveRecord::Reflection.create(:belongs_to, :client, nil, { :validate => true }, Firm).validate? - assert ActiveRecord::Reflection.create(:has_many, :clients, nil, { :validate => true }, Firm).validate? + assert ActiveRecord::Reflection.create(:has_one, :client, nil, { validate: true }, Firm).validate? + assert ActiveRecord::Reflection.create(:belongs_to, :client, nil, { validate: true }, Firm).validate? + assert ActiveRecord::Reflection.create(:has_many, :clients, nil, { validate: true }, Firm).validate? end def test_validate_association_if_autosave - assert ActiveRecord::Reflection.create(:has_one, :client, nil, { :autosave => true }, Firm).validate? - assert ActiveRecord::Reflection.create(:belongs_to, :client, nil, { :autosave => true }, Firm).validate? - assert ActiveRecord::Reflection.create(:has_many, :clients, nil, { :autosave => true }, Firm).validate? + assert ActiveRecord::Reflection.create(:has_one, :client, nil, { autosave: true }, Firm).validate? + assert ActiveRecord::Reflection.create(:belongs_to, :client, nil, { autosave: true }, Firm).validate? + assert ActiveRecord::Reflection.create(:has_many, :clients, nil, { autosave: true }, Firm).validate? end def test_never_validate_association_if_explicit - assert !ActiveRecord::Reflection.create(:has_one, :client, nil, { :autosave => true, :validate => false }, Firm).validate? - assert !ActiveRecord::Reflection.create(:belongs_to, :client, nil, { :autosave => true, :validate => false }, Firm).validate? - assert !ActiveRecord::Reflection.create(:has_many, :clients, nil, { :autosave => true, :validate => false }, Firm).validate? + assert !ActiveRecord::Reflection.create(:has_one, :client, nil, { autosave: true, validate: false }, Firm).validate? + assert !ActiveRecord::Reflection.create(:belongs_to, :client, nil, { autosave: true, validate: false }, Firm).validate? + assert !ActiveRecord::Reflection.create(:has_many, :clients, nil, { autosave: true, validate: false }, Firm).validate? end def test_foreign_key @@ -399,62 +399,62 @@ class ReflectionTest < ActiveRecord::TestCase end def test_join_table - category = Struct.new(:table_name, :pluralize_table_names).new('categories', true) - product = Struct.new(:table_name, :pluralize_table_names).new('products', true) + category = Struct.new(:table_name, :pluralize_table_names).new("categories", true) + product = Struct.new(:table_name, :pluralize_table_names).new("products", true) reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, {}, product) reflection.stub(:klass, category) do - assert_equal 'categories_products', reflection.join_table + assert_equal "categories_products", reflection.join_table end reflection = ActiveRecord::Reflection.create(:has_many, :products, nil, {}, category) reflection.stub(:klass, product) do - assert_equal 'categories_products', reflection.join_table + assert_equal "categories_products", reflection.join_table end end def test_join_table_with_common_prefix - category = Struct.new(:table_name, :pluralize_table_names).new('catalog_categories', true) - product = Struct.new(:table_name, :pluralize_table_names).new('catalog_products', true) + category = Struct.new(:table_name, :pluralize_table_names).new("catalog_categories", true) + product = Struct.new(:table_name, :pluralize_table_names).new("catalog_products", true) reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, {}, product) reflection.stub(:klass, category) do - assert_equal 'catalog_categories_products', reflection.join_table + assert_equal "catalog_categories_products", reflection.join_table end reflection = ActiveRecord::Reflection.create(:has_many, :products, nil, {}, category) reflection.stub(:klass, product) do - assert_equal 'catalog_categories_products', reflection.join_table + assert_equal "catalog_categories_products", reflection.join_table end end def test_join_table_with_different_prefix - category = Struct.new(:table_name, :pluralize_table_names).new('catalog_categories', true) - page = Struct.new(:table_name, :pluralize_table_names).new('content_pages', true) + category = Struct.new(:table_name, :pluralize_table_names).new("catalog_categories", true) + page = Struct.new(:table_name, :pluralize_table_names).new("content_pages", true) reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, {}, page) reflection.stub(:klass, category) do - assert_equal 'catalog_categories_content_pages', reflection.join_table + assert_equal "catalog_categories_content_pages", reflection.join_table end reflection = ActiveRecord::Reflection.create(:has_many, :pages, nil, {}, category) reflection.stub(:klass, page) do - assert_equal 'catalog_categories_content_pages', reflection.join_table + assert_equal "catalog_categories_content_pages", reflection.join_table end end def test_join_table_can_be_overridden - category = Struct.new(:table_name, :pluralize_table_names).new('categories', true) - product = Struct.new(:table_name, :pluralize_table_names).new('products', true) + category = Struct.new(:table_name, :pluralize_table_names).new("categories", true) + product = Struct.new(:table_name, :pluralize_table_names).new("products", true) - reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, { :join_table => 'product_categories' }, product) + reflection = ActiveRecord::Reflection.create(:has_many, :categories, nil, { join_table: "product_categories" }, product) reflection.stub(:klass, category) do - assert_equal 'product_categories', reflection.join_table + assert_equal "product_categories", reflection.join_table end - reflection = ActiveRecord::Reflection.create(:has_many, :products, nil, { :join_table => 'product_categories' }, category) + reflection = ActiveRecord::Reflection.create(:has_many, :products, nil, { join_table: "product_categories" }, category) reflection.stub(:klass, product) do - assert_equal 'product_categories', reflection.join_table + assert_equal "product_categories", reflection.join_table end end @@ -474,7 +474,7 @@ class ReflectionTest < ActiveRecord::TestCase department.chefs.create! assert_nothing_raised do - assert_equal department.chefs, Hotel.includes(['departments' => 'chefs']).first.chefs + assert_equal department.chefs, Hotel.includes(["departments" => "chefs"]).first.chefs end end diff --git a/activerecord/test/cases/relation/delegation_test.rb b/activerecord/test/cases/relation/delegation_test.rb index f0e07e0731..d2382b9bb2 100644 --- a/activerecord/test/cases/relation/delegation_test.rb +++ b/activerecord/test/cases/relation/delegation_test.rb @@ -1,6 +1,6 @@ -require 'cases/helper' -require 'models/post' -require 'models/comment' +require "cases/helper" +require "models/post" +require "models/comment" module ActiveRecord class DelegationTest < ActiveRecord::TestCase @@ -18,7 +18,7 @@ module ActiveRecord target.public_send(method, 1) end elsif method_arity == 1 - target.public_send(method, 1) + target.public_send(method, 1) else raise NotImplementedError end diff --git a/activerecord/test/cases/relation/merging_test.rb b/activerecord/test/cases/relation/merging_test.rb index 60a806c05a..278dac8171 100644 --- a/activerecord/test/cases/relation/merging_test.rb +++ b/activerecord/test/cases/relation/merging_test.rb @@ -1,20 +1,20 @@ -require 'cases/helper' -require 'models/author' -require 'models/comment' -require 'models/developer' -require 'models/computer' -require 'models/post' -require 'models/project' -require 'models/rating' +require "cases/helper" +require "models/author" +require "models/comment" +require "models/developer" +require "models/computer" +require "models/post" +require "models/project" +require "models/rating" class RelationMergingTest < ActiveRecord::TestCase fixtures :developers, :comments, :authors, :posts def test_relation_merging - devs = Developer.where("salary >= 80000").merge(Developer.limit(2)).merge(Developer.order('id ASC').where("id < 3")) + devs = Developer.where("salary >= 80000").merge(Developer.limit(2)).merge(Developer.order("id ASC").where("id < 3")) assert_equal [developers(:david), developers(:jamis)], devs.to_a - dev_with_count = Developer.limit(1).merge(Developer.order('id DESC')).merge(Developer.select('developers.*')) + dev_with_count = Developer.limit(1).merge(Developer.order("id DESC")).merge(Developer.select("developers.*")) assert_equal [developers(:poor_jamis)], dev_with_count.to_a end @@ -34,10 +34,10 @@ class RelationMergingTest < ActiveRecord::TestCase def test_relation_merging_with_arel_equalities_keeps_last_equality_with_non_attribute_left_hand salary_attr = Developer.arel_table[:salary] devs = Developer.where( - Arel::Nodes::NamedFunction.new('abs', [salary_attr]).eq(80000) + Arel::Nodes::NamedFunction.new("abs", [salary_attr]).eq(80000) ).merge( Developer.where( - Arel::Nodes::NamedFunction.new('abs', [salary_attr]).eq(9000) + Arel::Nodes::NamedFunction.new("abs", [salary_attr]).eq(9000) ) ) assert_equal [developers(:poor_jamis)], devs.to_a @@ -45,8 +45,8 @@ class RelationMergingTest < ActiveRecord::TestCase def test_relation_merging_with_eager_load relations = [] - relations << Post.order('comments.id DESC').merge(Post.eager_load(:last_comment)).merge(Post.all) - relations << Post.eager_load(:last_comment).merge(Post.order('comments.id DESC')).merge(Post.all) + relations << Post.order("comments.id DESC").merge(Post.eager_load(:last_comment)).merge(Post.all) + relations << Post.eager_load(:last_comment).merge(Post.order("comments.id DESC")).merge(Post.all) relations.each do |posts| post = posts.find { |p| p.id == 1 } @@ -66,14 +66,14 @@ class RelationMergingTest < ActiveRecord::TestCase end def test_relation_merging_with_joins - comments = Comment.joins(:post).where(:body => 'Thank you for the welcome').merge(Post.where(:body => 'Such a lovely day')) + comments = Comment.joins(:post).where(body: "Thank you for the welcome").merge(Post.where(body: "Such a lovely day")) assert_equal 1, comments.count end def test_relation_merging_with_association assert_queries(2) do # one for loading post, and another one merged query - post = Post.where(:body => 'Such a lovely day').first - comments = Comment.where(:body => 'Thank you for the welcome').merge(post.comments) + post = Post.where(body: "Such a lovely day").first + comments = Comment.where(body: "Thank you for the welcome").merge(post.comments) assert_equal 1, comments.count end end @@ -86,9 +86,9 @@ class RelationMergingTest < ActiveRecord::TestCase merged = left.merge(right) assert_equal expected, merged.bound_attributes - assert !merged.to_sql.include?("omg") - assert merged.to_sql.include?("wtf") - assert merged.to_sql.include?("bbq") + assert_not_includes merged.to_sql, "omg" + assert_includes merged.to_sql, "wtf" + assert_includes merged.to_sql, "bbq" end def test_merging_reorders_bind_params diff --git a/activerecord/test/cases/relation/mutation_test.rb b/activerecord/test/cases/relation/mutation_test.rb index ffb2da7a26..966ae83a3f 100644 --- a/activerecord/test/cases/relation/mutation_test.rb +++ b/activerecord/test/cases/relation/mutation_test.rb @@ -1,8 +1,8 @@ -require 'cases/helper' -require 'models/post' +require "cases/helper" +require "models/post" module ActiveRecord - class RelationMutationTest < ActiveSupport::TestCase + class RelationMutationTest < ActiveRecord::TestCase class FakeKlass < Struct.new(:table_name, :name) extend ActiveRecord::Delegation::DelegateCache inherited self @@ -33,7 +33,7 @@ module ActiveRecord end def relation - @relation ||= Relation.new FakeKlass.new('posts'), Post.arel_table, Post.predicate_builder + @relation ||= Relation.new FakeKlass.new("posts"), Post.arel_table, Post.predicate_builder end (Relation::MULTI_VALUE_METHODS - [:references, :extending, :order, :unscope, :select, :left_joins]).each do |method| @@ -44,16 +44,16 @@ module ActiveRecord end test "#_select!" do - assert relation.public_send("_select!", :foo).equal?(relation) - assert_equal [:foo], relation.public_send("select_values") + assert relation._select!(:foo).equal?(relation) + assert_equal [:foo], relation.select_values end - test '#order!' do - assert relation.order!('name ASC').equal?(relation) - assert_equal ['name ASC'], relation.order_values + test "#order!" do + assert relation.order!("name ASC").equal?(relation) + assert_equal ["name ASC"], relation.order_values end - test '#order! with symbol prepends the table name' do + test "#order! with symbol prepends the table name" do assert relation.order!(:name).equal?(relation) node = relation.order_values.first assert node.ascending? @@ -61,7 +61,7 @@ module ActiveRecord assert_equal "posts", node.expr.relation.name end - test '#order! on non-string does not attempt regexp match for references' do + test "#order! on non-string does not attempt regexp match for references" do obj = Object.new assert_not_called(obj, :=~) do assert relation.order!(obj) @@ -69,12 +69,12 @@ module ActiveRecord end end - test '#references!' do + test "#references!" do assert relation.references!(:foo).equal?(relation) - assert relation.references_values.include?('foo') + assert_includes relation.references_values, "foo" end - test 'extending!' do + test "extending!" do mod, mod2 = Module.new, Module.new assert relation.extending!(mod).equal?(relation) @@ -85,7 +85,7 @@ module ActiveRecord assert_equal [mod, mod2], relation.extending_values end - test 'extending! with empty args' do + test "extending! with empty args" do relation.extending! assert_equal [], relation.extending_values end @@ -97,25 +97,25 @@ module ActiveRecord end end - test '#from!' do - assert relation.from!('foo').equal?(relation) - assert_equal 'foo', relation.from_clause.value + test "#from!" do + assert relation.from!("foo").equal?(relation) + assert_equal "foo", relation.from_clause.value end - test '#lock!' do - assert relation.lock!('foo').equal?(relation) - assert_equal 'foo', relation.lock_value + test "#lock!" do + assert relation.lock!("foo").equal?(relation) + assert_equal "foo", relation.lock_value end - test '#reorder!' do - @relation = self.relation.order('foo') + test "#reorder!" do + @relation = self.relation.order("foo") - assert relation.reorder!('bar').equal?(relation) - assert_equal ['bar'], relation.order_values + assert relation.reorder!("bar").equal?(relation) + assert_equal ["bar"], relation.order_values assert relation.reordering_value end - test '#reorder! with symbol prepends the table name' do + test "#reorder! with symbol prepends the table name" do assert relation.reorder!(:name).equal?(relation) node = relation.order_values.first @@ -124,42 +124,41 @@ module ActiveRecord assert_equal "posts", node.expr.relation.name end - test 'reverse_order!' do - @relation = Post.order('title ASC, comments_count DESC') + test "reverse_order!" do + @relation = Post.order("title ASC, comments_count DESC") relation.reverse_order! - assert_equal 'title DESC', relation.order_values.first - assert_equal 'comments_count ASC', relation.order_values.last - + assert_equal "title DESC", relation.order_values.first + assert_equal "comments_count ASC", relation.order_values.last relation.reverse_order! - assert_equal 'title ASC', relation.order_values.first - assert_equal 'comments_count DESC', relation.order_values.last + assert_equal "title ASC", relation.order_values.first + assert_equal "comments_count DESC", relation.order_values.last end - test 'create_with!' do - assert relation.create_with!(foo: 'bar').equal?(relation) - assert_equal({foo: 'bar'}, relation.create_with_value) + test "create_with!" do + assert relation.create_with!(foo: "bar").equal?(relation) + assert_equal({ foo: "bar" }, relation.create_with_value) end - test 'test_merge!' do + test "test_merge!" do assert relation.merge!(select: :foo).equal?(relation) assert_equal [:foo], relation.select_values end - test 'merge with a proc' do + test "merge with a proc" do assert_equal [:foo], relation.merge(-> { select(:foo) }).select_values end - test 'none!' do + test "none!" do assert relation.none!.equal?(relation) assert_equal [NullRelation], relation.extending_values assert relation.is_a?(NullRelation) end - test 'distinct!' do + test "distinct!" do relation.distinct! :foo assert_equal :foo, relation.distinct_value @@ -168,7 +167,7 @@ module ActiveRecord end end - test 'uniq! was replaced by distinct!' do + test "uniq! was replaced by distinct!" do assert_deprecated(/use distinct! instead/) do relation.uniq! :foo end diff --git a/activerecord/test/cases/relation/or_test.rb b/activerecord/test/cases/relation/or_test.rb index ce8c5ca489..2796595523 100644 --- a/activerecord/test/cases/relation/or_test.rb +++ b/activerecord/test/cases/relation/or_test.rb @@ -1,28 +1,28 @@ require "cases/helper" -require 'models/post' +require "models/post" module ActiveRecord class OrTest < ActiveRecord::TestCase fixtures :posts def test_or_with_relation - expected = Post.where('id = 1 or id = 2').to_a - assert_equal expected, Post.where('id = 1').or(Post.where('id = 2')).to_a + expected = Post.where("id = 1 or id = 2").to_a + assert_equal expected, Post.where("id = 1").or(Post.where("id = 2")).to_a end def test_or_identity - expected = Post.where('id = 1').to_a - assert_equal expected, Post.where('id = 1').or(Post.where('id = 1')).to_a + expected = Post.where("id = 1").to_a + assert_equal expected, Post.where("id = 1").or(Post.where("id = 1")).to_a end def test_or_with_null_left - expected = Post.where('id = 1').to_a - assert_equal expected, Post.none.or(Post.where('id = 1')).to_a + expected = Post.where("id = 1").to_a + assert_equal expected, Post.none.or(Post.where("id = 1")).to_a end def test_or_with_null_right - expected = Post.where('id = 1').to_a - assert_equal expected, Post.where('id = 1').or(Post.none).to_a + expected = Post.where("id = 1").to_a + assert_equal expected, Post.where("id = 1").or(Post.none).to_a end def test_or_with_bind_params @@ -36,56 +36,56 @@ module ActiveRecord def test_or_without_left_where expected = Post.all - assert_equal expected, Post.or(Post.where('id = 1')).to_a + assert_equal expected, Post.or(Post.where("id = 1")).to_a end def test_or_without_right_where expected = Post.all - assert_equal expected, Post.where('id = 1').or(Post.all).to_a + assert_equal expected, Post.where("id = 1").or(Post.all).to_a end def test_or_preserves_other_querying_methods - expected = Post.where('id = 1 or id = 2 or id = 3').order('body asc').to_a - partial = Post.order('body asc') - assert_equal expected, partial.where('id = 1').or(partial.where(:id => [2, 3])).to_a - assert_equal expected, Post.order('body asc').where('id = 1').or(Post.order('body asc').where(:id => [2, 3])).to_a + expected = Post.where("id = 1 or id = 2 or id = 3").order("body asc").to_a + partial = Post.order("body asc") + assert_equal expected, partial.where("id = 1").or(partial.where(id: [2, 3])).to_a + assert_equal expected, Post.order("body asc").where("id = 1").or(Post.order("body asc").where(id: [2, 3])).to_a end def test_or_with_incompatible_relations error = assert_raises ArgumentError do - Post.order('body asc').where('id = 1').or(Post.order('id desc').where(:id => [2, 3])).to_a + Post.order("body asc").where("id = 1").or(Post.order("id desc").where(id: [2, 3])).to_a end assert_equal "Relation passed to #or must be structurally compatible. Incompatible values: [:order]", error.message end def test_or_when_grouping - groups = Post.where('id < 10').group('body').select('body, COUNT(*) AS c') - expected = groups.having("COUNT(*) > 1 OR body like 'Such%'").to_a.map {|o| [o.body, o.c] } - assert_equal expected, groups.having('COUNT(*) > 1').or(groups.having("body like 'Such%'")).to_a.map {|o| [o.body, o.c] } + groups = Post.where("id < 10").group("body").select("body, COUNT(*) AS c") + expected = groups.having("COUNT(*) > 1 OR body like 'Such%'").to_a.map { |o| [o.body, o.c] } + assert_equal expected, groups.having("COUNT(*) > 1").or(groups.having("body like 'Such%'")).to_a.map { |o| [o.body, o.c] } end def test_or_with_named_scope expected = Post.where("id = 1 or body LIKE '\%a\%'").to_a - assert_equal expected, Post.where('id = 1').or(Post.containing_the_letter_a) + assert_equal expected, Post.where("id = 1").or(Post.containing_the_letter_a) end def test_or_inside_named_scope - expected = Post.where("body LIKE '\%a\%' OR title LIKE ?", "%'%").order('id DESC').to_a + expected = Post.where("body LIKE '\%a\%' OR title LIKE ?", "%'%").order("id DESC").to_a assert_equal expected, Post.order(id: :desc).typographically_interesting end def test_or_on_loaded_relation - expected = Post.where('id = 1 or id = 2').to_a - p = Post.where('id = 1') + expected = Post.where("id = 1 or id = 2").to_a + p = Post.where("id = 1") p.load assert_equal p.loaded?, true - assert_equal expected, p.or(Post.where('id = 2')).to_a + assert_equal expected, p.or(Post.where("id = 2")).to_a end def test_or_with_non_relation_object_raises_error assert_raises ArgumentError do - Post.where(id: [1, 2, 3]).or(title: 'Rails') + Post.where(id: [1, 2, 3]).or(title: "Rails") end end end diff --git a/activerecord/test/cases/relation/predicate_builder_test.rb b/activerecord/test/cases/relation/predicate_builder_test.rb index 8f62014622..48758dc148 100644 --- a/activerecord/test/cases/relation/predicate_builder_test.rb +++ b/activerecord/test/cases/relation/predicate_builder_test.rb @@ -1,11 +1,11 @@ require "cases/helper" -require 'models/topic' +require "models/topic" module ActiveRecord class PredicateBuilderTest < ActiveRecord::TestCase def test_registering_new_handlers Topic.predicate_builder.register_handler(Regexp, proc do |column, value| - Arel::Nodes::InfixOperation.new('~', column, Arel.sql(value.source)) + Arel::Nodes::InfixOperation.new("~", column, Arel.sql(value.source)) end) assert_match %r{["`]topics["`]\.["`]title["`] ~ rails}i, Topic.where(title: /rails/).to_sql diff --git a/activerecord/test/cases/relation/record_fetch_warning_test.rb b/activerecord/test/cases/relation/record_fetch_warning_test.rb index 0e0e23b24b..62ca051431 100644 --- a/activerecord/test/cases/relation/record_fetch_warning_test.rb +++ b/activerecord/test/cases/relation/record_fetch_warning_test.rb @@ -1,6 +1,6 @@ -require 'cases/helper' -require 'models/post' -require 'active_record/relation/record_fetch_warning' +require "cases/helper" +require "models/post" +require "active_record/relation/record_fetch_warning" module ActiveRecord class RecordFetchWarningTest < ActiveRecord::TestCase diff --git a/activerecord/test/cases/relation/where_chain_test.rb b/activerecord/test/cases/relation/where_chain_test.rb index 27bbd80f79..a96d1ae5b5 100644 --- a/activerecord/test/cases/relation/where_chain_test.rb +++ b/activerecord/test/cases/relation/where_chain_test.rb @@ -1,6 +1,6 @@ -require 'cases/helper' -require 'models/post' -require 'models/comment' +require "cases/helper" +require "models/post" +require "models/comment" module ActiveRecord class WhereChainTest < ActiveRecord::TestCase @@ -8,12 +8,12 @@ module ActiveRecord def setup super - @name = 'title' + @name = "title" end def test_not_inverts_where_clause - relation = Post.where.not(title: 'hello') - expected_where_clause = Post.where(title: 'hello').where_clause.invert + relation = Post.where.not(title: "hello") + expected_where_clause = Post.where(title: "hello").where_clause.invert assert_equal expected_where_clause, relation.where_clause end @@ -26,54 +26,54 @@ module ActiveRecord def test_association_not_eq expected = Arel::Nodes::Grouping.new(Comment.arel_table[@name].not_eq(Arel::Nodes::BindParam.new)) - relation = Post.joins(:comments).where.not(comments: {title: 'hello'}) + relation = Post.joins(:comments).where.not(comments: { title: "hello" }) assert_equal(expected.to_sql, relation.where_clause.ast.to_sql) end def test_not_eq_with_preceding_where - relation = Post.where(title: 'hello').where.not(title: 'world') + relation = Post.where(title: "hello").where.not(title: "world") expected_where_clause = - Post.where(title: 'hello').where_clause + - Post.where(title: 'world').where_clause.invert + Post.where(title: "hello").where_clause + + Post.where(title: "world").where_clause.invert assert_equal expected_where_clause, relation.where_clause end def test_not_eq_with_succeeding_where - relation = Post.where.not(title: 'hello').where(title: 'world') + relation = Post.where.not(title: "hello").where(title: "world") expected_where_clause = - Post.where(title: 'hello').where_clause.invert + - Post.where(title: 'world').where_clause + Post.where(title: "hello").where_clause.invert + + Post.where(title: "world").where_clause assert_equal expected_where_clause, relation.where_clause end def test_chaining_multiple - relation = Post.where.not(author_id: [1, 2]).where.not(title: 'ruby on rails') + relation = Post.where.not(author_id: [1, 2]).where.not(title: "ruby on rails") expected_where_clause = Post.where(author_id: [1, 2]).where_clause.invert + - Post.where(title: 'ruby on rails').where_clause.invert + Post.where(title: "ruby on rails").where_clause.invert assert_equal expected_where_clause, relation.where_clause end def test_rewhere_with_one_condition - relation = Post.where(title: 'hello').where(title: 'world').rewhere(title: 'alone') - expected = Post.where(title: 'alone') + relation = Post.where(title: "hello").where(title: "world").rewhere(title: "alone") + expected = Post.where(title: "alone") assert_equal expected.where_clause, relation.where_clause end def test_rewhere_with_multiple_overwriting_conditions - relation = Post.where(title: 'hello').where(body: 'world').rewhere(title: 'alone', body: 'again') - expected = Post.where(title: 'alone', body: 'again') + relation = Post.where(title: "hello").where(body: "world").rewhere(title: "alone", body: "again") + expected = Post.where(title: "alone", body: "again") assert_equal expected.where_clause, relation.where_clause end def test_rewhere_with_one_overwriting_condition_and_one_unrelated - relation = Post.where(title: 'hello').where(body: 'world').rewhere(title: 'alone') - expected = Post.where(body: 'world', title: 'alone') + relation = Post.where(title: "hello").where(body: "world").rewhere(title: "alone") + expected = Post.where(body: "world", title: "alone") assert_equal expected.where_clause, relation.where_clause end diff --git a/activerecord/test/cases/relation/where_clause_test.rb b/activerecord/test/cases/relation/where_clause_test.rb index c20ed94d90..d8e4c304f0 100644 --- a/activerecord/test/cases/relation/where_clause_test.rb +++ b/activerecord/test/cases/relation/where_clause_test.rb @@ -140,7 +140,7 @@ class ActiveRecord::Relation test "ast removes any empty strings" do where_clause = WhereClause.new([table["id"].in([1, 2, 3])], []) - where_clause_with_empty = WhereClause.new([table["id"].in([1, 2, 3]), ''], []) + where_clause_with_empty = WhereClause.new([table["id"].in([1, 2, 3]), ""], []) assert_equal where_clause.ast, where_clause_with_empty.ast end @@ -167,16 +167,16 @@ class ActiveRecord::Relation private - def table - Arel::Table.new("table") - end + def table + Arel::Table.new("table") + end - def bind_param - Arel::Nodes::BindParam.new - end + def bind_param + Arel::Nodes::BindParam.new + end - def attribute(name, value) - ActiveRecord::Attribute.with_cast_value(name, value, ActiveRecord::Type::Value.new) - end + def attribute(name, value) + ActiveRecord::Attribute.with_cast_value(name, value, ActiveRecord::Type::Value.new) + end end end diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb index 56a2b5b8c6..925af49ffe 100644 --- a/activerecord/test/cases/relation/where_test.rb +++ b/activerecord/test/cases/relation/where_test.rb @@ -4,10 +4,10 @@ require "models/binary" require "models/cake_designer" require "models/car" require "models/chef" +require "models/post" require "models/comment" require "models/edge" require "models/essay" -require "models/post" require "models/price_estimate" require "models/topic" require "models/treasure" @@ -19,7 +19,7 @@ module ActiveRecord def test_where_copies_bind_params author = authors(:david) - posts = author.posts.where('posts.id != 1') + posts = author.posts.where("posts.id != 1") joined = Post.where(id: posts) assert_operator joined.length, :>, 0 @@ -49,7 +49,7 @@ module ActiveRecord end def test_rewhere_on_root - assert_equal posts(:welcome), Post.rewhere(title: 'Welcome to the weblog').first + assert_equal posts(:welcome), Post.rewhere(title: "Welcome to the weblog").first end def test_belongs_to_shallow_where @@ -97,7 +97,7 @@ module ActiveRecord treasure = Treasure.new treasure.id = 1 - expected = PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: 1) + expected = PriceEstimate.where(estimate_of_type: "Treasure", estimate_of_id: 1) actual = PriceEstimate.where(estimate_of: treasure) assert_equal expected.to_sql, actual.to_sql @@ -109,7 +109,7 @@ module ActiveRecord hidden = HiddenTreasure.new hidden.id = 2 - expected = PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: [treasure, hidden]) + expected = PriceEstimate.where(estimate_of_type: "Treasure", estimate_of_id: [treasure, hidden]) actual = PriceEstimate.where(estimate_of: [treasure, hidden]) assert_equal expected.to_sql, actual.to_sql @@ -127,7 +127,7 @@ module ActiveRecord end def test_polymorphic_nested_relation_where - expected = PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: Treasure.where(id: [1,2])) + expected = PriceEstimate.where(estimate_of_type: "Treasure", estimate_of_id: Treasure.where(id: [1,2])) actual = PriceEstimate.where(estimate_of: Treasure.where(id: [1,2])) assert_equal expected.to_sql, actual.to_sql @@ -137,7 +137,7 @@ module ActiveRecord treasure = HiddenTreasure.new treasure.id = 1 - expected = PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: 1) + expected = PriceEstimate.where(estimate_of_type: "Treasure", estimate_of_id: 1) actual = PriceEstimate.where(estimate_of: treasure) assert_equal expected.to_sql, actual.to_sql @@ -147,7 +147,7 @@ module ActiveRecord thing = Post.new thing.id = 1 - expected = Treasure.where(price_estimates: { thing_type: 'Post', thing_id: 1 }).joins(:price_estimates) + expected = Treasure.where(price_estimates: { thing_type: "Post", thing_id: 1 }).joins(:price_estimates) actual = Treasure.where(price_estimates: { thing: thing }).joins(:price_estimates) assert_equal expected.to_sql, actual.to_sql @@ -157,7 +157,7 @@ module ActiveRecord treasure = HiddenTreasure.new treasure.id = 1 - expected = Treasure.where(price_estimates: { estimate_of_type: 'Treasure', estimate_of_id: 1 }).joins(:price_estimates) + expected = Treasure.where(price_estimates: { estimate_of_type: "Treasure", estimate_of_id: 1 }).joins(:price_estimates) actual = Treasure.where(price_estimates: { estimate_of: treasure }).joins(:price_estimates) assert_equal expected.to_sql, actual.to_sql @@ -182,40 +182,40 @@ module ActiveRecord treasure.id = 1 decorated_treasure = treasure_decorator.new(treasure) - expected = PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: 1) + expected = PriceEstimate.where(estimate_of_type: "Treasure", estimate_of_id: 1) actual = PriceEstimate.where(estimate_of: decorated_treasure) assert_equal expected.to_sql, actual.to_sql end def test_aliased_attribute - expected = Topic.where(heading: 'The First Topic') - actual = Topic.where(title: 'The First Topic') + expected = Topic.where(heading: "The First Topic") + actual = Topic.where(title: "The First Topic") assert_equal expected.to_sql, actual.to_sql end def test_where_error - assert_raises(ActiveRecord::StatementInvalid) do - Post.where(:id => { 'posts.author_id' => 10 }).first + assert_nothing_raised do + Post.where(id: { "posts.author_id" => 10 }).first end end def test_where_with_table_name post = Post.first - assert_equal post, Post.where(:posts => { 'id' => post.id }).first + assert_equal post, Post.where(posts: { "id" => post.id }).first end def test_where_with_table_name_and_empty_hash - assert_equal 0, Post.where(:posts => {}).count + assert_equal 0, Post.where(posts: {}).count end def test_where_with_table_name_and_empty_array - assert_equal 0, Post.where(:id => []).count + assert_equal 0, Post.where(id: []).count end def test_where_with_empty_hash_and_no_foreign_key - assert_equal 0, Edge.where(:sink => {}).count + assert_equal 0, Edge.where(sink: {}).count end def test_where_with_blank_conditions @@ -225,32 +225,32 @@ module ActiveRecord end def test_where_with_integer_for_string_column - count = Post.where(:title => 0).count + count = Post.where(title: 0).count assert_equal 0, count end def test_where_with_float_for_string_column - count = Post.where(:title => 0.0).count + count = Post.where(title: 0.0).count assert_equal 0, count end def test_where_with_boolean_for_string_column - count = Post.where(:title => false).count + count = Post.where(title: false).count assert_equal 0, count end def test_where_with_decimal_for_string_column - count = Post.where(:title => BigDecimal.new(0)).count + count = Post.where(title: BigDecimal.new(0)).count assert_equal 0, count end def test_where_with_duration_for_string_column - count = Post.where(:title => 0.seconds).count + count = Post.where(title: 0.seconds).count assert_equal 0, count end def test_where_with_integer_for_binary_column - count = Binary.where(:data => 0).count + count = Binary.where(data: 0).count assert_equal 0, count end diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 03583344a8..23d27ab90a 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -1,8 +1,8 @@ require "cases/helper" -require 'models/post' -require 'models/comment' -require 'models/author' -require 'models/rating' +require "models/post" +require "models/comment" +require "models/author" +require "models/rating" module ActiveRecord class RelationTest < ActiveRecord::TestCase @@ -18,7 +18,7 @@ module ActiveRecord end def self.table_name - 'fake_table' + "fake_table" end def self.sanitize_sql_for_order(sql) @@ -30,7 +30,7 @@ module ActiveRecord relation = Relation.new(FakeKlass, :b, nil) assert_equal FakeKlass, relation.klass assert_equal :b, relation.table - assert !relation.loaded, 'relation is not loaded' + assert !relation.loaded, "relation is not loaded" end def test_responds_to_model_and_returns_klass @@ -40,9 +40,10 @@ module ActiveRecord def test_initialize_single_values relation = Relation.new(FakeKlass, :b, nil) - (Relation::SINGLE_VALUE_METHODS - [:create_with]).each do |method| + (Relation::SINGLE_VALUE_METHODS - [:create_with, :readonly]).each do |method| assert_nil relation.send("#{method}_value"), method.to_s end + assert_equal false, relation.readonly_value value = relation.create_with_value assert_equal({}, value) assert_predicate value, :frozen? @@ -70,7 +71,7 @@ module ActiveRecord def test_has_values relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) relation.where! relation.table[:id].eq(10) - assert_equal({:id => 10}, relation.where_values_hash) + assert_equal({ id: 10 }, relation.where_values_hash) end def test_values_wrong_table @@ -89,8 +90,8 @@ module ActiveRecord end def test_table_name_delegates_to_klass - relation = Relation.new(FakeKlass.new('posts'), :b, Post.predicate_builder) - assert_equal 'posts', relation.table_name + relation = Relation.new(FakeKlass.new("posts"), :b, Post.predicate_builder) + assert_equal "posts", relation.table_name end def test_scope_for_create @@ -100,7 +101,7 @@ module ActiveRecord def test_create_with_value relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) - hash = { :hello => 'world' } + hash = { hello: "world" } relation.create_with_value = hash assert_equal hash, relation.scope_for_create end @@ -108,8 +109,8 @@ module ActiveRecord def test_create_with_value_with_wheres relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) relation.where! relation.table[:id].eq(10) - relation.create_with_value = {:hello => 'world'} - assert_equal({:hello => 'world', :id => 10}, relation.scope_for_create) + relation.create_with_value = { hello: "world" } + assert_equal({ hello: "world", id: 10 }, relation.scope_for_create) end # FIXME: is this really wanted or expected behavior? @@ -120,7 +121,7 @@ module ActiveRecord relation.where! relation.table[:id].eq(10) assert_equal({}, relation.scope_for_create) - relation.create_with_value = {:hello => 'world'} + relation.create_with_value = { hello: "world" } assert_equal({}, relation.scope_for_create) end @@ -145,48 +146,48 @@ module ActiveRecord relation = Relation.new(FakeKlass, :b, nil) assert_equal [], relation.references_values relation = relation.references(:foo).references(:omg, :lol) - assert_equal ['foo', 'omg', 'lol'], relation.references_values + assert_equal ["foo", "omg", "lol"], relation.references_values end def test_references_values_dont_duplicate relation = Relation.new(FakeKlass, :b, nil) relation = relation.references(:foo).references(:foo) - assert_equal ['foo'], relation.references_values + assert_equal ["foo"], relation.references_values end - test 'merging a hash into a relation' do + test "merging a hash into a relation" do relation = Relation.new(Post, Post.arel_table, Post.predicate_builder) - relation = relation.merge where: {name: :lol}, readonly: true + relation = relation.merge where: { name: :lol }, readonly: true - assert_equal({"name"=>:lol}, relation.where_clause.to_h) + assert_equal({ "name"=>:lol }, relation.where_clause.to_h) assert_equal true, relation.readonly_value end - test 'merging an empty hash into a relation' do + test "merging an empty hash into a relation" do assert_equal Relation::WhereClause.empty, Relation.new(FakeKlass, :b, nil).merge({}).where_clause end - test 'merging a hash with unknown keys raises' do - assert_raises(ArgumentError) { Relation::HashMerger.new(nil, omg: 'lol') } + test "merging a hash with unknown keys raises" do + assert_raises(ArgumentError) { Relation::HashMerger.new(nil, omg: "lol") } end - test 'merging nil or false raises' do + test "merging nil or false raises" do relation = Relation.new(FakeKlass, :b, nil) e = assert_raises(ArgumentError) do relation = relation.merge nil end - assert_equal 'invalid argument: nil.', e.message + assert_equal "invalid argument: nil.", e.message e = assert_raises(ArgumentError) do relation = relation.merge false end - assert_equal 'invalid argument: false.', e.message + assert_equal "invalid argument: false.", e.message end - test '#values returns a dup of the values' do + test "#values returns a dup of the values" do relation = Relation.new(Post, Post.arel_table, Post.predicate_builder).where!(name: :foo) values = relation.values @@ -194,22 +195,22 @@ module ActiveRecord assert_not_nil relation.where_clause end - test 'relations can be created with a values hash' do + test "relations can be created with a values hash" do relation = Relation.new(FakeKlass, :b, nil, select: [:foo]) assert_equal [:foo], relation.select_values end - test 'merging a hash interpolates conditions' do + test "merging a hash interpolates conditions" do klass = Class.new(FakeKlass) do def self.sanitize_sql(args) - raise unless args == ['foo = ?', 'bar'] - 'foo = bar' + raise unless args == ["foo = ?", "bar"] + "foo = bar" end end relation = Relation.new(klass, :b, nil) - relation.merge!(where: ['foo = ?', 'bar']) - assert_equal Relation::WhereClause.new(['foo = bar'], []), relation.where_clause + relation.merge!(where: ["foo = ?", "bar"]) + assert_equal Relation::WhereClause.new(["foo = bar"], []), relation.where_clause end def test_merging_readonly_false @@ -223,7 +224,7 @@ module ActiveRecord def test_relation_merging_with_merged_joins_as_symbols special_comments_with_ratings = SpecialComment.joins(:ratings) posts_with_special_comments_with_ratings = Post.group("posts.id").joins(:special_comments).merge(special_comments_with_ratings) - assert_equal 3, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count.length + assert_equal({ 2=>1, 4=>3, 5=>1 }, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count) end def test_relation_merging_with_joins_as_join_dependency_pick_proper_parent @@ -273,7 +274,7 @@ module ActiveRecord join_string = "LEFT OUTER JOIN #{Rating.quoted_table_name} ON #{SpecialComment.quoted_table_name}.id = #{Rating.quoted_table_name}.comment_id" special_comments_with_ratings = SpecialComment.joins join_string posts_with_special_comments_with_ratings = Post.group("posts.id").joins(:special_comments).merge(special_comments_with_ratings) - assert_equal 3, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count.length + assert_equal({ 2=>1, 4=>3, 5=>1 }, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count) end class EnsureRoundTripTypeCasting < ActiveRecord::Type::Value @@ -293,7 +294,7 @@ module ActiveRecord end class UpdateAllTestModel < ActiveRecord::Base - self.table_name = 'posts' + self.table_name = "posts" attribute :body, EnsureRoundTripTypeCasting.new end @@ -306,23 +307,23 @@ module ActiveRecord private - def skip_if_sqlite3_version_includes_quoting_bug - if sqlite3_version_includes_quoting_bug? - skip <<-ERROR.squish - You are using an outdated version of SQLite3 which has a bug in - quoted column names. Please update SQLite3 and rebuild the sqlite3 - ruby gem - ERROR + def skip_if_sqlite3_version_includes_quoting_bug + if sqlite3_version_includes_quoting_bug? + skip <<-ERROR.squish + You are using an outdated version of SQLite3 which has a bug in + quoted column names. Please update SQLite3 and rebuild the sqlite3 + ruby gem + ERROR + end end - end - def sqlite3_version_includes_quoting_bug? - if current_adapter?(:SQLite3Adapter) - selected_quoted_column_names = ActiveRecord::Base.connection.exec_query( - 'SELECT "join" FROM (SELECT id AS "join" FROM posts) subquery' - ).columns - ["join"] != selected_quoted_column_names + def sqlite3_version_includes_quoting_bug? + if current_adapter?(:SQLite3Adapter) + selected_quoted_column_names = ActiveRecord::Base.connection.exec_query( + 'SELECT "join" FROM (SELECT id AS "join" FROM posts) subquery' + ).columns + ["join"] != selected_quoted_column_names + end end - end end end diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 95e4230a58..dcaae5b462 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -1,21 +1,21 @@ require "cases/helper" -require 'models/tag' -require 'models/tagging' -require 'models/post' -require 'models/topic' -require 'models/comment' -require 'models/author' -require 'models/entrant' -require 'models/developer' -require 'models/computer' -require 'models/reply' -require 'models/company' -require 'models/bird' -require 'models/car' -require 'models/engine' -require 'models/tyre' -require 'models/minivan' -require 'models/aircraft' +require "models/tag" +require "models/tagging" +require "models/post" +require "models/topic" +require "models/comment" +require "models/author" +require "models/entrant" +require "models/developer" +require "models/computer" +require "models/reply" +require "models/company" +require "models/bird" +require "models/car" +require "models/engine" +require "models/tyre" +require "models/minivan" +require "models/aircraft" require "models/possession" require "models/reader" require "models/categorization" @@ -27,19 +27,19 @@ class RelationTest < ActiveRecord::TestCase class TopicWithCallbacks < ActiveRecord::Base self.table_name = :topics - before_update { |topic| topic.author_name = 'David' if topic.author_name.blank? } + before_update { |topic| topic.author_name = "David" if topic.author_name.blank? } end def test_do_not_double_quote_string_id van = Minivan.last assert van - assert_equal van.id, Minivan.where(:minivan_id => van).to_a.first.minivan_id + assert_equal van.id, Minivan.where(minivan_id: van).to_a.first.minivan_id end def test_do_not_double_quote_string_id_with_array van = Minivan.last assert van - assert_equal van, Minivan.where(:minivan_id => [van]).to_a.first + assert_equal van, Minivan.where(minivan_id: [van]).to_a.first end def test_two_scopes_with_includes_should_not_drop_any_include @@ -54,12 +54,12 @@ class RelationTest < ActiveRecord::TestCase end def test_dynamic_finder - x = Post.where('author_id = ?', 1) - assert x.klass.respond_to?(:find_by_id), '@klass should handle dynamic finders' + x = Post.where("author_id = ?", 1) + assert x.klass.respond_to?(:find_by_id), "@klass should handle dynamic finders" end def test_multivalue_where - posts = Post.where('author_id = ? AND id = ?', 1, 1) + posts = Post.where("author_id = ? AND id = ?", 1, 1) assert_equal 1, posts.to_a.size end @@ -101,7 +101,7 @@ class RelationTest < ActiveRecord::TestCase end def test_scoped_first - topics = Topic.all.order('id ASC') + topics = Topic.all.order("id ASC") assert_queries(1) do 2.times { assert_equal "The First Topic", topics.first.title } @@ -111,7 +111,7 @@ class RelationTest < ActiveRecord::TestCase end def test_loaded_first - topics = Topic.all.order('id ASC') + topics = Topic.all.order("id ASC") topics.to_a # force load assert_no_queries do @@ -122,7 +122,7 @@ class RelationTest < ActiveRecord::TestCase end def test_loaded_first_with_limit - topics = Topic.all.order('id ASC') + topics = Topic.all.order("id ASC") topics.to_a # force load assert_no_queries do @@ -134,7 +134,7 @@ class RelationTest < ActiveRecord::TestCase end def test_first_get_more_than_available - topics = Topic.all.order('id ASC') + topics = Topic.all.order("id ASC") unloaded_first = topics.first(10) topics.to_a # force load @@ -154,7 +154,7 @@ class RelationTest < ActiveRecord::TestCase assert topics.loaded? original_size = topics.to_a.size - Topic.create! :title => 'fake' + Topic.create! title: "fake" assert_queries(1) { topics.reload } assert_equal original_size + 1, topics.size @@ -162,17 +162,17 @@ class RelationTest < ActiveRecord::TestCase end def test_finding_with_subquery - relation = Topic.where(:approved => true) - assert_equal relation.to_a, Topic.select('*').from(relation).to_a - assert_equal relation.to_a, Topic.select('subquery.*').from(relation).to_a - assert_equal relation.to_a, Topic.select('a.*').from(relation, :a).to_a + relation = Topic.where(approved: true) + assert_equal relation.to_a, Topic.select("*").from(relation).to_a + assert_equal relation.to_a, Topic.select("subquery.*").from(relation).to_a + assert_equal relation.to_a, Topic.select("a.*").from(relation, :a).to_a end def test_finding_with_subquery_with_binds relation = Post.first.comments - assert_equal relation.to_a, Comment.select('*').from(relation).to_a - assert_equal relation.to_a, Comment.select('subquery.*').from(relation).to_a - assert_equal relation.to_a, Comment.select('a.*').from(relation, :a).to_a + assert_equal relation.to_a, Comment.select("*").from(relation).to_a + assert_equal relation.to_a, Comment.select("subquery.*").from(relation).to_a + assert_equal relation.to_a, Comment.select("a.*").from(relation, :a).to_a end def test_finding_with_subquery_without_select_does_not_change_the_select @@ -183,25 +183,25 @@ class RelationTest < ActiveRecord::TestCase end def test_select_with_subquery_in_from_does_not_use_original_table_name - relation = Comment.group(:type).select('COUNT(post_id) AS post_count, type') - subquery = Comment.from(relation).select('type','post_count') + relation = Comment.group(:type).select("COUNT(post_id) AS post_count, type") + subquery = Comment.from(relation).select("type","post_count") assert_equal(relation.map(&:post_count).sort,subquery.map(&:post_count).sort) end def test_group_with_subquery_in_from_does_not_use_original_table_name - relation = Comment.group(:type).select('COUNT(post_id) AS post_count,type') - subquery = Comment.from(relation).group('type').average("post_count") + relation = Comment.group(:type).select("COUNT(post_id) AS post_count,type") + subquery = Comment.from(relation).group("type").average("post_count") assert_equal(relation.map(&:post_count).sort,subquery.values.sort) end def test_finding_with_conditions - assert_equal ["David"], Author.where(:name => 'David').map(&:name) - assert_equal ['Mary'], Author.where(["name = ?", 'Mary']).map(&:name) - assert_equal ['Mary'], Author.where("name = ?", 'Mary').map(&:name) + assert_equal ["David"], Author.where(name: "David").map(&:name) + assert_equal ["Mary"], Author.where(["name = ?", "Mary"]).map(&:name) + assert_equal ["Mary"], Author.where("name = ?", "Mary").map(&:name) end def test_finding_with_order - topics = Topic.order('id') + topics = Topic.order("id") assert_equal 5, topics.to_a.size assert_equal topics(:first).title, topics.first.title end @@ -213,13 +213,13 @@ class RelationTest < ActiveRecord::TestCase end def test_finding_with_assoc_order - topics = Topic.order(:id => :desc) + topics = Topic.order(id: :desc) assert_equal 5, topics.to_a.size assert_equal topics(:fifth).title, topics.first.title end def test_finding_with_reverted_assoc_order - topics = Topic.order(:id => :asc).reverse_order + topics = Topic.order(id: :asc).reverse_order assert_equal 5, topics.to_a.size assert_equal topics(:fifth).title, topics.first.title end @@ -240,6 +240,15 @@ class RelationTest < ActiveRecord::TestCase assert_raises(ActiveRecord::IrreversibleOrderError) do Topic.order("concat(author_name, title)").reverse_order end + assert_raises(ActiveRecord::IrreversibleOrderError) do + Topic.order("concat(lower(author_name), title)").reverse_order + end + assert_raises(ActiveRecord::IrreversibleOrderError) do + Topic.order("concat(author_name, lower(title))").reverse_order + end + assert_raises(ActiveRecord::IrreversibleOrderError) do + Topic.order("concat(lower(author_name), title, length(title)").reverse_order + end end def test_reverse_order_with_nulls_first_or_last @@ -258,7 +267,7 @@ class RelationTest < ActiveRecord::TestCase end def test_order_with_hash_and_symbol_generates_the_same_sql - assert_equal Topic.order(:id).to_sql, Topic.order(:id => :asc).to_sql + assert_equal Topic.order(:id).to_sql, Topic.order(id: :asc).to_sql end def test_finding_with_desc_order_with_string @@ -268,7 +277,7 @@ class RelationTest < ActiveRecord::TestCase end def test_finding_with_asc_order_with_string - topics = Topic.order(id: 'asc') + topics = Topic.order(id: "asc") assert_equal 5, topics.to_a.size assert_equal [topics(:first), topics(:second), topics(:third), topics(:fourth), topics(:fifth)], topics.to_a end @@ -296,7 +305,7 @@ class RelationTest < ActiveRecord::TestCase end def test_finding_with_order_concatenated - topics = Topic.order('author_name').order('title') + topics = Topic.order("author_name").order("title") assert_equal 5, topics.to_a.size assert_equal topics(:fourth).title, topics.first.title end @@ -314,19 +323,19 @@ class RelationTest < ActiveRecord::TestCase end def test_finding_with_reorder - topics = Topic.order('author_name').order('title').reorder('id').to_a + topics = Topic.order("author_name").order("title").reorder("id").to_a topics_titles = topics.map(&:title) - assert_equal ['The First Topic', 'The Second Topic of the day', 'The Third Topic of the day', 'The Fourth Topic of the day', 'The Fifth Topic of the day'], topics_titles + assert_equal ["The First Topic", "The Second Topic of the day", "The Third Topic of the day", "The Fourth Topic of the day", "The Fifth Topic of the day"], topics_titles end def test_finding_with_reorder_by_aliased_attributes - topics = Topic.order('author_name').reorder(:heading) + topics = Topic.order("author_name").reorder(:heading) assert_equal 5, topics.to_a.size assert_equal topics(:fifth).title, topics.first.title end def test_finding_with_assoc_reorder_by_aliased_attributes - topics = Topic.order('author_name').reorder(heading: :desc) + topics = Topic.order("author_name").reorder(heading: :desc) assert_equal 5, topics.to_a.size assert_equal topics(:third).title, topics.first.title end @@ -384,7 +393,7 @@ class RelationTest < ActiveRecord::TestCase end def test_select_with_block - even_ids = Developer.all.select {|d| d.id % 2 == 0 }.map(&:id) + even_ids = Developer.all.select { |d| d.id % 2 == 0 }.map(&:id) assert_equal [2, 4, 6, 8, 10], even_ids.sort end @@ -397,7 +406,7 @@ class RelationTest < ActiveRecord::TestCase def test_none_chainable assert_no_queries(ignore_none: false) do - assert_equal [], Developer.none.where(:name => 'David') + assert_equal [], Developer.none.where(name: "David") end end @@ -411,7 +420,7 @@ class RelationTest < ActiveRecord::TestCase assert_no_queries(ignore_none: false) do assert_equal [], Developer.none.pluck(:id, :name) assert_equal 0, Developer.none.delete_all - assert_equal 0, Developer.none.update_all(:name => 'David') + assert_equal 0, Developer.none.update_all(name: "David") assert_equal 0, Developer.none.delete(1) assert_equal false, Developer.none.exists?(1) end @@ -433,7 +442,7 @@ class RelationTest < ActiveRecord::TestCase assert_no_queries(ignore_none: false) do assert_equal 0, Developer.none.count assert_equal 0, Developer.none.calculate(:count, nil) - assert_equal nil, Developer.none.calculate(:average, 'salary') + assert_equal nil, Developer.none.calculate(:average, "salary") end end @@ -443,7 +452,7 @@ class RelationTest < ActiveRecord::TestCase end def test_null_relation_where_values_hash - assert_equal({ 'salary' => 100_000 }, Developer.none.where(salary: 100_000).where_values_hash) + assert_equal({ "salary" => 100_000 }, Developer.none.where(salary: 100_000).where_values_hash) end def test_null_relation_sum @@ -510,23 +519,23 @@ class RelationTest < ActiveRecord::TestCase end def test_finding_with_hash_conditions_on_joined_table - firms = DependentFirm.joins(:account).where({:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}).to_a + firms = DependentFirm.joins(:account).where(name: "RailsCore", accounts: { credit_limit: 55..60 }).to_a assert_equal 1, firms.size assert_equal companies(:rails_core), firms.first end def test_find_all_with_join - developers_on_project_one = Developer.joins('LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id'). - where('project_id=1').to_a + developers_on_project_one = Developer.joins("LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id"). + where("project_id=1").to_a assert_equal 3, developers_on_project_one.length developer_names = developers_on_project_one.map(&:name) - assert developer_names.include?('David') - assert developer_names.include?('Jamis') + assert_includes developer_names, "David" + assert_includes developer_names, "Jamis" end def test_find_on_hash_conditions - assert_equal Topic.all.merge!(:where => {:approved => false}).to_a, Topic.where({ :approved => false }).to_a + assert_equal Topic.all.merge!(where: { approved: false }).to_a, Topic.where(approved: false).to_a end def test_joins_with_string_array @@ -565,7 +574,7 @@ class RelationTest < ActiveRecord::TestCase def test_respond_to_delegates_to_relation relation = Topic.all fake_arel = Struct.new(:responds) { - def respond_to? method, access = false + def respond_to?(method, access = false) responds << [method, access] end }.new [] @@ -599,8 +608,8 @@ class RelationTest < ActiveRecord::TestCase end def test_eager_association_loading_of_stis_with_multiple_references - authors = Author.eager_load(:posts => { :special_comments => { :post => [ :special_comments, :very_special_comment ] } }). - order('comments.body, very_special_comments_posts.body').where('posts.id = 4').to_a + authors = Author.eager_load(posts: { special_comments: { post: [ :special_comments, :very_special_comment ] } }). + order("comments.body, very_special_comments_posts.body").where("posts.id = 4").to_a assert_equal [authors(:david)], authors assert_no_queries do @@ -611,27 +620,27 @@ class RelationTest < ActiveRecord::TestCase def test_find_with_preloaded_associations assert_queries(2) do - posts = Post.preload(:comments).order('posts.id') + posts = Post.preload(:comments).order("posts.id") assert posts.first.comments.first end assert_queries(2) do - posts = Post.preload(:comments).order('posts.id') + posts = Post.preload(:comments).order("posts.id") assert posts.first.comments.first end assert_queries(2) do - posts = Post.preload(:author).order('posts.id') + posts = Post.preload(:author).order("posts.id") assert posts.first.author end assert_queries(2) do - posts = Post.preload(:author).order('posts.id') + posts = Post.preload(:author).order("posts.id") assert posts.first.author end assert_queries(3) do - posts = Post.preload(:author, :comments).order('posts.id') + posts = Post.preload(:author, :comments).order("posts.id") assert posts.first.author assert posts.first.comments.first end @@ -646,58 +655,58 @@ class RelationTest < ActiveRecord::TestCase def test_find_with_included_associations assert_queries(2) do - posts = Post.includes(:comments).order('posts.id') + posts = Post.includes(:comments).order("posts.id") assert posts.first.comments.first end assert_queries(2) do - posts = Post.all.includes(:comments).order('posts.id') + posts = Post.all.includes(:comments).order("posts.id") assert posts.first.comments.first end assert_queries(2) do - posts = Post.includes(:author).order('posts.id') + posts = Post.includes(:author).order("posts.id") assert posts.first.author end assert_queries(3) do - posts = Post.includes(:author, :comments).order('posts.id') + posts = Post.includes(:author, :comments).order("posts.id") assert posts.first.author assert posts.first.comments.first end end def test_default_scope_with_conditions_string - assert_equal Developer.where(name: 'David').map(&:id).sort, DeveloperCalledDavid.all.map(&:id).sort + assert_equal Developer.where(name: "David").map(&:id).sort, DeveloperCalledDavid.all.map(&:id).sort assert_nil DeveloperCalledDavid.create!.name end def test_default_scope_with_conditions_hash - assert_equal Developer.where(name: 'Jamis').map(&:id).sort, DeveloperCalledJamis.all.map(&:id).sort - assert_equal 'Jamis', DeveloperCalledJamis.create!.name + assert_equal Developer.where(name: "Jamis").map(&:id).sort, DeveloperCalledJamis.all.map(&:id).sort + assert_equal "Jamis", DeveloperCalledJamis.create!.name end def test_default_scoping_finder_methods - developers = DeveloperCalledDavid.order('id').map(&:id).sort - assert_equal Developer.where(name: 'David').map(&:id).sort, developers + developers = DeveloperCalledDavid.order("id").map(&:id).sort + assert_equal Developer.where(name: "David").map(&:id).sort, developers end def test_includes_with_select - query = Post.select('comments_count AS ranking').order('ranking').includes(:comments) + query = Post.select("comments_count AS ranking").order("ranking").includes(:comments) .where(comments: { id: 1 }) - assert_equal ['comments_count AS ranking'], query.select_values + assert_equal ["comments_count AS ranking"], query.select_values assert_equal 1, query.to_a.size end def test_preloading_with_associations_and_merges - post = Post.create! title: 'Uhuu', body: 'body' + post = Post.create! title: "Uhuu", body: "body" reader = Reader.create! post_id: post.id, person_id: 1 - comment = Comment.create! post_id: post.id, body: 'body' + comment = Comment.create! post_id: post.id, body: "body" assert !comment.respond_to?(:readers) - post_rel = Post.preload(:readers).joins(:readers).where(title: 'Uhuu') + post_rel = Post.preload(:readers).joins(:readers).where(title: "Uhuu") result_comment = Comment.joins(:post).merge(post_rel).to_a.first assert_equal comment, result_comment @@ -706,7 +715,7 @@ class RelationTest < ActiveRecord::TestCase assert_equal [reader], result_comment.post.readers.to_a end - post_rel = Post.includes(:readers).where(title: 'Uhuu') + post_rel = Post.includes(:readers).where(title: "Uhuu") result_comment = Comment.joins(:post).merge(post_rel).first assert_equal comment, result_comment @@ -717,17 +726,17 @@ class RelationTest < ActiveRecord::TestCase end def test_preloading_with_associations_default_scopes_and_merges - post = Post.create! title: 'Uhuu', body: 'body' + post = Post.create! title: "Uhuu", body: "body" reader = Reader.create! post_id: post.id, person_id: 1 - post_rel = PostWithPreloadDefaultScope.preload(:readers).joins(:readers).where(title: 'Uhuu') + post_rel = PostWithPreloadDefaultScope.preload(:readers).joins(:readers).where(title: "Uhuu") result_post = PostWithPreloadDefaultScope.all.merge(post_rel).to_a.first assert_no_queries do assert_equal [reader], result_post.readers.to_a end - post_rel = PostWithIncludesDefaultScope.includes(:readers).where(title: 'Uhuu') + post_rel = PostWithIncludesDefaultScope.includes(:readers).where(title: "Uhuu") result_post = PostWithIncludesDefaultScope.all.merge(post_rel).to_a.first assert_no_queries do @@ -739,11 +748,11 @@ class RelationTest < ActiveRecord::TestCase posts = Post.preload(:comments) post = posts.find { |p| p.id == 1 } assert_equal 2, post.comments.size - assert post.comments.include?(comments(:greetings)) + assert_includes post.comments, comments(:greetings) post = Post.where("posts.title = 'Welcome to the weblog'").preload(:comments).first assert_equal 2, post.comments.size - assert post.comments.include?(comments(:greetings)) + assert_includes post.comments, comments(:greetings) posts = Post.preload(:last_comment) post = posts.find { |p| p.id == 1 } @@ -752,9 +761,9 @@ class RelationTest < ActiveRecord::TestCase def test_to_sql_on_eager_join expected = assert_sql { - Post.eager_load(:last_comment).order('comments.id DESC').to_a + Post.eager_load(:last_comment).order("comments.id DESC").to_a }.first - actual = Post.eager_load(:last_comment).order('comments.id DESC').to_sql + actual = Post.eager_load(:last_comment).order("comments.id DESC").to_sql assert_equal expected, actual end @@ -765,7 +774,7 @@ class RelationTest < ActiveRecord::TestCase end def test_loading_with_one_association_with_non_preload - posts = Post.eager_load(:last_comment).order('comments.id DESC') + posts = Post.eager_load(:last_comment).order("comments.id DESC") post = posts.find { |p| p.id == 1 } assert_equal Post.find(1).last_comment, post.last_comment end @@ -789,40 +798,40 @@ class RelationTest < ActiveRecord::TestCase author = Author.all.find_by_id!(authors(:david).id) assert_equal "David", author.name - assert_raises(ActiveRecord::RecordNotFound) { Author.all.find_by_id_and_name!(20, 'invalid') } + assert_raises(ActiveRecord::RecordNotFound) { Author.all.find_by_id_and_name!(20, "invalid") } end def test_find_id authors = Author.all david = authors.find(authors(:david).id) - assert_equal 'David', david.name + assert_equal "David", david.name - assert_raises(ActiveRecord::RecordNotFound) { authors.where(:name => 'lifo').find('42') } + assert_raises(ActiveRecord::RecordNotFound) { authors.where(name: "lifo").find("42") } end def test_find_ids - authors = Author.order('id ASC') + authors = Author.order("id ASC") results = authors.find(authors(:david).id, authors(:mary).id) assert_kind_of Array, results assert_equal 2, results.size - assert_equal 'David', results[0].name - assert_equal 'Mary', results[1].name + assert_equal "David", results[0].name + assert_equal "Mary", results[1].name assert_equal results, authors.find([authors(:david).id, authors(:mary).id]) - assert_raises(ActiveRecord::RecordNotFound) { authors.where(:name => 'lifo').find(authors(:david).id, '42') } - assert_raises(ActiveRecord::RecordNotFound) { authors.find(['42', 43]) } + assert_raises(ActiveRecord::RecordNotFound) { authors.where(name: "lifo").find(authors(:david).id, "42") } + assert_raises(ActiveRecord::RecordNotFound) { authors.find(["42", 43]) } end def test_find_in_empty_array - authors = Author.all.where(:id => []) + authors = Author.all.where(id: []) assert authors.to_a.blank? end def test_where_with_ar_object author = Author.first - authors = Author.all.where(:id => author) + authors = Author.all.where(id: author) assert_equal 1, authors.to_a.length end @@ -835,9 +844,9 @@ class RelationTest < ActiveRecord::TestCase class Mary < Author; end def test_find_by_classname - Author.create!(:name => Mary.name) + Author.create!(name: Mary.name) assert_deprecated do - assert_equal 1, Author.where(:name => Mary).size + assert_equal 1, Author.where(name: Mary).size end end @@ -850,25 +859,25 @@ class RelationTest < ActiveRecord::TestCase def test_find_all_using_where_twice_should_or_the_relation david = authors(:david) relation = Author.unscoped - relation = relation.where(:name => david.name) - relation = relation.where(:name => 'Santiago') - relation = relation.where(:id => david.id) + relation = relation.where(name: david.name) + relation = relation.where(name: "Santiago") + relation = relation.where(id: david.id) assert_equal [], relation.to_a end def test_multi_where_ands_queries relation = Author.unscoped david = authors(:david) - sql = relation.where(:name => david.name).where(:name => 'Santiago').to_sql - assert_match('AND', sql) + sql = relation.where(name: david.name).where(name: "Santiago").to_sql + assert_match("AND", sql) end def test_find_all_with_multiple_should_use_and david = authors(:david) relation = [ - { :name => david.name }, - { :name => 'Santiago' }, - { :name => 'tenderlove' }, + { name: david.name }, + { name: "Santiago" }, + { name: "tenderlove" }, ].inject(Author.unscoped) do |memo, param| memo.where(param) end @@ -887,17 +896,17 @@ class RelationTest < ActiveRecord::TestCase # switching the lines below would succeed in current rails # assert_queries(2) { assert_queries(1) { - relation = Author.where(:id => Author.where(:id => david.id)) + relation = Author.where(id: Author.where(id: david.id)) assert_equal [david], relation.to_a } assert_queries(1) { - relation = Author.where('id in (?)', Author.where(id: david).select(:id)) + relation = Author.where("id in (?)", Author.where(id: david).select(:id)) assert_equal [david], relation.to_a } assert_queries(1) do - relation = Author.where('id in (:author_ids)', author_ids: Author.where(id: david).select(:id)) + relation = Author.where("id in (:author_ids)", author_ids: Author.where(id: david).select(:id)) assert_equal [david], relation.to_a end end @@ -912,13 +921,13 @@ class RelationTest < ActiveRecord::TestCase end assert_queries(1) do - relation = Post.where('id in (?)', david.posts.select(:id)) - assert_equal davids_posts, relation.order(:id).to_a, 'should process Relation as bind variables' + relation = Post.where("id in (?)", david.posts.select(:id)) + assert_equal davids_posts, relation.order(:id).to_a, "should process Relation as bind variables" end assert_queries(1) do - relation = Post.where('id in (:post_ids)', post_ids: david.posts.select(:id)) - assert_equal davids_posts, relation.order(:id).to_a, 'should process Relation as named bind variables' + relation = Post.where("id in (:post_ids)", post_ids: david.posts.select(:id)) + assert_equal davids_posts, relation.order(:id).to_a, "should process Relation as named bind variables" end end @@ -927,7 +936,7 @@ class RelationTest < ActiveRecord::TestCase # switching the lines below would succeed in current rails # assert_queries(2) { assert_queries(1) { - relation = Minivan.where(:minivan_id => Minivan.where(:name => cool_first.name)) + relation = Minivan.where(minivan_id: Minivan.where(name: cool_first.name)) assert_equal [cool_first], relation.to_a } end @@ -935,10 +944,10 @@ class RelationTest < ActiveRecord::TestCase def test_find_all_using_where_with_relation_does_not_alter_select_values david = authors(:david) - subquery = Author.where(:id => david.id) + subquery = Author.where(id: david.id) assert_queries(1) { - relation = Author.where(:id => subquery) + relation = Author.where(id: subquery) assert_equal [david], relation.to_a } @@ -948,22 +957,21 @@ class RelationTest < ActiveRecord::TestCase def test_find_all_using_where_with_relation_with_joins david = authors(:david) assert_queries(1) { - relation = Author.where(:id => Author.joins(:posts).where(:id => david.id)) + relation = Author.where(id: Author.joins(:posts).where(id: david.id)) assert_equal [david], relation.to_a } end - def test_find_all_using_where_with_relation_with_select_to_build_subquery david = authors(:david) assert_queries(1) { - relation = Author.where(:name => Author.where(:id => david.id).select(:name)) + relation = Author.where(name: Author.where(id: david.id).select(:name)) assert_equal [david], relation.to_a } end def test_exists - davids = Author.where(:name => 'David') + davids = Author.where(name: "David") assert davids.exists? assert davids.exists?(authors(:david).id) assert ! davids.exists?(authors(:mary).id) @@ -971,7 +979,7 @@ class RelationTest < ActiveRecord::TestCase assert ! davids.exists?(42) assert ! davids.exists?(davids.new.id) - fake = Author.where(:name => 'fake author') + fake = Author.where(name: "fake author") assert ! fake.exists? assert ! fake.exists?(authors(:david).id) end @@ -994,13 +1002,13 @@ class RelationTest < ActiveRecord::TestCase end def test_destroy_all - davids = Author.where(:name => 'David') + davids = Author.where(name: "David") # Force load assert_equal [authors(:david)], davids.to_a assert davids.loaded? - assert_difference('Author.count', -1) { davids.destroy_all } + assert_difference("Author.count", -1) { davids.destroy_all } assert_equal [], davids.to_a assert davids.loaded? @@ -1008,31 +1016,31 @@ class RelationTest < ActiveRecord::TestCase def test_destroy_all_with_conditions_is_deprecated assert_deprecated do - assert_difference('Author.count', -1) { Author.destroy_all(name: 'David') } + assert_difference("Author.count", -1) { Author.destroy_all(name: "David") } end end def test_delete_all - davids = Author.where(:name => 'David') + davids = Author.where(name: "David") - assert_difference('Author.count', -1) { davids.delete_all } + assert_difference("Author.count", -1) { davids.delete_all } assert ! davids.loaded? end def test_delete_all_with_conditions_is_deprecated assert_deprecated do - assert_difference('Author.count', -1) { Author.delete_all(name: 'David') } + assert_difference("Author.count", -1) { Author.delete_all(name: "David") } end end def test_delete_all_loaded - davids = Author.where(:name => 'David') + davids = Author.where(name: "David") # Force load assert_equal [authors(:david)], davids.to_a assert davids.loaded? - assert_difference('Author.count', -1) { davids.delete_all } + assert_difference("Author.count", -1) { davids.delete_all } assert_equal [], davids.to_a assert davids.loaded? @@ -1042,7 +1050,7 @@ class RelationTest < ActiveRecord::TestCase assert_raises(ActiveRecord::ActiveRecordError) { Author.limit(10).delete_all } assert_raises(ActiveRecord::ActiveRecordError) { Author.distinct.delete_all } assert_raises(ActiveRecord::ActiveRecordError) { Author.group(:name).delete_all } - assert_raises(ActiveRecord::ActiveRecordError) { Author.having('SUM(id) < 3').delete_all } + assert_raises(ActiveRecord::ActiveRecordError) { Author.having("SUM(id) < 3").delete_all } assert_raises(ActiveRecord::ActiveRecordError) { Author.offset(10).delete_all } end @@ -1082,8 +1090,13 @@ class RelationTest < ActiveRecord::TestCase assert_equal 11, posts.count(:all) assert_equal 11, posts.count(:id) - assert_equal 1, posts.where('comments_count > 1').count - assert_equal 9, posts.where(:comments_count => 0).count + assert_equal 1, posts.where("comments_count > 1").count + assert_equal 9, posts.where(comments_count: 0).count + end + + def test_count_with_block + posts = Post.all + assert_equal 10, posts.count { |p| p.comments_count.even? } end def test_count_on_association_relation @@ -1112,24 +1125,24 @@ class RelationTest < ActiveRecord::TestCase Post.tagged_with(tag.id).update_all title: "rofl" list = Post.tagged_with(tag.id).all.to_a assert_operator list.length, :>, 0 - list.each { |post| assert_equal 'rofl', post.title } + list.each { |post| assert_equal "rofl", post.title } end def test_count_explicit_columns - Post.update_all(:comments_count => nil) + Post.update_all(comments_count: nil) posts = Post.all - assert_equal [0], posts.select('comments_count').where('id is not null').group('id').order('id').count.values.uniq - assert_equal 0, posts.where('id is not null').select('comments_count').count + assert_equal [0], posts.select("comments_count").where("id is not null").group("id").order("id").count.values.uniq + assert_equal 0, posts.where("id is not null").select("comments_count").count - assert_equal 11, posts.select('comments_count').count('id') - assert_equal 0, posts.select('comments_count').count + assert_equal 11, posts.select("comments_count").count("id") + assert_equal 0, posts.select("comments_count").count assert_equal 0, posts.count(:comments_count) - assert_equal 0, posts.count('comments_count') + assert_equal 0, posts.count("comments_count") end def test_multiple_selects - post = Post.all.select('comments_count').select('title').order("id ASC").first + post = Post.all.select("comments_count").select("title").order("id ASC").first assert_equal "Welcome to the weblog", post.title assert_equal 2, post.comments_count end @@ -1140,7 +1153,7 @@ class RelationTest < ActiveRecord::TestCase assert_queries(1) { assert_equal 11, posts.size } assert ! posts.loaded? - best_posts = posts.where(:comments_count => 0) + best_posts = posts.where(comments_count: 0) best_posts.to_a # force load assert_no_queries { assert_equal 9, best_posts.size } end @@ -1151,7 +1164,7 @@ class RelationTest < ActiveRecord::TestCase assert_queries(1) { assert_equal 10, posts.size } assert ! posts.loaded? - best_posts = posts.where(:comments_count => 0) + best_posts = posts.where(comments_count: 0) best_posts.to_a # force load assert_no_queries { assert_equal 9, best_posts.size } end @@ -1174,7 +1187,7 @@ class RelationTest < ActiveRecord::TestCase end def test_count_complex_chained_relations - posts = Post.select('comments_count').where('id is not null').group("author_id").where("comments_count > 0") + posts = Post.select("comments_count").where("id is not null").group("author_id").where("comments_count > 0") expected = { 1 => 2 } assert_equal expected, posts.count @@ -1186,11 +1199,11 @@ class RelationTest < ActiveRecord::TestCase assert_queries(1) { assert_equal false, posts.empty? } assert ! posts.loaded? - no_posts = posts.where(:title => "") + no_posts = posts.where(title: "") assert_queries(1) { assert_equal true, no_posts.empty? } assert ! no_posts.loaded? - best_posts = posts.where(:comments_count => 0) + best_posts = posts.where(comments_count: 0) best_posts.to_a # force load assert_no_queries { assert_equal false, best_posts.empty? } end @@ -1201,7 +1214,7 @@ class RelationTest < ActiveRecord::TestCase assert_queries(1) { assert_equal false, posts.empty? } assert ! posts.loaded? - no_posts = posts.where(:title => "") + no_posts = posts.where(title: "") assert_queries(1) { assert_equal true, no_posts.empty? } assert ! no_posts.loaded? end @@ -1215,14 +1228,14 @@ class RelationTest < ActiveRecord::TestCase # the SHOW TABLES result to be cached so we don't have to do it again in the block. # # This is obviously a rubbish fix but it's the best I can come up with for now... - posts.where(:id => nil).any? + posts.where(id: nil).any? assert_queries(3) do assert posts.any? # Uses COUNT() - assert ! posts.where(:id => nil).any? + assert ! posts.where(id: nil).any? - assert posts.any? {|p| p.id > 0 } - assert ! posts.any? {|p| p.id <= 0 } + assert posts.any? { |p| p.id > 0 } + assert ! posts.any? { |p| p.id <= 0 } end assert posts.loaded? @@ -1233,8 +1246,8 @@ class RelationTest < ActiveRecord::TestCase assert_queries(2) do assert posts.many? # Uses COUNT() - assert posts.many? {|p| p.id > 0 } - assert ! posts.many? {|p| p.id < 2 } + assert posts.many? { |p| p.id > 0 } + assert ! posts.many? { |p| p.id < 2 } end assert posts.loaded? @@ -1256,8 +1269,8 @@ class RelationTest < ActiveRecord::TestCase assert ! posts.loaded? assert_queries(1) do - assert posts.none? {|p| p.id < 0 } - assert ! posts.none? {|p| p.id == 1 } + assert posts.none? { |p| p.id < 0 } + assert ! posts.none? { |p| p.id == 1 } end assert posts.loaded? @@ -1272,8 +1285,8 @@ class RelationTest < ActiveRecord::TestCase assert ! posts.loaded? assert_queries(1) do - assert ! posts.one? {|p| p.id < 3 } - assert posts.one? {|p| p.id == 1 } + assert ! posts.one? { |p| p.id < 3 } + assert posts.one? { |p| p.id == 1 } end assert posts.loaded? @@ -1297,11 +1310,11 @@ class RelationTest < ActiveRecord::TestCase end def test_scoped_build - posts = Post.where(:title => 'You told a lie') + posts = Post.where(title: "You told a lie") post = posts.new assert_kind_of Post, post - assert_equal 'You told a lie', post.title + assert_equal "You told a lie", post.title end def test_create @@ -1311,9 +1324,9 @@ class RelationTest < ActiveRecord::TestCase assert_kind_of Bird, sparrow assert !sparrow.persisted? - hen = birds.where(:name => 'hen').create + hen = birds.where(name: "hen").create assert hen.persisted? - assert_equal 'hen', hen.name + assert_equal "hen", hen.name end def test_create_bang @@ -1321,201 +1334,201 @@ class RelationTest < ActiveRecord::TestCase assert_raises(ActiveRecord::RecordInvalid) { birds.create! } - hen = birds.where(:name => 'hen').create! + hen = birds.where(name: "hen").create! assert_kind_of Bird, hen assert hen.persisted? - assert_equal 'hen', hen.name + assert_equal "hen", hen.name end def test_first_or_create - parrot = Bird.where(:color => 'green').first_or_create(:name => 'parrot') + parrot = Bird.where(color: "green").first_or_create(name: "parrot") assert_kind_of Bird, parrot assert parrot.persisted? - assert_equal 'parrot', parrot.name - assert_equal 'green', parrot.color + assert_equal "parrot", parrot.name + assert_equal "green", parrot.color - same_parrot = Bird.where(:color => 'green').first_or_create(:name => 'parakeet') + same_parrot = Bird.where(color: "green").first_or_create(name: "parakeet") assert_kind_of Bird, same_parrot assert same_parrot.persisted? assert_equal parrot, same_parrot end def test_first_or_create_with_no_parameters - parrot = Bird.where(:color => 'green').first_or_create + parrot = Bird.where(color: "green").first_or_create assert_kind_of Bird, parrot assert !parrot.persisted? - assert_equal 'green', parrot.color + assert_equal "green", parrot.color end def test_first_or_create_with_block - parrot = Bird.where(:color => 'green').first_or_create { |bird| bird.name = 'parrot' } + parrot = Bird.where(color: "green").first_or_create { |bird| bird.name = "parrot" } assert_kind_of Bird, parrot assert parrot.persisted? - assert_equal 'green', parrot.color - assert_equal 'parrot', parrot.name + assert_equal "green", parrot.color + assert_equal "parrot", parrot.name - same_parrot = Bird.where(:color => 'green').first_or_create { |bird| bird.name = 'parakeet' } + same_parrot = Bird.where(color: "green").first_or_create { |bird| bird.name = "parakeet" } assert_equal parrot, same_parrot end def test_first_or_create_with_array - several_green_birds = Bird.where(:color => 'green').first_or_create([{:name => 'parrot'}, {:name => 'parakeet'}]) + several_green_birds = Bird.where(color: "green").first_or_create([{ name: "parrot" }, { name: "parakeet" }]) assert_kind_of Array, several_green_birds several_green_birds.each { |bird| assert bird.persisted? } - same_parrot = Bird.where(:color => 'green').first_or_create([{:name => 'hummingbird'}, {:name => 'macaw'}]) + same_parrot = Bird.where(color: "green").first_or_create([{ name: "hummingbird" }, { name: "macaw" }]) assert_kind_of Bird, same_parrot assert_equal several_green_birds.first, same_parrot end def test_first_or_create_bang_with_valid_options - parrot = Bird.where(:color => 'green').first_or_create!(:name => 'parrot') + parrot = Bird.where(color: "green").first_or_create!(name: "parrot") assert_kind_of Bird, parrot assert parrot.persisted? - assert_equal 'parrot', parrot.name - assert_equal 'green', parrot.color + assert_equal "parrot", parrot.name + assert_equal "green", parrot.color - same_parrot = Bird.where(:color => 'green').first_or_create!(:name => 'parakeet') + same_parrot = Bird.where(color: "green").first_or_create!(name: "parakeet") assert_kind_of Bird, same_parrot assert same_parrot.persisted? assert_equal parrot, same_parrot end def test_first_or_create_bang_with_invalid_options - assert_raises(ActiveRecord::RecordInvalid) { Bird.where(:color => 'green').first_or_create!(:pirate_id => 1) } + assert_raises(ActiveRecord::RecordInvalid) { Bird.where(color: "green").first_or_create!(pirate_id: 1) } end def test_first_or_create_bang_with_no_parameters - assert_raises(ActiveRecord::RecordInvalid) { Bird.where(:color => 'green').first_or_create! } + assert_raises(ActiveRecord::RecordInvalid) { Bird.where(color: "green").first_or_create! } end def test_first_or_create_bang_with_valid_block - parrot = Bird.where(:color => 'green').first_or_create! { |bird| bird.name = 'parrot' } + parrot = Bird.where(color: "green").first_or_create! { |bird| bird.name = "parrot" } assert_kind_of Bird, parrot assert parrot.persisted? - assert_equal 'green', parrot.color - assert_equal 'parrot', parrot.name + assert_equal "green", parrot.color + assert_equal "parrot", parrot.name - same_parrot = Bird.where(:color => 'green').first_or_create! { |bird| bird.name = 'parakeet' } + same_parrot = Bird.where(color: "green").first_or_create! { |bird| bird.name = "parakeet" } assert_equal parrot, same_parrot end def test_first_or_create_bang_with_invalid_block assert_raise(ActiveRecord::RecordInvalid) do - Bird.where(:color => 'green').first_or_create! { |bird| bird.pirate_id = 1 } + Bird.where(color: "green").first_or_create! { |bird| bird.pirate_id = 1 } end end def test_first_or_create_with_valid_array - several_green_birds = Bird.where(:color => 'green').first_or_create!([{:name => 'parrot'}, {:name => 'parakeet'}]) + several_green_birds = Bird.where(color: "green").first_or_create!([{ name: "parrot" }, { name: "parakeet" }]) assert_kind_of Array, several_green_birds several_green_birds.each { |bird| assert bird.persisted? } - same_parrot = Bird.where(:color => 'green').first_or_create!([{:name => 'hummingbird'}, {:name => 'macaw'}]) + same_parrot = Bird.where(color: "green").first_or_create!([{ name: "hummingbird" }, { name: "macaw" }]) assert_kind_of Bird, same_parrot assert_equal several_green_birds.first, same_parrot end def test_first_or_create_with_invalid_array - assert_raises(ActiveRecord::RecordInvalid) { Bird.where(:color => 'green').first_or_create!([ {:name => 'parrot'}, {:pirate_id => 1} ]) } + assert_raises(ActiveRecord::RecordInvalid) { Bird.where(color: "green").first_or_create!([ { name: "parrot" }, { pirate_id: 1 } ]) } end def test_first_or_initialize - parrot = Bird.where(:color => 'green').first_or_initialize(:name => 'parrot') + parrot = Bird.where(color: "green").first_or_initialize(name: "parrot") assert_kind_of Bird, parrot assert !parrot.persisted? assert parrot.valid? assert parrot.new_record? - assert_equal 'parrot', parrot.name - assert_equal 'green', parrot.color + assert_equal "parrot", parrot.name + assert_equal "green", parrot.color end def test_first_or_initialize_with_no_parameters - parrot = Bird.where(:color => 'green').first_or_initialize + parrot = Bird.where(color: "green").first_or_initialize assert_kind_of Bird, parrot assert !parrot.persisted? assert !parrot.valid? assert parrot.new_record? - assert_equal 'green', parrot.color + assert_equal "green", parrot.color end def test_first_or_initialize_with_block - parrot = Bird.where(:color => 'green').first_or_initialize { |bird| bird.name = 'parrot' } + parrot = Bird.where(color: "green").first_or_initialize { |bird| bird.name = "parrot" } assert_kind_of Bird, parrot assert !parrot.persisted? assert parrot.valid? assert parrot.new_record? - assert_equal 'green', parrot.color - assert_equal 'parrot', parrot.name + assert_equal "green", parrot.color + assert_equal "parrot", parrot.name end def test_find_or_create_by - assert_nil Bird.find_by(name: 'bob') + assert_nil Bird.find_by(name: "bob") - bird = Bird.find_or_create_by(name: 'bob') + bird = Bird.find_or_create_by(name: "bob") assert bird.persisted? - assert_equal bird, Bird.find_or_create_by(name: 'bob') + assert_equal bird, Bird.find_or_create_by(name: "bob") end def test_find_or_create_by_with_create_with - assert_nil Bird.find_by(name: 'bob') + assert_nil Bird.find_by(name: "bob") - bird = Bird.create_with(color: 'green').find_or_create_by(name: 'bob') + bird = Bird.create_with(color: "green").find_or_create_by(name: "bob") assert bird.persisted? - assert_equal 'green', bird.color + assert_equal "green", bird.color - assert_equal bird, Bird.create_with(color: 'blue').find_or_create_by(name: 'bob') + assert_equal bird, Bird.create_with(color: "blue").find_or_create_by(name: "bob") end def test_find_or_create_by! - assert_raises(ActiveRecord::RecordInvalid) { Bird.find_or_create_by!(color: 'green') } + assert_raises(ActiveRecord::RecordInvalid) { Bird.find_or_create_by!(color: "green") } end def test_find_or_initialize_by - assert_nil Bird.find_by(name: 'bob') + assert_nil Bird.find_by(name: "bob") - bird = Bird.find_or_initialize_by(name: 'bob') + bird = Bird.find_or_initialize_by(name: "bob") assert bird.new_record? bird.save! - assert_equal bird, Bird.find_or_initialize_by(name: 'bob') + assert_equal bird, Bird.find_or_initialize_by(name: "bob") end def test_explicit_create_scope - hens = Bird.where(:name => 'hen') - assert_equal 'hen', hens.new.name + hens = Bird.where(name: "hen") + assert_equal "hen", hens.new.name - hens = hens.create_with(:name => 'cock') - assert_equal 'cock', hens.new.name + hens = hens.create_with(name: "cock") + assert_equal "cock", hens.new.name end def test_except - relation = Post.where(:author_id => 1).order('id ASC').limit(1) + relation = Post.where(author_id: 1).order("id ASC").limit(1) assert_equal [posts(:welcome)], relation.to_a author_posts = relation.except(:order, :limit) - assert_equal Post.where(:author_id => 1).to_a, author_posts.to_a + assert_equal Post.where(author_id: 1).to_a, author_posts.to_a all_posts = relation.except(:where, :order, :limit) assert_equal Post.all, all_posts end def test_only - relation = Post.where(:author_id => 1).order('id ASC').limit(1) + relation = Post.where(author_id: 1).order("id ASC").limit(1) assert_equal [posts(:welcome)], relation.to_a author_posts = relation.only(:where) - assert_equal Post.where(:author_id => 1).to_a, author_posts.to_a + assert_equal Post.where(author_id: 1).to_a, author_posts.to_a all_posts = relation.only(:limit) assert_equal Post.limit(1).to_a.first, all_posts.first end def test_anonymous_extension - relation = Post.where(:author_id => 1).order('id ASC').extending do + relation = Post.where(author_id: 1).order("id ASC").extending do def author - 'lifo' + "lifo" end end @@ -1524,7 +1537,7 @@ class RelationTest < ActiveRecord::TestCase end def test_named_extension - relation = Post.where(:author_id => 1).order('id ASC').extending(Post::NamedExtension) + relation = Post.where(author_id: 1).order("id ASC").extending(Post::NamedExtension) assert_equal "lifo", relation.author assert_equal "lifo", relation.limit(1).author end @@ -1534,29 +1547,29 @@ class RelationTest < ActiveRecord::TestCase end def test_default_scope_order_with_scope_order - assert_equal 'zyke', CoolCar.order_using_new_style.limit(1).first.name - assert_equal 'zyke', FastCar.order_using_new_style.limit(1).first.name + assert_equal "zyke", CoolCar.order_using_new_style.limit(1).first.name + assert_equal "zyke", FastCar.order_using_new_style.limit(1).first.name end def test_order_using_scoping - car1 = CoolCar.order('id DESC').scoping do - CoolCar.all.merge!(order: 'id asc').first + car1 = CoolCar.order("id DESC").scoping do + CoolCar.all.merge!(order: "id asc").first end - assert_equal 'zyke', car1.name + assert_equal "zyke", car1.name - car2 = FastCar.order('id DESC').scoping do - FastCar.all.merge!(order: 'id asc').first + car2 = FastCar.order("id DESC").scoping do + FastCar.all.merge!(order: "id asc").first end - assert_equal 'zyke', car2.name + assert_equal "zyke", car2.name end def test_unscoped_block_style - assert_equal 'honda', CoolCar.unscoped { CoolCar.order_using_new_style.limit(1).first.name} - assert_equal 'honda', FastCar.unscoped { FastCar.order_using_new_style.limit(1).first.name} + assert_equal "honda", CoolCar.unscoped { CoolCar.order_using_new_style.limit(1).first.name } + assert_equal "honda", FastCar.unscoped { FastCar.order_using_new_style.limit(1).first.name } end def test_intersection_with_array - relation = Author.where(:name => "David") + relation = Author.where(name: "David") rails_author = relation.first assert_equal [rails_author], [rails_author] & relation @@ -1568,7 +1581,7 @@ class RelationTest < ActiveRecord::TestCase end def test_ordering_with_extra_spaces - assert_equal authors(:david), Author.order('id DESC , name DESC').last + assert_equal authors(:david), Author.order("id DESC , name DESC").last end def test_update_all_with_blank_argument @@ -1576,87 +1589,87 @@ class RelationTest < ActiveRecord::TestCase end def test_update_all_with_joins - comments = Comment.joins(:post).where('posts.id' => posts(:welcome).id) + comments = Comment.joins(:post).where("posts.id" => posts(:welcome).id) count = comments.count - assert_equal count, comments.update_all(:post_id => posts(:thinking).id) + assert_equal count, comments.update_all(post_id: posts(:thinking).id) assert_equal posts(:thinking), comments(:greetings).post end def test_update_all_with_joins_and_limit - comments = Comment.joins(:post).where('posts.id' => posts(:welcome).id).limit(1) - assert_equal 1, comments.update_all(:post_id => posts(:thinking).id) + comments = Comment.joins(:post).where("posts.id" => posts(:welcome).id).limit(1) + assert_equal 1, comments.update_all(post_id: posts(:thinking).id) end def test_update_all_with_joins_and_limit_and_order - comments = Comment.joins(:post).where('posts.id' => posts(:welcome).id).order('comments.id').limit(1) - assert_equal 1, comments.update_all(:post_id => posts(:thinking).id) + comments = Comment.joins(:post).where("posts.id" => posts(:welcome).id).order("comments.id").limit(1) + assert_equal 1, comments.update_all(post_id: posts(:thinking).id) assert_equal posts(:thinking), comments(:greetings).post assert_equal posts(:welcome), comments(:more_greetings).post end def test_update_all_with_joins_and_offset - all_comments = Comment.joins(:post).where('posts.id' => posts(:welcome).id) + all_comments = Comment.joins(:post).where("posts.id" => posts(:welcome).id) count = all_comments.count comments = all_comments.offset(1) - assert_equal count - 1, comments.update_all(:post_id => posts(:thinking).id) + assert_equal count - 1, comments.update_all(post_id: posts(:thinking).id) end def test_update_all_with_joins_and_offset_and_order - all_comments = Comment.joins(:post).where('posts.id' => posts(:welcome).id).order('posts.id', 'comments.id') + all_comments = Comment.joins(:post).where("posts.id" => posts(:welcome).id).order("posts.id", "comments.id") count = all_comments.count comments = all_comments.offset(1) - assert_equal count - 1, comments.update_all(:post_id => posts(:thinking).id) + assert_equal count - 1, comments.update_all(post_id: posts(:thinking).id) assert_equal posts(:thinking), comments(:more_greetings).post assert_equal posts(:welcome), comments(:greetings).post end def test_update_on_relation - topic1 = TopicWithCallbacks.create! title: 'arel', author_name: nil - topic2 = TopicWithCallbacks.create! title: 'activerecord', author_name: nil + topic1 = TopicWithCallbacks.create! title: "arel", author_name: nil + topic2 = TopicWithCallbacks.create! title: "activerecord", author_name: nil topics = TopicWithCallbacks.where(id: [topic1.id, topic2.id]) - topics.update(title: 'adequaterecord') + topics.update(title: "adequaterecord") - assert_equal 'adequaterecord', topic1.reload.title - assert_equal 'adequaterecord', topic2.reload.title + assert_equal "adequaterecord", topic1.reload.title + assert_equal "adequaterecord", topic2.reload.title # Testing that the before_update callbacks have run - assert_equal 'David', topic1.reload.author_name - assert_equal 'David', topic2.reload.author_name + assert_equal "David", topic1.reload.author_name + assert_equal "David", topic2.reload.author_name end def test_update_on_relation_passing_active_record_object_is_deprecated - topic = Topic.create!(title: 'Foo', author_name: nil) + topic = Topic.create!(title: "Foo", author_name: nil) assert_deprecated(/update/) do - Topic.where(id: topic.id).update(topic, title: 'Bar') + Topic.where(id: topic.id).update(topic, title: "Bar") end end def test_distinct - tag1 = Tag.create(:name => 'Foo') - tag2 = Tag.create(:name => 'Foo') + tag1 = Tag.create(name: "Foo") + tag2 = Tag.create(name: "Foo") - query = Tag.select(:name).where(:id => [tag1.id, tag2.id]) + query = Tag.select(:name).where(id: [tag1.id, tag2.id]) - assert_equal ['Foo', 'Foo'], query.map(&:name) + assert_equal ["Foo", "Foo"], query.map(&:name) assert_sql(/DISTINCT/) do - assert_equal ['Foo'], query.distinct.map(&:name) - assert_deprecated { assert_equal ['Foo'], query.uniq.map(&:name) } + assert_equal ["Foo"], query.distinct.map(&:name) + assert_deprecated { assert_equal ["Foo"], query.uniq.map(&:name) } end assert_sql(/DISTINCT/) do - assert_equal ['Foo'], query.distinct(true).map(&:name) - assert_deprecated { assert_equal ['Foo'], query.uniq(true).map(&:name) } + assert_equal ["Foo"], query.distinct(true).map(&:name) + assert_deprecated { assert_equal ["Foo"], query.uniq(true).map(&:name) } end - assert_equal ['Foo', 'Foo'], query.distinct(true).distinct(false).map(&:name) + assert_equal ["Foo", "Foo"], query.distinct(true).distinct(false).map(&:name) assert_deprecated do - assert_equal ['Foo', 'Foo'], query.uniq(true).uniq(false).map(&:name) + assert_equal ["Foo", "Foo"], query.uniq(true).uniq(false).map(&:name) end end def test_doesnt_add_having_values_if_options_are_blank - scope = Post.having('') + scope = Post.having("") assert scope.having_clause.empty? scope = Post.having([]) @@ -1696,62 +1709,62 @@ class RelationTest < ActiveRecord::TestCase end def test_automatically_added_where_references - scope = Post.where(:comments => { :body => "Bla" }) - assert_equal ['comments'], scope.references_values + scope = Post.where(comments: { body: "Bla" }) + assert_equal ["comments"], scope.references_values - scope = Post.where('comments.body' => 'Bla') - assert_equal ['comments'], scope.references_values + scope = Post.where("comments.body" => "Bla") + assert_equal ["comments"], scope.references_values end def test_automatically_added_where_not_references scope = Post.where.not(comments: { body: "Bla" }) - assert_equal ['comments'], scope.references_values + assert_equal ["comments"], scope.references_values - scope = Post.where.not('comments.body' => 'Bla') - assert_equal ['comments'], scope.references_values + scope = Post.where.not("comments.body" => "Bla") + assert_equal ["comments"], scope.references_values end def test_automatically_added_having_references - scope = Post.having(:comments => { :body => "Bla" }) - assert_equal ['comments'], scope.references_values + scope = Post.having(comments: { body: "Bla" }) + assert_equal ["comments"], scope.references_values - scope = Post.having('comments.body' => 'Bla') - assert_equal ['comments'], scope.references_values + scope = Post.having("comments.body" => "Bla") + assert_equal ["comments"], scope.references_values end def test_automatically_added_order_references - scope = Post.order('comments.body') - assert_equal ['comments'], scope.references_values + scope = Post.order("comments.body") + assert_equal ["comments"], scope.references_values - scope = Post.order('comments.body', 'yaks.body') - assert_equal ['comments', 'yaks'], scope.references_values + scope = Post.order("comments.body", "yaks.body") + assert_equal ["comments", "yaks"], scope.references_values # Don't infer yaks, let's not go down that road again... - scope = Post.order('comments.body, yaks.body') - assert_equal ['comments'], scope.references_values + scope = Post.order("comments.body, yaks.body") + assert_equal ["comments"], scope.references_values - scope = Post.order('comments.body asc') - assert_equal ['comments'], scope.references_values + scope = Post.order("comments.body asc") + assert_equal ["comments"], scope.references_values - scope = Post.order('foo(comments.body)') + scope = Post.order("foo(comments.body)") assert_equal [], scope.references_values end def test_automatically_added_reorder_references - scope = Post.reorder('comments.body') + scope = Post.reorder("comments.body") assert_equal %w(comments), scope.references_values - scope = Post.reorder('comments.body', 'yaks.body') + scope = Post.reorder("comments.body", "yaks.body") assert_equal %w(comments yaks), scope.references_values # Don't infer yaks, let's not go down that road again... - scope = Post.reorder('comments.body, yaks.body') + scope = Post.reorder("comments.body, yaks.body") assert_equal %w(comments), scope.references_values - scope = Post.reorder('comments.body asc') + scope = Post.reorder("comments.body asc") assert_equal %w(comments), scope.references_values - scope = Post.reorder('foo(comments.body)') + scope = Post.reorder("foo(comments.body)") assert_equal [], scope.references_values end @@ -1798,7 +1811,7 @@ class RelationTest < ActiveRecord::TestCase end test "find_by with multi-arg conditions returns the first matching record" do - assert_equal posts(:eager_other), Post.order(:id).find_by('author_id = ?', 2) + assert_equal posts(:eager_other), Post.order(:id).find_by("author_id = ?", 2) end test "find_by returns nil if the record is missing" do @@ -1822,7 +1835,7 @@ class RelationTest < ActiveRecord::TestCase end test "find_by! with multi-arg conditions returns the first matching record" do - assert_equal posts(:eager_other), Post.order(:id).find_by!('author_id = ?', 2) + assert_equal posts(:eager_other), Post.order(:id).find_by!("author_id = ?", 2) end test "find_by! doesn't have implicit ordering" do @@ -1844,7 +1857,7 @@ class RelationTest < ActiveRecord::TestCase relation.to_a assert_raises(ActiveRecord::ImmutableRelation) do - relation.where! 'foo' + relation.where! "foo" end end @@ -1862,7 +1875,7 @@ class RelationTest < ActiveRecord::TestCase relation.to_a assert_raises(ActiveRecord::ImmutableRelation) do - relation.merge! where: 'foo' + relation.merge! where: "foo" end end @@ -1904,19 +1917,19 @@ class RelationTest < ActiveRecord::TestCase end end - test 'using a custom table affects the wheres' do - table_alias = Post.arel_table.alias('omg_posts') + test "using a custom table affects the wheres" do + table_alias = Post.arel_table.alias("omg_posts") table_metadata = ActiveRecord::TableMetadata.new(Post, table_alias) predicate_builder = ActiveRecord::PredicateBuilder.new(table_metadata) relation = ActiveRecord::Relation.new(Post, table_alias, predicate_builder) - relation.where!(:foo => "bar") + relation.where!(foo: "bar") node = relation.arel.constraints.first.grep(Arel::Attributes::Attribute).first assert_equal table_alias, node.relation end - test '#load' do + test "#load" do relation = Post.all assert_queries(1) do assert_equal relation, relation.load @@ -1924,9 +1937,9 @@ class RelationTest < ActiveRecord::TestCase assert_no_queries { relation.to_a } end - test 'group with select and includes' do - authors_count = Post.select('author_id, COUNT(author_id) AS num_posts'). - group('author_id').order('author_id').includes(:author).to_a + test "group with select and includes" do + authors_count = Post.select("author_id, COUNT(author_id) AS num_posts"). + group("author_id").order("author_id").includes(:author).to_a assert_no_queries do result = authors_count.map do |post| @@ -1952,7 +1965,7 @@ class RelationTest < ActiveRecord::TestCase def test_unscope_removes_binds left = Post.where(id: Arel::Nodes::BindParam.new) - column = Post.columns_hash['id'] + column = Post.columns_hash["id"] left.bind_values += [[column, 20]] relation = left.unscope(where: :id) @@ -1987,6 +2000,24 @@ class RelationTest < ActiveRecord::TestCase end def test_relation_join_method - assert_equal 'Thank you for the welcome,Thank you again for the welcome', Post.first.comments.join(",") + assert_equal "Thank you for the welcome,Thank you again for the welcome", Post.first.comments.join(",") + end + + def test_connection_adapters_can_reorder_binds + posts = Post.limit(1).offset(2) + + stubbed_connection = Post.connection.dup + def stubbed_connection.combine_bind_parameters(**kwargs) + offset = kwargs[:offset] + kwargs[:offset] = kwargs[:limit] + kwargs[:limit] = offset + super(**kwargs) + end + + posts.define_singleton_method(:connection) do + stubbed_connection + end + + assert_equal 2, posts.to_a.length end end diff --git a/activerecord/test/cases/reload_models_test.rb b/activerecord/test/cases/reload_models_test.rb index 431fbf1297..5dc9d6d8b7 100644 --- a/activerecord/test/cases/reload_models_test.rb +++ b/activerecord/test/cases/reload_models_test.rb @@ -1,13 +1,13 @@ require "cases/helper" -require 'models/owner' -require 'models/pet' +require "models/owner" +require "models/pet" class ReloadModelsTest < ActiveRecord::TestCase fixtures :pets, :owners def test_has_one_with_reload - pet = Pet.find_by_name('parrot') - pet.owner = Owner.find_by_name('ashley') + pet = Pet.find_by_name("parrot") + pet.owner = Owner.find_by_name("ashley") # Reload the class Owner, simulating auto-reloading of model classes in a # development environment. Note that meanwhile the class Pet is not @@ -15,8 +15,8 @@ class ReloadModelsTest < ActiveRecord::TestCase Object.class_eval { remove_const :Owner } Kernel.load(File.expand_path(File.join(File.dirname(__FILE__), "../models/owner.rb"))) - pet = Pet.find_by_name('parrot') - pet.owner = Owner.find_by_name('ashley') - assert_equal pet.owner, Owner.find_by_name('ashley') + pet = Pet.find_by_name("parrot") + pet.owner = Owner.find_by_name("ashley") + assert_equal pet.owner, Owner.find_by_name("ashley") end end diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb index dec01dfa76..949086fda0 100644 --- a/activerecord/test/cases/result_test.rb +++ b/activerecord/test/cases/result_test.rb @@ -3,10 +3,10 @@ require "cases/helper" module ActiveRecord class ResultTest < ActiveRecord::TestCase def result - Result.new(['col_1', 'col_2'], [ - ['row 1 col 1', 'row 1 col 2'], - ['row 2 col 1', 'row 2 col 2'], - ['row 3 col 1', 'row 3 col 2'], + Result.new(["col_1", "col_2"], [ + ["row 1 col 1", "row 1 col 2"], + ["row 2 col 1", "row 2 col 2"], + ["row 3 col 1", "row 3 col 2"], ]) end @@ -16,21 +16,31 @@ module ActiveRecord test "to_hash returns row_hashes" do assert_equal [ - {'col_1' => 'row 1 col 1', 'col_2' => 'row 1 col 2'}, - {'col_1' => 'row 2 col 1', 'col_2' => 'row 2 col 2'}, - {'col_1' => 'row 3 col 1', 'col_2' => 'row 3 col 2'}, + { "col_1" => "row 1 col 1", "col_2" => "row 1 col 2" }, + { "col_1" => "row 2 col 1", "col_2" => "row 2 col 2" }, + { "col_1" => "row 3 col 1", "col_2" => "row 3 col 2" }, ], result.to_hash end + test "first returns first row as a hash" do + assert_equal( + { "col_1" => "row 1 col 1", "col_2" => "row 1 col 2" }, result.first) + end + + test "last returns last row as a hash" do + assert_equal( + { "col_1" => "row 3 col 1", "col_2" => "row 3 col 2" }, result.last) + end + test "each with block returns row hashes" do result.each do |row| - assert_equal ['col_1', 'col_2'], row.keys + assert_equal ["col_1", "col_2"], row.keys end end test "each without block returns an enumerator" do result.each.with_index do |row, index| - assert_equal ['col_1', 'col_2'], row.keys + assert_equal ["col_1", "col_2"], row.keys assert_kind_of Integer, index end end diff --git a/activerecord/test/cases/sanitize_test.rb b/activerecord/test/cases/sanitize_test.rb index 239f63d27b..464bb12ccb 100644 --- a/activerecord/test/cases/sanitize_test.rb +++ b/activerecord/test/cases/sanitize_test.rb @@ -1,7 +1,7 @@ require "cases/helper" -require 'models/binary' -require 'models/author' -require 'models/post' +require "models/binary" +require "models/author" +require "models/post" class SanitizeTest < ActiveRecord::TestCase def setup @@ -36,42 +36,42 @@ class SanitizeTest < ActiveRecord::TestCase end def test_sanitize_sql_array_handles_relations - david = Author.create!(name: 'David') + david = Author.create!(name: "David") david_posts = david.posts.select(:id) sub_query_pattern = /\(\bselect\b.*?\bwhere\b.*?\)/i - select_author_sql = Post.send(:sanitize_sql_array, ['id in (?)', david_posts]) - assert_match(sub_query_pattern, select_author_sql, 'should sanitize `Relation` as subquery for bind variables') + select_author_sql = Post.send(:sanitize_sql_array, ["id in (?)", david_posts]) + assert_match(sub_query_pattern, select_author_sql, "should sanitize `Relation` as subquery for bind variables") - select_author_sql = Post.send(:sanitize_sql_array, ['id in (:post_ids)', post_ids: david_posts]) - assert_match(sub_query_pattern, select_author_sql, 'should sanitize `Relation` as subquery for named bind variables') + select_author_sql = Post.send(:sanitize_sql_array, ["id in (:post_ids)", post_ids: david_posts]) + assert_match(sub_query_pattern, select_author_sql, "should sanitize `Relation` as subquery for named bind variables") end def test_sanitize_sql_array_handles_empty_statement - select_author_sql = Post.send(:sanitize_sql_array, ['']) - assert_equal('', select_author_sql) + select_author_sql = Post.send(:sanitize_sql_array, [""]) + assert_equal("", select_author_sql) end def test_sanitize_sql_like - assert_equal '100\%', Binary.send(:sanitize_sql_like, '100%') - assert_equal 'snake\_cased\_string', Binary.send(:sanitize_sql_like, 'snake_cased_string') + assert_equal '100\%', Binary.send(:sanitize_sql_like, "100%") + assert_equal 'snake\_cased\_string', Binary.send(:sanitize_sql_like, "snake_cased_string") assert_equal 'C:\\\\Programs\\\\MsPaint', Binary.send(:sanitize_sql_like, 'C:\\Programs\\MsPaint') - assert_equal 'normal string 42', Binary.send(:sanitize_sql_like, 'normal string 42') + assert_equal "normal string 42", Binary.send(:sanitize_sql_like, "normal string 42") end def test_sanitize_sql_like_with_custom_escape_character - assert_equal '100!%', Binary.send(:sanitize_sql_like, '100%', '!') - assert_equal 'snake!_cased!_string', Binary.send(:sanitize_sql_like, 'snake_cased_string', '!') - assert_equal 'great!!', Binary.send(:sanitize_sql_like, 'great!', '!') - assert_equal 'C:\\Programs\\MsPaint', Binary.send(:sanitize_sql_like, 'C:\\Programs\\MsPaint', '!') - assert_equal 'normal string 42', Binary.send(:sanitize_sql_like, 'normal string 42', '!') + assert_equal "100!%", Binary.send(:sanitize_sql_like, "100%", "!") + assert_equal "snake!_cased!_string", Binary.send(:sanitize_sql_like, "snake_cased_string", "!") + assert_equal "great!!", Binary.send(:sanitize_sql_like, "great!", "!") + assert_equal 'C:\\Programs\\MsPaint', Binary.send(:sanitize_sql_like, 'C:\\Programs\\MsPaint', "!") + assert_equal "normal string 42", Binary.send(:sanitize_sql_like, "normal string 42", "!") end def test_sanitize_sql_like_example_use_case searchable_post = Class.new(Post) do def self.search(term) - where("title LIKE ?", sanitize_sql_like(term, '!')) + where("title LIKE ?", sanitize_sql_like(term, "!")) end end @@ -81,25 +81,25 @@ class SanitizeTest < ActiveRecord::TestCase end def test_bind_arity - assert_nothing_raised { bind '' } - assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '', 1 } + assert_nothing_raised { bind "" } + assert_raise(ActiveRecord::PreparedStatementInvalid) { bind "", 1 } - assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '?' } - assert_nothing_raised { bind '?', 1 } - assert_raise(ActiveRecord::PreparedStatementInvalid) { bind '?', 1, 1 } + assert_raise(ActiveRecord::PreparedStatementInvalid) { bind "?" } + assert_nothing_raised { bind "?", 1 } + assert_raise(ActiveRecord::PreparedStatementInvalid) { bind "?", 1, 1 } end def test_named_bind_variables - assert_equal '1', bind(':a', :a => 1) # ' ruby-mode - assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode + assert_equal "1", bind(":a", a: 1) # ' ruby-mode + assert_equal "1 1", bind(":a :a", a: 1) # ' ruby-mode - assert_nothing_raised { bind("'+00:00'", :foo => "bar") } + assert_nothing_raised { bind("'+00:00'", foo: "bar") } end def test_named_bind_arity - assert_nothing_raised { bind "name = :name", { name: "37signals" } } - assert_nothing_raised { bind "name = :name", { name: "37signals", id: 1 } } - assert_raise(ActiveRecord::PreparedStatementInvalid) { bind "name = :name", { id: 1 } } + assert_nothing_raised { bind "name = :name", name: "37signals" } + assert_nothing_raised { bind "name = :name", name: "37signals", id: 1 } + assert_raise(ActiveRecord::PreparedStatementInvalid) { bind "name = :name", id: 1 } end class SimpleEnumerable @@ -117,50 +117,50 @@ class SanitizeTest < ActiveRecord::TestCase def test_bind_enumerable quoted_abc = %(#{ActiveRecord::Base.connection.quote('a')},#{ActiveRecord::Base.connection.quote('b')},#{ActiveRecord::Base.connection.quote('c')}) - assert_equal '1,2,3', bind('?', [1, 2, 3]) - assert_equal quoted_abc, bind('?', %w(a b c)) + assert_equal "1,2,3", bind("?", [1, 2, 3]) + assert_equal quoted_abc, bind("?", %w(a b c)) - assert_equal '1,2,3', bind(':a', :a => [1, 2, 3]) - assert_equal quoted_abc, bind(':a', :a => %w(a b c)) # ' + assert_equal "1,2,3", bind(":a", a: [1, 2, 3]) + assert_equal quoted_abc, bind(":a", a: %w(a b c)) # ' - assert_equal '1,2,3', bind('?', SimpleEnumerable.new([1, 2, 3])) - assert_equal quoted_abc, bind('?', SimpleEnumerable.new(%w(a b c))) + assert_equal "1,2,3", bind("?", SimpleEnumerable.new([1, 2, 3])) + assert_equal quoted_abc, bind("?", SimpleEnumerable.new(%w(a b c))) - assert_equal '1,2,3', bind(':a', :a => SimpleEnumerable.new([1, 2, 3])) - assert_equal quoted_abc, bind(':a', :a => SimpleEnumerable.new(%w(a b c))) # ' + assert_equal "1,2,3", bind(":a", a: SimpleEnumerable.new([1, 2, 3])) + assert_equal quoted_abc, bind(":a", a: SimpleEnumerable.new(%w(a b c))) # ' end def test_bind_empty_enumerable quoted_nil = ActiveRecord::Base.connection.quote(nil) - assert_equal quoted_nil, bind('?', []) - assert_equal " in (#{quoted_nil})", bind(' in (?)', []) - assert_equal "foo in (#{quoted_nil})", bind('foo in (?)', []) + assert_equal quoted_nil, bind("?", []) + assert_equal " in (#{quoted_nil})", bind(" in (?)", []) + assert_equal "foo in (#{quoted_nil})", bind("foo in (?)", []) end def test_bind_empty_string - quoted_empty = ActiveRecord::Base.connection.quote('') - assert_equal quoted_empty, bind('?', '') + quoted_empty = ActiveRecord::Base.connection.quote("") + assert_equal quoted_empty, bind("?", "") end def test_bind_chars quoted_bambi = ActiveRecord::Base.connection.quote("Bambi") quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote("Bambi\nand\nThumper") - assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi") - assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper") - assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi".mb_chars) - assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper".mb_chars) + assert_equal "name=#{quoted_bambi}", bind("name=?", "Bambi") + assert_equal "name=#{quoted_bambi_and_thumper}", bind("name=?", "Bambi\nand\nThumper") + assert_equal "name=#{quoted_bambi}", bind("name=?", "Bambi".mb_chars) + assert_equal "name=#{quoted_bambi_and_thumper}", bind("name=?", "Bambi\nand\nThumper".mb_chars) end def test_bind_record o = Struct.new(:quoted_id).new(1) - assert_equal '1', bind('?', o) + assert_equal "1", bind("?", o) os = [o] * 3 - assert_equal '1,1,1', bind('?', os) + assert_equal "1,1,1", bind("?", os) end def test_named_bind_with_postgresql_type_casts - l = Proc.new { bind(":a::integer '2009-01-01'::date", :a => '10') } + l = Proc.new { bind(":a::integer '2009-01-01'::date", a: "10") } assert_nothing_raised(&l) assert_equal "#{ActiveRecord::Base.connection.quote('10')}::integer '2009-01-01'::date", l.call end diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 8bf7cf6b96..8b604ba930 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'support/schema_dumping_helper' +require "support/schema_dumping_helper" class SchemaDumperTest < ActiveRecord::TestCase include SchemaDumpingHelper @@ -20,7 +20,7 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_dump_schema_information_outputs_lexically_ordered_versions versions = %w{ 20100101010101 20100201010101 20100301010101 } versions.reverse_each do |v| - ActiveRecord::SchemaMigration.create!(:version => v) + ActiveRecord::SchemaMigration.create!(version: v) end schema_info = ActiveRecord::Base.connection.dump_schema_information @@ -37,7 +37,7 @@ class SchemaDumperTest < ActiveRecord::TestCase versions = %w{ 20100101010101 20100201010101 20100301010101 } versions.reverse_each do |v| - ActiveRecord::SchemaMigration.create!(:version => v) + ActiveRecord::SchemaMigration.create!(version: v) end schema_info = ActiveRecord::Base.connection.dump_schema_information @@ -47,10 +47,6 @@ class SchemaDumperTest < ActiveRecord::TestCase end end - def test_magic_comment - assert_match "# encoding: #{Encoding.default_external.name}", standard_dump - end - def test_schema_dump output = standard_dump assert_match %r{create_table "accounts"}, output @@ -74,38 +70,35 @@ class SchemaDumperTest < ActiveRecord::TestCase assert_match %r{create_table "CamelCase"}, output end - def assert_line_up(lines, pattern, required = false) + def assert_no_line_up(lines, pattern) 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 + 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/) } + output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map { |m| m.last.split(/\n/) } end - def test_types_line_up + def test_types_no_line_up column_definition_lines.each do |column_set| next if column_set.empty? - lengths = column_set.map do |column| - if match = column.match(/\bt\.\w+\s+(?="\w+?")/) - match[0].length - end - end.compact - - assert_equal 1, lengths.uniq.length + assert column_set.all? { |column| !column.match(/\bt\.\w+\s{2,}/) } end end - def test_arguments_line_up + def test_arguments_no_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: /) + assert_no_line_up(column_set, /default: /) + assert_no_line_up(column_set, /limit: /) + assert_no_line_up(column_set, /null: /) end end @@ -173,7 +166,7 @@ class SchemaDumperTest < ActiveRecord::TestCase end def test_schema_dump_with_string_ignored_table - output = dump_all_table_schema(['accounts']) + output = dump_all_table_schema(["accounts"]) assert_no_match %r{create_table "accounts"}, output assert_match %r{create_table "authors"}, output assert_no_match %r{create_table "schema_migrations"}, output @@ -222,12 +215,17 @@ class SchemaDumperTest < ActiveRecord::TestCase assert_match %r{t\.boolean\s+"has_fun",.+default: false}, output end - if current_adapter?(:Mysql2Adapter) - def test_schema_dump_should_add_default_value_for_mysql_text_field - output = standard_dump - assert_match %r{t\.text\s+"body",\s+limit: 65535,\s+null: false$}, output - end + def test_schema_dump_does_not_include_limit_for_text_field + output = standard_dump + assert_match %r{t\.text\s+"params"$}, output + end + + def test_schema_dump_does_not_include_limit_for_binary_field + output = standard_dump + assert_match %r{t\.binary\s+"data"$}, output + end + if current_adapter?(:Mysql2Adapter) def test_schema_dump_includes_length_for_mysql_binary_fields output = standard_dump assert_match %r{t\.binary\s+"var_binary",\s+limit: 255$}, output @@ -237,11 +235,11 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_schema_dump_includes_length_for_mysql_blob_and_text_fields output = standard_dump assert_match %r{t\.blob\s+"tiny_blob",\s+limit: 255$}, output - assert_match %r{t\.binary\s+"normal_blob",\s+limit: 65535$}, 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: 4294967295$}, output assert_match %r{t\.text\s+"tiny_text",\s+limit: 255$}, output - assert_match %r{t\.text\s+"normal_text",\s+limit: 65535$}, 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: 4294967295$}, output end @@ -288,7 +286,7 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_schema_dump_includes_extensions connection = ActiveRecord::Base.connection - connection.stubs(:extensions).returns(['hstore']) + connection.stubs(:extensions).returns(["hstore"]) output = perform_schema_dump assert_match "# These are extensions that must be enabled", output assert_match %r{enable_extension "hstore"}, output @@ -358,8 +356,8 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_schema_dump_with_table_name_prefix_and_suffix original, $stdout = $stdout, StringIO.new - ActiveRecord::Base.table_name_prefix = 'foo_' - ActiveRecord::Base.table_name_suffix = '_bar' + ActiveRecord::Base.table_name_prefix = "foo_" + ActiveRecord::Base.table_name_suffix = "_bar" migration = CreateDogMigration.new migration.migrate(:up) @@ -377,7 +375,7 @@ class SchemaDumperTest < ActiveRecord::TestCase ensure migration.migrate(:down) - ActiveRecord::Base.table_name_suffix = ActiveRecord::Base.table_name_prefix = '' + ActiveRecord::Base.table_name_suffix = ActiveRecord::Base.table_name_prefix = "" $stdout = original end @@ -395,7 +393,7 @@ class SchemaDumperTest < ActiveRecord::TestCase original_table_name_prefix = ActiveRecord::Base.table_name_prefix original_schema_dumper_ignore_tables = ActiveRecord::SchemaDumper.ignore_tables - ActiveRecord::Base.table_name_prefix = 'omg_' + ActiveRecord::Base.table_name_prefix = "omg_" ActiveRecord::SchemaDumper.ignore_tables = ["cats"] migration = create_cat_migration.new migration.migrate(:up) @@ -421,7 +419,7 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase @connection = ActiveRecord::Base.connection @connection.create_table :defaults, force: true do |t| t.string :string_with_default, default: "Hello!" - t.date :date_with_default, default: '2014-06-05' + t.date :date_with_default, default: "2014-06-05" t.datetime :datetime_with_default, default: "2014-06-05 07:17:04" t.time :time_with_default, default: "07:17:04" end @@ -436,11 +434,11 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase teardown do return unless @connection - @connection.drop_table 'defaults', if_exists: true + @connection.drop_table "defaults", if_exists: true end def test_schema_dump_defaults_with_universally_supported_types - output = dump_table_schema('defaults') + output = dump_table_schema("defaults") assert_match %r{t\.string\s+"string_with_default",.*?default: "Hello!"}, output assert_match %r{t\.date\s+"date_with_default",\s+default: '2014-06-05'}, output diff --git a/activerecord/test/cases/schema_loading_test.rb b/activerecord/test/cases/schema_loading_test.rb index 2815ccd842..3d92a5e104 100644 --- a/activerecord/test/cases/schema_loading_test.rb +++ b/activerecord/test/cases/schema_loading_test.rb @@ -1,4 +1,3 @@ -require 'thread' require "cases/helper" module SchemaLoadCounter diff --git a/activerecord/test/cases/scoping/default_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb index dcd09b6973..61062da3e1 100644 --- a/activerecord/test/cases/scoping/default_scoping_test.rb +++ b/activerecord/test/cases/scoping/default_scoping_test.rb @@ -1,16 +1,17 @@ -require 'cases/helper' -require 'models/post' -require 'models/comment' -require 'models/developer' -require 'models/computer' -require 'models/vehicle' -require 'models/cat' +require "cases/helper" +require "models/post" +require "models/comment" +require "models/developer" +require "models/computer" +require "models/vehicle" +require "models/cat" +require "active_support/core_ext/regexp" class DefaultScopingTest < ActiveRecord::TestCase fixtures :developers, :posts, :comments def test_default_scope - expected = Developer.all.merge!(:order => 'salary DESC').to_a.collect(&:salary) + expected = Developer.all.merge!(order: "salary DESC").to_a.collect(&:salary) received = DeveloperOrderedBySalary.all.collect(&:salary) assert_equal expected, received end @@ -49,20 +50,20 @@ class DefaultScopingTest < ActiveRecord::TestCase end def test_default_scope_with_conditions_string - assert_equal Developer.where(name: 'David').map(&:id).sort, DeveloperCalledDavid.all.map(&:id).sort + assert_equal Developer.where(name: "David").map(&:id).sort, DeveloperCalledDavid.all.map(&:id).sort assert_equal nil, DeveloperCalledDavid.create!.name end def test_default_scope_with_conditions_hash - assert_equal Developer.where(name: 'Jamis').map(&:id).sort, DeveloperCalledJamis.all.map(&:id).sort - assert_equal 'Jamis', DeveloperCalledJamis.create!.name + assert_equal Developer.where(name: "Jamis").map(&:id).sort, DeveloperCalledJamis.all.map(&:id).sort + assert_equal "Jamis", DeveloperCalledJamis.create!.name end unless in_memory_db? def test_default_scoping_with_threads 2.times do Thread.new { - assert DeveloperOrderedBySalary.all.to_sql.include?('salary DESC') + assert_includes DeveloperOrderedBySalary.all.to_sql, "salary DESC" DeveloperOrderedBySalary.connection.close }.join end @@ -71,37 +72,37 @@ class DefaultScopingTest < ActiveRecord::TestCase def test_default_scope_with_inheritance wheres = InheritedPoorDeveloperCalledJamis.all.where_values_hash - assert_equal "Jamis", wheres['name'] - assert_equal 50000, wheres['salary'] + assert_equal "Jamis", wheres["name"] + assert_equal 50000, wheres["salary"] end def test_default_scope_with_module_includes wheres = ModuleIncludedPoorDeveloperCalledJamis.all.where_values_hash - assert_equal "Jamis", wheres['name'] - assert_equal 50000, wheres['salary'] + assert_equal "Jamis", wheres["name"] + assert_equal 50000, wheres["salary"] end def test_default_scope_with_multiple_calls wheres = MultiplePoorDeveloperCalledJamis.all.where_values_hash - assert_equal "Jamis", wheres['name'] - assert_equal 50000, wheres['salary'] + assert_equal "Jamis", wheres["name"] + assert_equal 50000, wheres["salary"] end def test_scope_overwrites_default - expected = Developer.all.merge!(order: 'salary DESC, name DESC').to_a.collect(&:name) + expected = Developer.all.merge!(order: "salary DESC, name DESC").to_a.collect(&:name) received = DeveloperOrderedBySalary.by_name.to_a.collect(&:name) assert_equal expected, received end def test_reorder_overrides_default_scope_order - expected = Developer.order('name DESC').collect(&:name) - received = DeveloperOrderedBySalary.reorder('name DESC').collect(&:name) + expected = Developer.order("name DESC").collect(&:name) + received = DeveloperOrderedBySalary.reorder("name DESC").collect(&:name) assert_equal expected, received end def test_order_after_reorder_combines_orders - expected = Developer.order('name DESC, id DESC').collect { |dev| [dev.name, dev.id] } - received = Developer.order('name ASC').reorder('name DESC').order('id DESC').collect { |dev| [dev.name, dev.id] } + expected = Developer.order("name DESC, id DESC").collect { |dev| [dev.name, dev.id] } + received = Developer.order("name ASC").reorder("name DESC").order("id DESC").collect { |dev| [dev.name, dev.id] } assert_equal expected, received end @@ -112,107 +113,107 @@ class DefaultScopingTest < ActiveRecord::TestCase end def test_unscope_after_reordering_and_combining - expected = Developer.order('id DESC, name DESC').collect { |dev| [dev.name, dev.id] } - received = DeveloperOrderedBySalary.reorder('name DESC').unscope(:order).order('id DESC, name DESC').collect { |dev| [dev.name, dev.id] } + expected = Developer.order("id DESC, name DESC").collect { |dev| [dev.name, dev.id] } + received = DeveloperOrderedBySalary.reorder("name DESC").unscope(:order).order("id DESC, name DESC").collect { |dev| [dev.name, dev.id] } assert_equal expected, received expected_2 = Developer.all.collect { |dev| [dev.name, dev.id] } - received_2 = Developer.order('id DESC, name DESC').unscope(:order).collect { |dev| [dev.name, dev.id] } + received_2 = Developer.order("id DESC, name DESC").unscope(:order).collect { |dev| [dev.name, dev.id] } assert_equal expected_2, received_2 expected_3 = Developer.all.collect { |dev| [dev.name, dev.id] } - received_3 = Developer.reorder('name DESC').unscope(:order).collect { |dev| [dev.name, dev.id] } + received_3 = Developer.reorder("name DESC").unscope(:order).collect { |dev| [dev.name, dev.id] } assert_equal expected_3, received_3 end def test_unscope_with_where_attributes - expected = Developer.order('salary DESC').collect(&:name) - received = DeveloperOrderedBySalary.where(name: 'David').unscope(where: :name).collect(&:name) + expected = Developer.order("salary DESC").collect(&:name) + received = DeveloperOrderedBySalary.where(name: "David").unscope(where: :name).collect(&:name) assert_equal expected, received - expected_2 = Developer.order('salary DESC').collect(&:name) - received_2 = DeveloperOrderedBySalary.select("id").where("name" => "Jamis").unscope({:where => :name}, :select).collect(&:name) + expected_2 = Developer.order("salary DESC").collect(&:name) + received_2 = DeveloperOrderedBySalary.select("id").where("name" => "Jamis").unscope({ where: :name }, :select).collect(&:name) assert_equal expected_2, received_2 - expected_3 = Developer.order('salary DESC').collect(&:name) + expected_3 = Developer.order("salary DESC").collect(&:name) received_3 = DeveloperOrderedBySalary.select("id").where("name" => "Jamis").unscope(:select, :where).collect(&:name) assert_equal expected_3, received_3 - expected_4 = Developer.order('salary DESC').collect(&:name) + expected_4 = Developer.order("salary DESC").collect(&:name) received_4 = DeveloperOrderedBySalary.where.not("name" => "Jamis").unscope(where: :name).collect(&:name) assert_equal expected_4, received_4 - expected_5 = Developer.order('salary DESC').collect(&:name) + expected_5 = Developer.order("salary DESC").collect(&:name) received_5 = DeveloperOrderedBySalary.where.not("name" => ["Jamis", "David"]).unscope(where: :name).collect(&:name) assert_equal expected_5, received_5 - expected_6 = Developer.order('salary DESC').collect(&:name) - received_6 = DeveloperOrderedBySalary.where(Developer.arel_table['name'].eq('David')).unscope(where: :name).collect(&:name) + expected_6 = Developer.order("salary DESC").collect(&:name) + received_6 = DeveloperOrderedBySalary.where(Developer.arel_table["name"].eq("David")).unscope(where: :name).collect(&:name) assert_equal expected_6, received_6 - expected_7 = Developer.order('salary DESC').collect(&:name) - received_7 = DeveloperOrderedBySalary.where(Developer.arel_table[:name].eq('David')).unscope(where: :name).collect(&:name) + expected_7 = Developer.order("salary DESC").collect(&:name) + received_7 = DeveloperOrderedBySalary.where(Developer.arel_table[:name].eq("David")).unscope(where: :name).collect(&:name) assert_equal expected_7, received_7 end def test_unscope_comparison_where_clauses # unscoped for WHERE (`developers`.`id` <= 2) - expected = Developer.order('salary DESC').collect(&:name) + expected = Developer.order("salary DESC").collect(&:name) received = DeveloperOrderedBySalary.where(id: -Float::INFINITY..2).unscope(where: :id).collect { |dev| dev.name } assert_equal expected, received # unscoped for WHERE (`developers`.`id` < 2) - expected = Developer.order('salary DESC').collect(&:name) + expected = Developer.order("salary DESC").collect(&:name) received = DeveloperOrderedBySalary.where(id: -Float::INFINITY...2).unscope(where: :id).collect { |dev| dev.name } assert_equal expected, received end def test_unscope_multiple_where_clauses - expected = Developer.order('salary DESC').collect(&:name) - received = DeveloperOrderedBySalary.where(name: 'Jamis').where(id: 1).unscope(where: [:name, :id]).collect(&:name) + expected = Developer.order("salary DESC").collect(&:name) + received = DeveloperOrderedBySalary.where(name: "Jamis").where(id: 1).unscope(where: [:name, :id]).collect(&:name) assert_equal expected, received end def test_unscope_string_where_clauses_involved - dev_relation = Developer.order('salary DESC').where("created_at > ?", 1.year.ago) + dev_relation = Developer.order("salary DESC").where("created_at > ?", 1.year.ago) expected = dev_relation.collect(&:name) - dev_ordered_relation = DeveloperOrderedBySalary.where(name: 'Jamis').where("created_at > ?", 1.year.ago) + dev_ordered_relation = DeveloperOrderedBySalary.where(name: "Jamis").where("created_at > ?", 1.year.ago) received = dev_ordered_relation.unscope(where: [:name]).collect(&:name) assert_equal expected, received end def test_unscope_with_grouping_attributes - expected = Developer.order('salary DESC').collect(&:name) + expected = Developer.order("salary DESC").collect(&:name) received = DeveloperOrderedBySalary.group(:name).unscope(:group).collect(&:name) assert_equal expected, received - expected_2 = Developer.order('salary DESC').collect(&:name) + expected_2 = Developer.order("salary DESC").collect(&:name) received_2 = DeveloperOrderedBySalary.group("name").unscope(:group).collect(&:name) assert_equal expected_2, received_2 end def test_unscope_with_limit_in_query - expected = Developer.order('salary DESC').collect(&:name) + expected = Developer.order("salary DESC").collect(&:name) received = DeveloperOrderedBySalary.limit(1).unscope(:limit).collect(&:name) assert_equal expected, received end def test_order_to_unscope_reordering - scope = DeveloperOrderedBySalary.order('salary DESC, name ASC').reverse_order.unscope(:order) - assert !(scope.to_sql =~ /order/i) + scope = DeveloperOrderedBySalary.order("salary DESC, name ASC").reverse_order.unscope(:order) + assert !/order/i.match?(scope.to_sql) end def test_unscope_reverse_order expected = Developer.all.collect(&:name) - received = Developer.order('salary DESC').reverse_order.unscope(:order).collect(&:name) + received = Developer.order("salary DESC").reverse_order.unscope(:order).collect(&:name) assert_equal expected, received end def test_unscope_select - expected = Developer.order('salary ASC').collect(&:name) - received = Developer.order('salary DESC').reverse_order.select(:name).unscope(:select).collect(&:name) + expected = Developer.order("salary ASC").collect(&:name) + received = Developer.order("salary DESC").reverse_order.select(:name).unscope(:select).collect(&:name) assert_equal expected, received expected_2 = Developer.all.collect(&:id) @@ -228,7 +229,7 @@ class DefaultScopingTest < ActiveRecord::TestCase def test_unscope_joins_and_select_on_developers_projects expected = Developer.all.collect(&:name) - received = Developer.joins('JOIN developers_projects ON id = developer_id').select(:id).unscope(:joins, :select).collect(&:name) + received = Developer.joins("JOIN developers_projects ON id = developer_id").select(:id).unscope(:joins, :select).collect(&:name) assert_equal expected, received end @@ -249,8 +250,8 @@ class DefaultScopingTest < ActiveRecord::TestCase scope :by_name, -> name { unscope(where: :name).where(name: name) } end - expected = developer_klass.where(name: 'Jamis').collect { |dev| [dev.name, dev.id] } - received = developer_klass.where(name: 'David').by_name('Jamis').collect { |dev| [dev.name, dev.id] } + expected = developer_klass.where(name: "Jamis").collect { |dev| [dev.name, dev.id] } + received = developer_klass.where(name: "David").by_name("Jamis").collect { |dev| [dev.name, dev.id] } assert_equal expected, received end @@ -264,11 +265,11 @@ class DefaultScopingTest < ActiveRecord::TestCase end assert_raises(ArgumentError) do - Developer.order('name DESC').reverse_order.unscope(:reverse_order) + Developer.order("name DESC").reverse_order.unscope(:reverse_order) end assert_raises(ArgumentError) do - Developer.order('name DESC').where(name: "Jamis").unscope() + Developer.order("name DESC").where(name: "Jamis").unscope() end end @@ -303,35 +304,35 @@ class DefaultScopingTest < ActiveRecord::TestCase end def test_order_in_default_scope_should_not_prevail - expected = Developer.all.merge!(order: 'salary desc').to_a.collect(&:salary) - received = DeveloperOrderedBySalary.all.merge!(order: 'salary').to_a.collect(&:salary) + expected = Developer.all.merge!(order: "salary desc").to_a.collect(&:salary) + received = DeveloperOrderedBySalary.all.merge!(order: "salary").to_a.collect(&:salary) assert_equal expected, received end def test_create_attribute_overwrites_default_scoping - assert_equal 'David', PoorDeveloperCalledJamis.create!(:name => 'David').name - assert_equal 200000, PoorDeveloperCalledJamis.create!(:name => 'David', :salary => 200000).salary + assert_equal "David", PoorDeveloperCalledJamis.create!(name: "David").name + assert_equal 200000, PoorDeveloperCalledJamis.create!(name: "David", salary: 200000).salary end def test_create_attribute_overwrites_default_values - assert_equal nil, PoorDeveloperCalledJamis.create!(:salary => nil).salary - assert_equal 50000, PoorDeveloperCalledJamis.create!(:name => 'David').salary + assert_equal nil, PoorDeveloperCalledJamis.create!(salary: nil).salary + assert_equal 50000, PoorDeveloperCalledJamis.create!(name: "David").salary end def test_default_scope_attribute - jamis = PoorDeveloperCalledJamis.new(:name => 'David') + jamis = PoorDeveloperCalledJamis.new(name: "David") assert_equal 50000, jamis.salary end def test_where_attribute - aaron = PoorDeveloperCalledJamis.where(:salary => 20).new(:name => 'Aaron') + aaron = PoorDeveloperCalledJamis.where(salary: 20).new(name: "Aaron") assert_equal 20, aaron.salary - assert_equal 'Aaron', aaron.name + assert_equal "Aaron", aaron.name end def test_where_attribute_merge - aaron = PoorDeveloperCalledJamis.where(:name => 'foo').new(:name => 'Aaron') - assert_equal 'Aaron', aaron.name + aaron = PoorDeveloperCalledJamis.where(name: "foo").new(name: "Aaron") + assert_equal "Aaron", aaron.name end def test_scope_composed_by_limit_and_then_offset_is_equal_to_scope_composed_by_offset_and_then_limit @@ -341,33 +342,33 @@ class DefaultScopingTest < ActiveRecord::TestCase end def test_create_with_merge - aaron = PoorDeveloperCalledJamis.create_with(:name => 'foo', :salary => 20).merge( - PoorDeveloperCalledJamis.create_with(:name => 'Aaron')).new + aaron = PoorDeveloperCalledJamis.create_with(name: "foo", salary: 20).merge( + PoorDeveloperCalledJamis.create_with(name: "Aaron")).new assert_equal 20, aaron.salary - assert_equal 'Aaron', aaron.name + assert_equal "Aaron", aaron.name - aaron = PoorDeveloperCalledJamis.create_with(:name => 'foo', :salary => 20). - create_with(:name => 'Aaron').new + aaron = PoorDeveloperCalledJamis.create_with(name: "foo", salary: 20). + create_with(name: "Aaron").new assert_equal 20, aaron.salary - assert_equal 'Aaron', aaron.name + assert_equal "Aaron", aaron.name end def test_create_with_reset - jamis = PoorDeveloperCalledJamis.create_with(:name => 'Aaron').create_with(nil).new - assert_equal 'Jamis', jamis.name + jamis = PoorDeveloperCalledJamis.create_with(name: "Aaron").create_with(nil).new + assert_equal "Jamis", jamis.name end # FIXME: I don't know if this is *desired* behavior, but it is *today's* # behavior. def test_create_with_empty_hash_will_not_reset - jamis = PoorDeveloperCalledJamis.create_with(:name => 'Aaron').create_with({}).new - assert_equal 'Aaron', jamis.name + jamis = PoorDeveloperCalledJamis.create_with(name: "Aaron").create_with({}).new + assert_equal "Aaron", jamis.name end def test_unscoped_with_named_scope_should_not_have_default_scope assert_equal [DeveloperCalledJamis.find(developers(:poor_jamis).id)], DeveloperCalledJamis.poor - assert DeveloperCalledJamis.unscoped.poor.include?(developers(:david).becomes(DeveloperCalledJamis)) + assert_includes DeveloperCalledJamis.unscoped.poor, developers(:david).becomes(DeveloperCalledJamis) assert_equal 11, DeveloperCalledJamis.unscoped.length assert_equal 1, DeveloperCalledJamis.poor.length @@ -409,9 +410,9 @@ class DefaultScopingTest < ActiveRecord::TestCase def test_default_scope_include_with_count d = DeveloperWithIncludes.create! - d.audit_logs.create! :message => 'foo' + d.audit_logs.create! message: "foo" - assert_equal 1, DeveloperWithIncludes.where(:audit_logs => { :message => 'foo' }).count + assert_equal 1, DeveloperWithIncludes.where(audit_logs: { message: "foo" }).count end def test_default_scope_with_references_works_through_collection_association @@ -474,9 +475,9 @@ class DefaultScopingTest < ActiveRecord::TestCase end def test_sti_conditions_are_not_carried_in_default_scope - ConditionalStiPost.create! body: '' - SubConditionalStiPost.create! body: '' - SubConditionalStiPost.create! title: 'Hello world', body: '' + ConditionalStiPost.create! body: "" + SubConditionalStiPost.create! body: "" + SubConditionalStiPost.create! title: "Hello world", body: "" assert_equal 2, ConditionalStiPost.count assert_equal 2, ConditionalStiPost.all.to_a.size diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb index 96c94eefa0..58e1310ab0 100644 --- a/activerecord/test/cases/scoping/named_scoping_test.rb +++ b/activerecord/test/cases/scoping/named_scoping_test.rb @@ -1,11 +1,11 @@ require "cases/helper" -require 'models/post' -require 'models/topic' -require 'models/comment' -require 'models/reply' -require 'models/author' -require 'models/developer' -require 'models/computer' +require "models/post" +require "models/topic" +require "models/comment" +require "models/reply" +require "models/author" +require "models/developer" +require "models/computer" class NamedScopingTest < ActiveRecord::TestCase fixtures :posts, :authors, :topics, :comments, :author_addresses @@ -33,8 +33,8 @@ class NamedScopingTest < ActiveRecord::TestCase all_posts.to_a new_post = Topic.create! - assert !all_posts.include?(new_post) - assert all_posts.reload.include?(new_post) + assert_not_includes all_posts, new_post + assert_includes all_posts.reload, new_post end def test_delegates_finds_and_calculations_to_the_base_class @@ -46,11 +46,18 @@ class NamedScopingTest < ActiveRecord::TestCase assert_equal Topic.average(:replies_count), Topic.base.average(:replies_count) end + def test_calling_merge_at_first_in_scope + Topic.class_eval do + scope :calling_merge_at_first_in_scope, Proc.new { merge(Topic.replied) } + end + assert_equal Topic.calling_merge_at_first_in_scope.to_a, Topic.replied.to_a + end + def test_method_missing_priority_when_delegating klazz = Class.new(ActiveRecord::Base) do self.table_name = "topics" - scope :since, Proc.new { where('written_on >= ?', Time.now - 1.day) } - scope :to, Proc.new { where('written_on <= ?', Time.now) } + scope :since, Proc.new { where("written_on >= ?", Time.now - 1.day) } + scope :to, Proc.new { where("written_on <= ?", Time.now) } end assert_equal klazz.to.since.to_a, klazz.since.to.to_a end @@ -62,10 +69,10 @@ class NamedScopingTest < ActiveRecord::TestCase end def test_scopes_with_options_limit_finds_to_those_matching_the_criteria_specified - assert !Topic.all.merge!(:where => {:approved => true}).to_a.empty? + assert !Topic.all.merge!(where: { approved: true }).to_a.empty? - assert_equal Topic.all.merge!(:where => {:approved => true}).to_a, Topic.approved - assert_equal Topic.where(:approved => true).count, Topic.approved.count + assert_equal Topic.all.merge!(where: { approved: true }).to_a, Topic.approved + assert_equal Topic.where(approved: true).count, Topic.approved.count end def test_scopes_with_string_name_can_be_composed @@ -75,8 +82,8 @@ class NamedScopingTest < ActiveRecord::TestCase end def test_scopes_are_composable - assert_equal((approved = Topic.all.merge!(:where => {:approved => true}).to_a), Topic.approved) - assert_equal((replied = Topic.all.merge!(:where => 'replies_count > 0').to_a), Topic.replied) + assert_equal((approved = Topic.all.merge!(where: { approved: true }).to_a), Topic.approved) + assert_equal((replied = Topic.all.merge!(where: "replies_count > 0").to_a), Topic.replied) assert !(approved == replied) assert !(approved & replied).empty? @@ -84,8 +91,8 @@ class NamedScopingTest < ActiveRecord::TestCase end def test_procedural_scopes - topics_written_before_the_third = Topic.where('written_on < ?', topics(:third).written_on) - topics_written_before_the_second = Topic.where('written_on < ?', topics(:second).written_on) + topics_written_before_the_third = Topic.where("written_on < ?", topics(:third).written_on) + topics_written_before_the_second = Topic.where("written_on < ?", topics(:second).written_on) assert_not_equal topics_written_before_the_second, topics_written_before_the_third assert_equal topics_written_before_the_third, Topic.written_before(topics(:third).written_on) @@ -101,7 +108,7 @@ class NamedScopingTest < ActiveRecord::TestCase def test_scope_with_object objects = Topic.with_object assert_operator objects.length, :>, 0 - assert objects.all?(&:approved?), 'all objects should be approved' + assert objects.all?(&:approved?), "all objects should be approved" end def test_has_many_associations_have_access_to_scopes @@ -231,9 +238,9 @@ class NamedScopingTest < ActiveRecord::TestCase end def test_many_should_return_false_if_none_or_one - topics = Topic.base.where(:id => 0) + topics = Topic.base.where(id: 0) assert !topics.many? - topics = Topic.base.where(:id => 1) + topics = Topic.base.where(id: 1) assert !topics.many? end @@ -273,7 +280,7 @@ class NamedScopingTest < ActiveRecord::TestCase def test_should_build_on_top_of_chained_scopes topic = Topic.approved.by_lifo.build({}) assert topic.approved - assert_equal 'lifo', topic.author_name + assert_equal "lifo", topic.author_name end def test_reserved_scope_names @@ -301,7 +308,7 @@ class NamedScopingTest < ActiveRecord::TestCase :relation, # private class method on AR::Base :new, # redefined class method on AR::Base :all, # a default scope - :public, # some imporant methods on Module and Class + :public, # some important methods on Module and Class :protected, :private, :name, @@ -320,12 +327,12 @@ class NamedScopingTest < ActiveRecord::TestCase conflicts.each do |name| e = assert_raises(ArgumentError, "scope `#{name}` should not be allowed") do - klass.class_eval { scope name, ->{ where(approved: true) } } + klass.class_eval { scope name, -> { where(approved: true) } } end assert_match(/You tried to define a scope named \"#{name}\" on the model/, e.message) e = assert_raises(ArgumentError, "scope `#{name}` should not be allowed") do - subklass.class_eval { scope name, ->{ where(approved: true) } } + subklass.class_eval { scope name, -> { where(approved: true) } } end assert_match(/You tried to define a scope named \"#{name}\" on the model/, e.message) end @@ -333,12 +340,12 @@ class NamedScopingTest < ActiveRecord::TestCase non_conflicts.each do |name| assert_nothing_raised do silence_warnings do - klass.class_eval { scope name, ->{ where(approved: true) } } + klass.class_eval { scope name, -> { where(approved: true) } } end end assert_nothing_raised do - subklass.class_eval { scope name, ->{ where(approved: true) } } + subklass.class_eval { scope name, -> { where(approved: true) } } end end end @@ -350,7 +357,7 @@ class NamedScopingTest < ActiveRecord::TestCase klass = Class.new(ActiveRecord::Base) do self.table_name = "topics" scope :"title containing space", -> { where("title LIKE '% %'") } - scope :approved, -> { where(:approved => true) } + scope :approved, -> { where(approved: true) } end assert_equal klass.send(:"title containing space"), klass.where("title LIKE '% %'") assert_equal klass.approved.send(:"title containing space"), klass.approved.where("title LIKE '% %'") @@ -365,7 +372,7 @@ class NamedScopingTest < ActiveRecord::TestCase end def test_should_use_where_in_query_for_scope - assert_equal Developer.where(name: 'Jamis').to_set, Developer.where(id: Developer.jamises).to_set + assert_equal Developer.where(name: "Jamis").to_set, Developer.where(id: Developer.jamises).to_set end def test_size_should_use_count_when_results_are_not_loaded @@ -424,12 +431,12 @@ class NamedScopingTest < ActiveRecord::TestCase assert_equal 4, Topic.approved.count assert_queries(5) do - Topic.approved.find_each(:batch_size => 1) {|t| assert t.approved? } + Topic.approved.find_each(batch_size: 1) { |t| assert t.approved? } end assert_queries(3) do - Topic.approved.find_in_batches(:batch_size => 2) do |group| - group.each {|t| assert t.approved? } + Topic.approved.find_in_batches(batch_size: 2) do |group| + group.each { |t| assert t.approved? } end end end @@ -455,13 +462,13 @@ class NamedScopingTest < ActiveRecord::TestCase [:public_method, :protected_method, :private_method].each do |reserved_method| assert Topic.respond_to?(reserved_method, true) ActiveRecord::Base.logger.expects(:warn) - silence_warnings { Topic.scope(reserved_method, -> { }) } + silence_warnings { Topic.scope(reserved_method, -> {}) } end end def test_scopes_on_relations # Topic.replied - approved_topics = Topic.all.approved.order('id DESC') + approved_topics = Topic.all.approved.order("id DESC") assert_equal topics(:fifth), approved_topics.first replied_approved_topics = approved_topics.replied @@ -469,7 +476,7 @@ class NamedScopingTest < ActiveRecord::TestCase end def test_index_on_scope - approved = Topic.approved.order('id ASC') + approved = Topic.approved.order("id ASC") assert_equal topics(:second), approved[0] assert approved.loaded? end @@ -510,7 +517,7 @@ class NamedScopingTest < ActiveRecord::TestCase def test_scopes_to_get_newest post = posts(:welcome) old_last_comment = post.comments.newest - new_comment = post.comments.create(:body => "My new comment") + new_comment = post.comments.create(body: "My new comment") assert_equal new_comment, post.comments.newest assert_not_equal old_last_comment, post.comments.newest end @@ -533,21 +540,15 @@ class NamedScopingTest < ActiveRecord::TestCase def test_eager_default_scope_relations_are_remove klass = Class.new(ActiveRecord::Base) - klass.table_name = 'posts' + klass.table_name = "posts" assert_raises(ArgumentError) do - klass.send(:default_scope, klass.where(:id => posts(:welcome).id)) + klass.send(:default_scope, klass.where(id: posts(:welcome).id)) end end def test_subclass_merges_scopes_properly - assert_equal 1, SpecialComment.where(body: 'go crazy').created.count - end - - def test_model_class_should_respond_to_empty - assert !Topic.empty? - Topic.delete_all - assert Topic.empty? + assert_equal 1, SpecialComment.where(body: "go crazy").created.count end def test_model_class_should_respond_to_none @@ -563,5 +564,4 @@ class NamedScopingTest < ActiveRecord::TestCase Topic.create! assert Topic.one? end - end diff --git a/activerecord/test/cases/scoping/relation_scoping_test.rb b/activerecord/test/cases/scoping/relation_scoping_test.rb index c15d57460b..27b4583457 100644 --- a/activerecord/test/cases/scoping/relation_scoping_test.rb +++ b/activerecord/test/cases/scoping/relation_scoping_test.rb @@ -1,13 +1,13 @@ require "cases/helper" -require 'models/post' -require 'models/author' -require 'models/developer' -require 'models/computer' -require 'models/project' -require 'models/comment' -require 'models/category' -require 'models/person' -require 'models/reference' +require "models/post" +require "models/author" +require "models/developer" +require "models/computer" +require "models/project" +require "models/comment" +require "models/category" +require "models/person" +require "models/reference" class RelationScopingTest < ActiveRecord::TestCase fixtures :authors, :developers, :projects, :comments, :posts, :developers_projects @@ -109,7 +109,7 @@ class RelationScopingTest < ActiveRecord::TestCase def test_scope_select_concatenates Developer.select("id, name").scoping do - developer = Developer.select('salary').where("name = 'David'").first + developer = Developer.select("salary").where("name = 'David'").first assert_equal 80000, developer.salary assert developer.has_attribute?(:id) assert developer.has_attribute?(:name) @@ -122,7 +122,7 @@ class RelationScopingTest < ActiveRecord::TestCase assert_equal 1, Developer.count end - Developer.where('salary = 100000').scoping do + Developer.where("salary = 100000").scoping do assert_equal 8, Developer.count assert_equal 1, Developer.where("name LIKE 'fixture_1%'").count end @@ -131,49 +131,49 @@ class RelationScopingTest < ActiveRecord::TestCase def test_scoped_find_include # with the include, will retrieve only developers for the given project scoped_developers = Developer.includes(:projects).scoping do - Developer.where('projects.id' => 2).to_a + Developer.where("projects.id" => 2).to_a end - assert scoped_developers.include?(developers(:david)) - assert !scoped_developers.include?(developers(:jamis)) + assert_includes scoped_developers, developers(:david) + assert_not_includes scoped_developers, developers(:jamis) assert_equal 1, scoped_developers.size end def test_scoped_find_joins - scoped_developers = Developer.joins('JOIN developers_projects ON id = developer_id').scoping do - Developer.where('developers_projects.project_id = 2').to_a + scoped_developers = Developer.joins("JOIN developers_projects ON id = developer_id").scoping do + Developer.where("developers_projects.project_id = 2").to_a end - assert scoped_developers.include?(developers(:david)) - assert !scoped_developers.include?(developers(:jamis)) + assert_includes scoped_developers, developers(:david) + assert_not_includes scoped_developers, developers(:jamis) assert_equal 1, scoped_developers.size assert_equal developers(:david).attributes, scoped_developers.first.attributes end def test_scoped_create_with_where - new_comment = VerySpecialComment.where(:post_id => 1).scoping do - VerySpecialComment.create :body => "Wonderful world" + new_comment = VerySpecialComment.where(post_id: 1).scoping do + VerySpecialComment.create body: "Wonderful world" end assert_equal 1, new_comment.post_id - assert Post.find(1).comments.include?(new_comment) + assert_includes Post.find(1).comments, new_comment end def test_scoped_create_with_create_with - new_comment = VerySpecialComment.create_with(:post_id => 1).scoping do - VerySpecialComment.create :body => "Wonderful world" + new_comment = VerySpecialComment.create_with(post_id: 1).scoping do + VerySpecialComment.create body: "Wonderful world" end assert_equal 1, new_comment.post_id - assert Post.find(1).comments.include?(new_comment) + assert_includes Post.find(1).comments, new_comment end def test_scoped_create_with_create_with_has_higher_priority - new_comment = VerySpecialComment.where(:post_id => 2).create_with(:post_id => 1).scoping do - VerySpecialComment.create :body => "Wonderful world" + new_comment = VerySpecialComment.where(post_id: 2).create_with(post_id: 1).scoping do + VerySpecialComment.create body: "Wonderful world" end assert_equal 1, new_comment.post_id - assert Post.find(1).comments.include?(new_comment) + assert_includes Post.find(1).comments, new_comment end def test_ensure_that_method_scoping_is_correctly_restored @@ -193,7 +193,7 @@ class RelationScopingTest < ActiveRecord::TestCase end def test_update_all_default_scope_filters_on_joins - DeveloperFilteredOnJoins.update_all(:salary => 65000) + DeveloperFilteredOnJoins.update_all(salary: 65000) assert_equal 65000, Developer.find(developers(:david).id).salary # has not changed jamis @@ -228,18 +228,25 @@ class RelationScopingTest < ActiveRecord::TestCase assert SpecialComment.all.any? end end + + def test_circular_joins_with_current_scope_does_not_crash + posts = Post.joins(comments: :post).scoping do + Post.current_scope.first(10) + end + assert_equal posts, Post.joins(comments: :post).first(10) + end end class NestedRelationScopingTest < ActiveRecord::TestCase fixtures :authors, :developers, :projects, :comments, :posts def test_merge_options - Developer.where('salary = 80000').scoping do + Developer.where("salary = 80000").scoping do Developer.limit(10).scoping do devs = Developer.all sql = devs.to_sql - assert_match '(salary = 80000)', sql - assert_match 'LIMIT 10', sql + assert_match "(salary = 80000)", sql + assert_match(/LIMIT 10|ROWNUM <= 10|FETCH FIRST 10 ROWS ONLY/, sql) end end end @@ -253,39 +260,39 @@ class NestedRelationScopingTest < ActiveRecord::TestCase end def test_replace_options - Developer.where(:name => 'David').scoping do + Developer.where(name: "David").scoping do Developer.unscoped do - assert_equal 'Jamis', Developer.where(:name => 'Jamis').first[:name] + assert_equal "Jamis", Developer.where(name: "Jamis").first[:name] end - assert_equal 'David', Developer.first[:name] + assert_equal "David", Developer.first[:name] end end def test_three_level_nested_exclusive_scoped_find Developer.where("name = 'Jamis'").scoping do - assert_equal 'Jamis', Developer.first.name + assert_equal "Jamis", Developer.first.name Developer.unscoped.where("name = 'David'") do - assert_equal 'David', Developer.first.name + assert_equal "David", Developer.first.name Developer.unscoped.where("name = 'Maiha'") do assert_equal nil, Developer.first end # ensure that scoping is restored - assert_equal 'David', Developer.first.name + assert_equal "David", Developer.first.name end # ensure that scoping is restored - assert_equal 'Jamis', Developer.first.name + assert_equal "Jamis", Developer.first.name end end def test_nested_scoped_create - comment = Comment.create_with(:post_id => 1).scoping do - Comment.create_with(:post_id => 2).scoping do - Comment.create :body => "Hey guys, nested scopes are broken. Please fix!" + comment = Comment.create_with(post_id: 1).scoping do + Comment.create_with(post_id: 2).scoping do + Comment.create body: "Hey guys, nested scopes are broken. Please fix!" end end @@ -293,15 +300,15 @@ class NestedRelationScopingTest < ActiveRecord::TestCase end def test_nested_exclusive_scope_for_create - comment = Comment.create_with(:body => "Hey guys, nested scopes are broken. Please fix!").scoping do - Comment.unscoped.create_with(:post_id => 1).scoping do + comment = Comment.create_with(body: "Hey guys, nested scopes are broken. Please fix!").scoping do + Comment.unscoped.create_with(post_id: 1).scoping do assert Comment.new.body.blank? - Comment.create :body => "Hey guys" + Comment.create body: "Hey guys" end end assert_equal 1, comment.post_id - assert_equal 'Hey guys', comment.body + assert_equal "Hey guys", comment.body end end @@ -313,24 +320,24 @@ class HasManyScopingTest < ActiveRecord::TestCase end def test_forwarding_of_static_methods - assert_equal 'a comment...', Comment.what_are_you - assert_equal 'a comment...', @welcome.comments.what_are_you + assert_equal "a comment...", Comment.what_are_you + assert_equal "a comment...", @welcome.comments.what_are_you end def test_forwarding_to_scoped - assert_equal 4, Comment.search_by_type('Comment').size - assert_equal 2, @welcome.comments.search_by_type('Comment').size + assert_equal 4, Comment.search_by_type("Comment").size + assert_equal 2, @welcome.comments.search_by_type("Comment").size end def test_nested_scope_finder - Comment.where('1=0').scoping do + Comment.where("1=0").scoping do assert_equal 0, @welcome.comments.count - assert_equal 'a comment...', @welcome.comments.what_are_you + assert_equal "a comment...", @welcome.comments.what_are_you end - Comment.where('1=1').scoping do + Comment.where("1=1").scoping do assert_equal 2, @welcome.comments.count - assert_equal 'a comment...', @welcome.comments.what_are_you + assert_equal "a comment...", @welcome.comments.what_are_you end end @@ -345,7 +352,7 @@ class HasManyScopingTest < ActiveRecord::TestCase end def test_should_maintain_default_scope_on_eager_loaded_associations - michael = Person.where(:id => people(:michael).id).includes(:bad_references).first + michael = Person.where(id: people(:michael).id).includes(:bad_references).first magician = BadReference.find(1) assert_equal [magician], michael.bad_references end @@ -359,19 +366,19 @@ class HasAndBelongsToManyScopingTest < ActiveRecord::TestCase end def test_forwarding_of_static_methods - assert_equal 'a category...', Category.what_are_you - assert_equal 'a category...', @welcome.categories.what_are_you + assert_equal "a category...", Category.what_are_you + assert_equal "a category...", @welcome.categories.what_are_you end def test_nested_scope_finder - Category.where('1=0').scoping do + Category.where("1=0").scoping do assert_equal 0, @welcome.categories.count - assert_equal 'a category...', @welcome.categories.what_are_you + assert_equal "a category...", @welcome.categories.what_are_you end - Category.where('1=1').scoping do + Category.where("1=1").scoping do assert_equal 2, @welcome.categories.count - assert_equal 'a category...', @welcome.categories.what_are_you + assert_equal "a category...", @welcome.categories.what_are_you end end end diff --git a/activerecord/test/cases/secure_token_test.rb b/activerecord/test/cases/secure_token_test.rb index e731443fc2..eda0229c26 100644 --- a/activerecord/test/cases/secure_token_test.rb +++ b/activerecord/test/cases/secure_token_test.rb @@ -1,5 +1,5 @@ -require 'cases/helper' -require 'models/user' +require "cases/helper" +require "models/user" class SecureTokenTest < ActiveRecord::TestCase setup do diff --git a/activerecord/test/cases/serialization_test.rb b/activerecord/test/cases/serialization_test.rb index 14b80f4df4..ec33ad38f2 100644 --- a/activerecord/test/cases/serialization_test.rb +++ b/activerecord/test/cases/serialization_test.rb @@ -1,9 +1,9 @@ require "cases/helper" -require 'models/contact' -require 'models/topic' -require 'models/book' -require 'models/author' -require 'models/post' +require "models/contact" +require "models/topic" +require "models/book" +require "models/author" +require "models/post" class SerializationTest < ActiveRecord::TestCase fixtures :books @@ -12,14 +12,14 @@ class SerializationTest < ActiveRecord::TestCase def setup @contact_attributes = { - :name => 'aaron stack', - :age => 25, - :avatar => 'binarydata', - :created_at => Time.utc(2006, 8, 1), - :awesome => false, - :preferences => { :gem => '<strong>ruby</strong>' }, - :alternative_id => nil, - :id => nil + name: "aaron stack", + age: 25, + avatar: "binarydata", + created_at: Time.utc(2006, 8, 1), + awesome: false, + preferences: { gem: "<strong>ruby</strong>" }, + alternative_id: nil, + id: nil } end @@ -38,7 +38,7 @@ class SerializationTest < ActiveRecord::TestCase def test_serialize_should_allow_attribute_only_filtering FORMATS.each do |format| - @serialized = Contact.new(@contact_attributes).send("to_#{format}", :only => [ :age, :name ]) + @serialized = Contact.new(@contact_attributes).send("to_#{format}", only: [ :age, :name ]) contact = Contact.new.send("from_#{format}", @serialized) assert_equal @contact_attributes[:name], contact.name, "For #{format}" assert_nil contact.avatar, "For #{format}" @@ -47,7 +47,7 @@ class SerializationTest < ActiveRecord::TestCase def test_serialize_should_allow_attribute_except_filtering FORMATS.each do |format| - @serialized = Contact.new(@contact_attributes).send("to_#{format}", :except => [ :age, :name ]) + @serialized = Contact.new(@contact_attributes).send("to_#{format}", except: [ :age, :name ]) contact = Contact.new.send("from_#{format}", @serialized) assert_nil contact.name, "For #{format}" assert_nil contact.age, "For #{format}" @@ -60,7 +60,7 @@ class SerializationTest < ActiveRecord::TestCase ActiveRecord::Base.include_root_in_json = true klazz = Class.new(ActiveRecord::Base) - klazz.table_name = 'topics' + klazz.table_name = "topics" assert klazz.include_root_in_json klazz.include_root_in_json = false @@ -73,7 +73,7 @@ class SerializationTest < ActiveRecord::TestCase def test_read_attribute_for_serialization_with_format_without_method_missing klazz = Class.new(ActiveRecord::Base) - klazz.table_name = 'books' + klazz.table_name = "books" book = klazz.new assert_nil book.read_attribute_for_serialization(:format) @@ -81,18 +81,18 @@ class SerializationTest < ActiveRecord::TestCase def test_read_attribute_for_serialization_with_format_after_init klazz = Class.new(ActiveRecord::Base) - klazz.table_name = 'books' + klazz.table_name = "books" - book = klazz.new(format: 'paperback') - assert_equal 'paperback', book.read_attribute_for_serialization(:format) + book = klazz.new(format: "paperback") + assert_equal "paperback", book.read_attribute_for_serialization(:format) end def test_read_attribute_for_serialization_with_format_after_find klazz = Class.new(ActiveRecord::Base) - klazz.table_name = 'books' + klazz.table_name = "books" book = klazz.find(books(:awdr).id) - assert_equal 'paperback', book.read_attribute_for_serialization(:format) + assert_equal "paperback", book.read_attribute_for_serialization(:format) end def test_find_records_by_serialized_attributes_through_join diff --git a/activerecord/test/cases/serialized_attribute_test.rb b/activerecord/test/cases/serialized_attribute_test.rb index 6056156698..8e9514de7c 100644 --- a/activerecord/test/cases/serialized_attribute_test.rb +++ b/activerecord/test/cases/serialized_attribute_test.rb @@ -1,10 +1,10 @@ -require 'cases/helper' -require 'models/topic' -require 'models/reply' -require 'models/person' -require 'models/traffic_light' -require 'models/post' -require 'bcrypt' +require "cases/helper" +require "models/topic" +require "models/reply" +require "models/person" +require "models/traffic_light" +require "models/post" +require "bcrypt" class SerializedAttributeTest < ActiveRecord::TestCase fixtures :topics, :posts @@ -25,7 +25,7 @@ class SerializedAttributeTest < ActiveRecord::TestCase def test_serialized_attribute Topic.serialize("content", MyObject) - myobj = MyObject.new('value1', 'value2') + myobj = MyObject.new("value1", "value2") topic = Topic.create("content" => myobj) assert_equal(myobj, topic.content) @@ -36,7 +36,7 @@ class SerializedAttributeTest < ActiveRecord::TestCase def test_serialized_attribute_in_base_class Topic.serialize("content", Hash) - hash = { 'content1' => 'value1', 'content2' => 'value2' } + hash = { "content1" => "value1", "content2" => "value2" } important_topic = ImportantTopic.create("content" => hash) assert_equal(hash, important_topic.content) @@ -97,7 +97,7 @@ class SerializedAttributeTest < ActiveRecord::TestCase end def test_serialized_attribute_declared_in_subclass - hash = { 'important1' => 'value1', 'important2' => 'value2' } + hash = { "important1" => "value1", "important2" => "value2" } important_topic = ImportantTopic.create("important" => hash) assert_equal(hash, important_topic.important) @@ -124,26 +124,26 @@ class SerializedAttributeTest < ActiveRecord::TestCase end def test_nil_not_serialized_without_class_constraint - assert Topic.new(:content => nil).save - assert_equal 1, Topic.where(:content => nil).count + assert Topic.new(content: nil).save + assert_equal 1, Topic.where(content: nil).count end def test_nil_not_serialized_with_class_constraint Topic.serialize :content, Hash - assert Topic.new(:content => nil).save - assert_equal 1, Topic.where(:content => nil).count + assert Topic.new(content: nil).save + assert_equal 1, Topic.where(content: nil).count end def test_serialized_attribute_should_raise_exception_on_assignment_with_wrong_type Topic.serialize(:content, Hash) assert_raise(ActiveRecord::SerializationTypeMismatch) do - Topic.new(content: 'string') + Topic.new(content: "string") end end def test_should_raise_exception_on_serialized_attribute_with_type_mismatch - myobj = MyObject.new('value1', 'value2') - topic = Topic.new(:content => myobj) + myobj = MyObject.new("value1", "value2") + topic = Topic.new(content: myobj) assert topic.save Topic.serialize(:content, Hash) assert_raise(ActiveRecord::SerializationTypeMismatch) { Topic.find(topic.id).content } @@ -152,11 +152,18 @@ class SerializedAttributeTest < ActiveRecord::TestCase def test_serialized_attribute_with_class_constraint settings = { "color" => "blue" } Topic.serialize(:content, Hash) - topic = Topic.new(:content => settings) + topic = Topic.new(content: settings) assert topic.save assert_equal(settings, Topic.find(topic.id).content) end + def test_where_by_serialized_attribute_with_hash + settings = { "color" => "green" } + Topic.serialize(:content, Hash) + topic = Topic.create!(content: settings) + assert_equal topic, Topic.where(content: settings).take + end + def test_serialized_default_class Topic.serialize(:content, Hash) topic = Topic.new @@ -175,14 +182,14 @@ class SerializedAttributeTest < ActiveRecord::TestCase end def test_serialized_boolean_value_true - topic = Topic.new(:content => true) + topic = Topic.new(content: true) assert topic.save topic = topic.reload assert_equal topic.content, true end def test_serialized_boolean_value_false - topic = Topic.new(:content => false) + topic = Topic.new(content: false) assert topic.save topic = topic.reload assert_equal topic.content, false @@ -200,18 +207,18 @@ class SerializedAttributeTest < ActiveRecord::TestCase end Topic.serialize(:content, some_class) - topic = Topic.new(:content => some_class.new('my value')) + topic = Topic.new(content: some_class.new("my value")) topic.save! topic.reload assert_kind_of some_class, topic.content - assert_equal topic.content, some_class.new('my value') + assert_equal topic.content, some_class.new("my value") end def test_serialize_attribute_via_select_method_when_time_zone_available with_timezone_config aware_attributes: true do Topic.serialize(:content, MyObject) - myobj = MyObject.new('value1', 'value2') + myobj = MyObject.new("value1", "value2") topic = Topic.create(content: myobj) assert_equal(myobj, Topic.select(:content).find(topic.id).content) @@ -220,8 +227,8 @@ class SerializedAttributeTest < ActiveRecord::TestCase end def test_serialize_attribute_can_be_serialized_in_an_integer_column - insures = ['life'] - person = SerializedPerson.new(first_name: 'David', insures: insures) + insures = ["life"] + person = SerializedPerson.new(first_name: "David", insures: insures) assert person.save person = person.reload assert_equal(insures, person.insures) @@ -295,4 +302,37 @@ class SerializedAttributeTest < ActiveRecord::TestCase topic.update_attribute :content, nil assert_equal [topic], Topic.where(content: nil) end + + def test_mutation_detection_does_not_double_serialize + coder = Object.new + def coder.dump(value) + return if value.nil? + value + " encoded" + end + def coder.load(value) + return if value.nil? + value.gsub(" encoded", "") + end + type = Class.new(ActiveRecord::Type::Value) do + include ActiveRecord::Type::Helpers::Mutable + + def serialize(value) + return if value.nil? + value + " serialized" + end + + def deserialize(value) + return if value.nil? + value.gsub(" serialized", "") + end + end.new + model = Class.new(Topic) do + attribute :foo, type + serialize :foo, coder + end + + topic = model.create!(foo: "bar") + topic.foo + refute topic.changed? + end end diff --git a/activerecord/test/cases/statement_cache_test.rb b/activerecord/test/cases/statement_cache_test.rb index 104226010a..f45f63c68e 100644 --- a/activerecord/test/cases/statement_cache_test.rb +++ b/activerecord/test/cases/statement_cache_test.rb @@ -1,8 +1,8 @@ -require 'cases/helper' -require 'models/book' -require 'models/liquid' -require 'models/molecule' -require 'models/electron' +require "cases/helper" +require "models/book" +require "models/liquid" +require "models/molecule" +require "models/electron" module ActiveRecord class StatementCacheTest < ActiveRecord::TestCase @@ -16,7 +16,7 @@ module ActiveRecord Book.create(name: "my other book") cache = StatementCache.create(Book.connection) do |params| - Book.where(:name => params.bind) + Book.where(name: params.bind) end b = cache.execute([ "my book" ], Book, Book.connection) @@ -25,7 +25,6 @@ module ActiveRecord assert_equal "my other book", b[0].name end - def test_statement_cache_id b1 = Book.create(name: "my book") b2 = Book.create(name: "my other book") @@ -65,12 +64,12 @@ module ActiveRecord def test_statement_cache_with_complex_statement cache = ActiveRecord::StatementCache.create(Book.connection) do |params| - Liquid.joins(:molecules => :electrons).where('molecules.name' => 'dioxane', 'electrons.name' => 'lepton') + Liquid.joins(molecules: :electrons).where("molecules.name" => "dioxane", "electrons.name" => "lepton") end - salty = Liquid.create(name: 'salty') - molecule = salty.molecules.create(name: 'dioxane') - molecule.electrons.create(name: 'lepton') + salty = Liquid.create(name: "salty") + molecule = salty.molecules.create(name: "dioxane") + molecule.electrons.create(name: "lepton") liquids = cache.execute([], Book, Book.connection) assert_equal "salty", liquids[0].name diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb index bce86875e1..633a8a0ebc 100644 --- a/activerecord/test/cases/store_test.rb +++ b/activerecord/test/cases/store_test.rb @@ -1,55 +1,55 @@ -require 'cases/helper' -require 'models/admin' -require 'models/admin/user' +require "cases/helper" +require "models/admin" +require "models/admin/user" class StoreTest < ActiveRecord::TestCase fixtures :'admin/users' setup do - @john = Admin::User.create!(:name => 'John Doe', :color => 'black', :remember_login => true, :height => 'tall', :is_a_good_guy => true) + @john = Admin::User.create!(name: "John Doe", color: "black", remember_login: true, height: "tall", is_a_good_guy: true) end test "reading store attributes through accessors" do - assert_equal 'black', @john.color + assert_equal "black", @john.color assert_nil @john.homepage end test "writing store attributes through accessors" do - @john.color = 'red' - @john.homepage = '37signals.com' + @john.color = "red" + @john.homepage = "37signals.com" - assert_equal 'red', @john.color - assert_equal '37signals.com', @john.homepage + assert_equal "red", @john.color + assert_equal "37signals.com", @john.homepage end test "accessing attributes not exposed by accessors" do - @john.settings[:icecream] = 'graeters' + @john.settings[:icecream] = "graeters" @john.save - assert_equal 'graeters', @john.reload.settings[:icecream] + assert_equal "graeters", @john.reload.settings[:icecream] end test "overriding a read accessor" do - @john.settings[:phone_number] = '1234567890' + @john.settings[:phone_number] = "1234567890" - assert_equal '(123) 456-7890', @john.phone_number + assert_equal "(123) 456-7890", @john.phone_number end test "overriding a read accessor using super" do @john.settings[:color] = nil - assert_equal 'red', @john.color + assert_equal "red", @john.color end test "updating the store will mark it as changed" do - @john.color = 'red' + @john.color = "red" assert @john.settings_changed? end test "updating the store populates the changed array correctly" do - @john.color = 'red' - assert_equal 'black', @john.settings_change[0]['color'] - assert_equal 'red', @john.settings_change[1]['color'] + @john.color = "red" + assert_equal "black", @john.settings_change[0]["color"] + assert_equal "red", @john.settings_change[1]["color"] end test "updating the store won't mark it as changed if an attribute isn't changed" do @@ -67,74 +67,74 @@ class StoreTest < ActiveRecord::TestCase end test "overriding a write accessor" do - @john.phone_number = '(123) 456-7890' + @john.phone_number = "(123) 456-7890" - assert_equal '1234567890', @john.settings[:phone_number] + assert_equal "1234567890", @john.settings[:phone_number] end test "overriding a write accessor using super" do - @john.color = 'yellow' + @john.color = "yellow" - assert_equal 'blue', @john.color + assert_equal "blue", @john.color end test "preserve store attributes data in HashWithIndifferentAccess format without any conversion" do - @john.json_data = ActiveSupport::HashWithIndifferentAccess.new(:height => 'tall', 'weight' => 'heavy') - @john.height = 'low' + @john.json_data = ActiveSupport::HashWithIndifferentAccess.new(:height => "tall", "weight" => "heavy") + @john.height = "low" assert_equal true, @john.json_data.instance_of?(ActiveSupport::HashWithIndifferentAccess) - assert_equal 'low', @john.json_data[:height] - assert_equal 'low', @john.json_data['height'] - assert_equal 'heavy', @john.json_data[:weight] - assert_equal 'heavy', @john.json_data['weight'] + assert_equal "low", @john.json_data[:height] + assert_equal "low", @john.json_data["height"] + assert_equal "heavy", @john.json_data[:weight] + assert_equal "heavy", @john.json_data["weight"] end test "convert store attributes from Hash to HashWithIndifferentAccess saving the data and access attributes indifferently" do - user = Admin::User.find_by_name('Jamis') - assert_equal 'symbol', user.settings[:symbol] - assert_equal 'symbol', user.settings['symbol'] - assert_equal 'string', user.settings[:string] - assert_equal 'string', user.settings['string'] + user = Admin::User.find_by_name("Jamis") + assert_equal "symbol", user.settings[:symbol] + assert_equal "symbol", user.settings["symbol"] + assert_equal "string", user.settings[:string] + assert_equal "string", user.settings["string"] assert_equal true, user.settings.instance_of?(ActiveSupport::HashWithIndifferentAccess) - user.height = 'low' - assert_equal 'symbol', user.settings[:symbol] - assert_equal 'symbol', user.settings['symbol'] - assert_equal 'string', user.settings[:string] - assert_equal 'string', user.settings['string'] + user.height = "low" + assert_equal "symbol", user.settings[:symbol] + assert_equal "symbol", user.settings["symbol"] + assert_equal "string", user.settings[:string] + assert_equal "string", user.settings["string"] assert_equal true, user.settings.instance_of?(ActiveSupport::HashWithIndifferentAccess) end test "convert store attributes from any format other than Hash or HashWithIndifferentAccess losing the data" do @john.json_data = "somedata" - @john.height = 'low' + @john.height = "low" assert_equal true, @john.json_data.instance_of?(ActiveSupport::HashWithIndifferentAccess) - assert_equal 'low', @john.json_data[:height] - assert_equal 'low', @john.json_data['height'] - assert_equal false, @john.json_data.delete_if { |k, v| k == 'height' }.any? + assert_equal "low", @john.json_data[:height] + assert_equal "low", @john.json_data["height"] + assert_equal false, @john.json_data.delete_if { |k, v| k == "height" }.any? end test "reading store attributes through accessors encoded with JSON" do - assert_equal 'tall', @john.height + assert_equal "tall", @john.height assert_nil @john.weight end test "writing store attributes through accessors encoded with JSON" do - @john.height = 'short' - @john.weight = 'heavy' + @john.height = "short" + @john.weight = "heavy" - assert_equal 'short', @john.height - assert_equal 'heavy', @john.weight + assert_equal "short", @john.height + assert_equal "heavy", @john.weight end test "accessing attributes not exposed by accessors encoded with JSON" do - @john.json_data['somestuff'] = 'somecoolstuff' + @john.json_data["somestuff"] = "somecoolstuff" @john.save - assert_equal 'somecoolstuff', @john.reload.json_data['somestuff'] + assert_equal "somecoolstuff", @john.reload.json_data["somestuff"] end test "updating the store will mark it as changed encoded with JSON" do - @john.height = 'short' + @john.height = "short" assert @john.json_data_changed? end diff --git a/activerecord/test/cases/suppressor_test.rb b/activerecord/test/cases/suppressor_test.rb index 7d44e36419..a7d16b7cdb 100644 --- a/activerecord/test/cases/suppressor_test.rb +++ b/activerecord/test/cases/suppressor_test.rb @@ -1,6 +1,6 @@ -require 'cases/helper' -require 'models/notification' -require 'models/user' +require "cases/helper" +require "models/notification" +require "models/user" class SuppressorTest < ActiveRecord::TestCase def test_suppresses_create @@ -15,22 +15,22 @@ class SuppressorTest < ActiveRecord::TestCase end def test_suppresses_update - user = User.create! token: 'asdf' + user = User.create! token: "asdf" User.suppress do - user.update token: 'ghjkl' - assert_equal 'asdf', user.reload.token + user.update token: "ghjkl" + assert_equal "asdf", user.reload.token - user.update! token: 'zxcvbnm' - assert_equal 'asdf', user.reload.token + user.update! token: "zxcvbnm" + assert_equal "asdf", user.reload.token - user.token = 'qwerty' + user.token = "qwerty" user.save - assert_equal 'asdf', user.reload.token + assert_equal "asdf", user.reload.token - user.token = 'uiop' + user.token = "uiop" user.save! - assert_equal 'asdf', user.reload.token + assert_equal "asdf", user.reload.token end end @@ -60,4 +60,16 @@ class SuppressorTest < ActiveRecord::TestCase end end end + + def test_suppresses_when_nested_multiple_times + assert_no_difference -> { Notification.count } do + Notification.suppress do + Notification.suppress {} + Notification.create + Notification.create! + Notification.new.save + Notification.new.save! + end + end + end end diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb index e6d731e1e1..d847a02679 100644 --- a/activerecord/test/cases/tasks/database_tasks_test.rb +++ b/activerecord/test/cases/tasks/database_tasks_test.rb @@ -1,5 +1,5 @@ -require 'cases/helper' -require 'active_record/tasks/database_tasks' +require "cases/helper" +require "active_record/tasks/database_tasks" module ActiveRecord module DatabaseTasksSetupper @@ -30,7 +30,7 @@ module ActiveRecord protected_environments = ActiveRecord::Base.protected_environments.dup current_env = ActiveRecord::Migrator.current_environment - assert !protected_environments.include?(current_env) + assert_not_includes protected_environments, current_env # Assert no error ActiveRecord::Tasks::DatabaseTasks.check_protected_environments! @@ -64,12 +64,12 @@ module ActiveRecord instance.expects(:structure_dump).with("awesome-file.sql") ActiveRecord::Tasks::DatabaseTasks.register_task(/foo/, klazz) - ActiveRecord::Tasks::DatabaseTasks.structure_dump({'adapter' => :foo}, "awesome-file.sql") + ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :foo }, "awesome-file.sql") end def test_unregistered_task assert_raise(ActiveRecord::Tasks::DatabaseNotSupported) do - ActiveRecord::Tasks::DatabaseTasks.structure_dump({'adapter' => :bar}, "awesome-file.sql") + ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :bar }, "awesome-file.sql") end end end @@ -80,20 +80,20 @@ module ActiveRecord ADAPTERS_TASKS.each do |k, v| define_method("test_#{k}_create") do eval("@#{v}").expects(:create) - ActiveRecord::Tasks::DatabaseTasks.create 'adapter' => k + ActiveRecord::Tasks::DatabaseTasks.create "adapter" => k end end end class DatabaseTasksCreateAllTest < ActiveRecord::TestCase def setup - @configurations = {'development' => {'database' => 'my-db'}} + @configurations = { "development" => { "database" => "my-db" } } ActiveRecord::Base.stubs(:configurations).returns(@configurations) end def test_ignores_configurations_without_databases - @configurations['development'].merge!('database' => nil) + @configurations["development"].merge!("database" => nil) ActiveRecord::Tasks::DatabaseTasks.expects(:create).never @@ -101,7 +101,7 @@ module ActiveRecord end def test_ignores_remote_databases - @configurations['development'].merge!('host' => 'my.server.tld') + @configurations["development"].merge!("host" => "my.server.tld") $stderr.stubs(:puts).returns(nil) ActiveRecord::Tasks::DatabaseTasks.expects(:create).never @@ -110,15 +110,15 @@ module ActiveRecord end def test_warning_for_remote_databases - @configurations['development'].merge!('host' => 'my.server.tld') + @configurations["development"].merge!("host" => "my.server.tld") - $stderr.expects(:puts).with('This task only modifies local databases. my-db is on a remote host.') + $stderr.expects(:puts).with("This task only modifies local databases. my-db is on a remote host.") ActiveRecord::Tasks::DatabaseTasks.create_all end def test_creates_configurations_with_local_ip - @configurations['development'].merge!('host' => '127.0.0.1') + @configurations["development"].merge!("host" => "127.0.0.1") ActiveRecord::Tasks::DatabaseTasks.expects(:create) @@ -126,7 +126,7 @@ module ActiveRecord end def test_creates_configurations_with_local_host - @configurations['development'].merge!('host' => 'localhost') + @configurations["development"].merge!("host" => "localhost") ActiveRecord::Tasks::DatabaseTasks.expects(:create) @@ -134,7 +134,7 @@ module ActiveRecord end def test_creates_configurations_with_blank_hosts - @configurations['development'].merge!('host' => nil) + @configurations["development"].merge!("host" => nil) ActiveRecord::Tasks::DatabaseTasks.expects(:create) @@ -145,9 +145,9 @@ module ActiveRecord class DatabaseTasksCreateCurrentTest < ActiveRecord::TestCase def setup @configurations = { - 'development' => {'database' => 'dev-db'}, - 'test' => {'database' => 'test-db'}, - 'production' => {'database' => 'prod-db'} + "development" => { "database" => "dev-db" }, + "test" => { "database" => "test-db" }, + "production" => { "database" => "prod-db" } } ActiveRecord::Base.stubs(:configurations).returns(@configurations) @@ -156,37 +156,37 @@ module ActiveRecord def test_creates_current_environment_database ActiveRecord::Tasks::DatabaseTasks.expects(:create). - with('database' => 'prod-db') + with("database" => "prod-db") ActiveRecord::Tasks::DatabaseTasks.create_current( - ActiveSupport::StringInquirer.new('production') + ActiveSupport::StringInquirer.new("production") ) end def test_creates_test_and_development_databases_when_env_was_not_specified ActiveRecord::Tasks::DatabaseTasks.expects(:create). - with('database' => 'dev-db') + with("database" => "dev-db") ActiveRecord::Tasks::DatabaseTasks.expects(:create). - with('database' => 'test-db') + with("database" => "test-db") ActiveRecord::Tasks::DatabaseTasks.create_current( - ActiveSupport::StringInquirer.new('development') + ActiveSupport::StringInquirer.new("development") ) end def test_creates_test_and_development_databases_when_rails_env_is_development - old_env = ENV['RAILS_ENV'] - ENV['RAILS_ENV'] = 'development' + old_env = ENV["RAILS_ENV"] + ENV["RAILS_ENV"] = "development" ActiveRecord::Tasks::DatabaseTasks.expects(:create). - with('database' => 'dev-db') + with("database" => "dev-db") ActiveRecord::Tasks::DatabaseTasks.expects(:create). - with('database' => 'test-db') + with("database" => "test-db") ActiveRecord::Tasks::DatabaseTasks.create_current( - ActiveSupport::StringInquirer.new('development') + ActiveSupport::StringInquirer.new("development") ) ensure - ENV['RAILS_ENV'] = old_env + ENV["RAILS_ENV"] = old_env end def test_establishes_connection_for_the_given_environment @@ -195,7 +195,7 @@ module ActiveRecord ActiveRecord::Base.expects(:establish_connection).with(:development) ActiveRecord::Tasks::DatabaseTasks.create_current( - ActiveSupport::StringInquirer.new('development') + ActiveSupport::StringInquirer.new("development") ) end end @@ -206,20 +206,20 @@ module ActiveRecord ADAPTERS_TASKS.each do |k, v| define_method("test_#{k}_drop") do eval("@#{v}").expects(:drop) - ActiveRecord::Tasks::DatabaseTasks.drop 'adapter' => k + ActiveRecord::Tasks::DatabaseTasks.drop "adapter" => k end end end class DatabaseTasksDropAllTest < ActiveRecord::TestCase def setup - @configurations = {:development => {'database' => 'my-db'}} + @configurations = { development: { "database" => "my-db" } } ActiveRecord::Base.stubs(:configurations).returns(@configurations) end def test_ignores_configurations_without_databases - @configurations[:development].merge!('database' => nil) + @configurations[:development].merge!("database" => nil) ActiveRecord::Tasks::DatabaseTasks.expects(:drop).never @@ -227,7 +227,7 @@ module ActiveRecord end def test_ignores_remote_databases - @configurations[:development].merge!('host' => 'my.server.tld') + @configurations[:development].merge!("host" => "my.server.tld") $stderr.stubs(:puts).returns(nil) ActiveRecord::Tasks::DatabaseTasks.expects(:drop).never @@ -236,15 +236,15 @@ module ActiveRecord end def test_warning_for_remote_databases - @configurations[:development].merge!('host' => 'my.server.tld') + @configurations[:development].merge!("host" => "my.server.tld") - $stderr.expects(:puts).with('This task only modifies local databases. my-db is on a remote host.') + $stderr.expects(:puts).with("This task only modifies local databases. my-db is on a remote host.") ActiveRecord::Tasks::DatabaseTasks.drop_all end def test_drops_configurations_with_local_ip - @configurations[:development].merge!('host' => '127.0.0.1') + @configurations[:development].merge!("host" => "127.0.0.1") ActiveRecord::Tasks::DatabaseTasks.expects(:drop) @@ -252,7 +252,7 @@ module ActiveRecord end def test_drops_configurations_with_local_host - @configurations[:development].merge!('host' => 'localhost') + @configurations[:development].merge!("host" => "localhost") ActiveRecord::Tasks::DatabaseTasks.expects(:drop) @@ -260,7 +260,7 @@ module ActiveRecord end def test_drops_configurations_with_blank_hosts - @configurations[:development].merge!('host' => nil) + @configurations[:development].merge!("host" => nil) ActiveRecord::Tasks::DatabaseTasks.expects(:drop) @@ -271,9 +271,9 @@ module ActiveRecord class DatabaseTasksDropCurrentTest < ActiveRecord::TestCase def setup @configurations = { - 'development' => {'database' => 'dev-db'}, - 'test' => {'database' => 'test-db'}, - 'production' => {'database' => 'prod-db'} + "development" => { "database" => "dev-db" }, + "test" => { "database" => "test-db" }, + "production" => { "database" => "prod-db" } } ActiveRecord::Base.stubs(:configurations).returns(@configurations) @@ -281,43 +281,45 @@ module ActiveRecord def test_drops_current_environment_database ActiveRecord::Tasks::DatabaseTasks.expects(:drop). - with('database' => 'prod-db') + with("database" => "prod-db") ActiveRecord::Tasks::DatabaseTasks.drop_current( - ActiveSupport::StringInquirer.new('production') + ActiveSupport::StringInquirer.new("production") ) end def test_drops_test_and_development_databases_when_env_was_not_specified ActiveRecord::Tasks::DatabaseTasks.expects(:drop). - with('database' => 'dev-db') + with("database" => "dev-db") ActiveRecord::Tasks::DatabaseTasks.expects(:drop). - with('database' => 'test-db') + with("database" => "test-db") ActiveRecord::Tasks::DatabaseTasks.drop_current( - ActiveSupport::StringInquirer.new('development') + ActiveSupport::StringInquirer.new("development") ) end def test_drops_testand_development_databases_when_rails_env_is_development - old_env = ENV['RAILS_ENV'] - ENV['RAILS_ENV'] = 'development' + old_env = ENV["RAILS_ENV"] + ENV["RAILS_ENV"] = "development" ActiveRecord::Tasks::DatabaseTasks.expects(:drop). - with('database' => 'dev-db') + with("database" => "dev-db") ActiveRecord::Tasks::DatabaseTasks.expects(:drop). - with('database' => 'test-db') + with("database" => "test-db") ActiveRecord::Tasks::DatabaseTasks.drop_current( - ActiveSupport::StringInquirer.new('development') + ActiveSupport::StringInquirer.new("development") ) ensure - ENV['RAILS_ENV'] = old_env + ENV["RAILS_ENV"] = old_env end end class DatabaseTasksMigrateTest < ActiveRecord::TestCase + self.use_transactional_tests = false + def setup - ActiveRecord::Tasks::DatabaseTasks.migrations_paths = 'custom/path' + ActiveRecord::Tasks::DatabaseTasks.migrations_paths = "custom/path" end def teardown @@ -325,15 +327,15 @@ module ActiveRecord end def test_migrate_receives_correct_env_vars - verbose, version = ENV['VERBOSE'], ENV['VERSION'] + verbose, version = ENV["VERBOSE"], ENV["VERSION"] - ENV['VERBOSE'] = 'false' - ENV['VERSION'] = '4' + ENV["VERBOSE"] = "false" + ENV["VERSION"] = "4" - ActiveRecord::Migrator.expects(:migrate).with('custom/path', 4) + ActiveRecord::Migrator.expects(:migrate).with("custom/path", 4) ActiveRecord::Tasks::DatabaseTasks.migrate ensure - ENV['VERBOSE'], ENV['VERSION'] = verbose, version + ENV["VERBOSE"], ENV["VERSION"] = verbose, version end def test_migrate_clears_schema_cache_afterward @@ -348,7 +350,7 @@ module ActiveRecord ADAPTERS_TASKS.each do |k, v| define_method("test_#{k}_purge") do eval("@#{v}").expects(:purge) - ActiveRecord::Tasks::DatabaseTasks.purge 'adapter' => k + ActiveRecord::Tasks::DatabaseTasks.purge "adapter" => k end end end @@ -356,27 +358,27 @@ module ActiveRecord class DatabaseTasksPurgeCurrentTest < ActiveRecord::TestCase def test_purges_current_environment_database configurations = { - 'development' => {'database' => 'dev-db'}, - 'test' => {'database' => 'test-db'}, - 'production' => {'database' => 'prod-db'} + "development" => { "database" => "dev-db" }, + "test" => { "database" => "test-db" }, + "production" => { "database" => "prod-db" } } ActiveRecord::Base.stubs(:configurations).returns(configurations) ActiveRecord::Tasks::DatabaseTasks.expects(:purge). - with('database' => 'prod-db') + with("database" => "prod-db") ActiveRecord::Base.expects(:establish_connection).with(:production) - ActiveRecord::Tasks::DatabaseTasks.purge_current('production') + ActiveRecord::Tasks::DatabaseTasks.purge_current("production") end end class DatabaseTasksPurgeAllTest < ActiveRecord::TestCase def test_purge_all_local_configurations - configurations = {:development => {'database' => 'my-db'}} + configurations = { development: { "database" => "my-db" } } ActiveRecord::Base.stubs(:configurations).returns(configurations) ActiveRecord::Tasks::DatabaseTasks.expects(:purge). - with('database' => 'my-db') + with("database" => "my-db") ActiveRecord::Tasks::DatabaseTasks.purge_all end @@ -388,7 +390,7 @@ module ActiveRecord ADAPTERS_TASKS.each do |k, v| define_method("test_#{k}_charset") do eval("@#{v}").expects(:charset) - ActiveRecord::Tasks::DatabaseTasks.charset 'adapter' => k + ActiveRecord::Tasks::DatabaseTasks.charset "adapter" => k end end end @@ -399,7 +401,7 @@ module ActiveRecord ADAPTERS_TASKS.each do |k, v| define_method("test_#{k}_collation") do eval("@#{v}").expects(:collation) - ActiveRecord::Tasks::DatabaseTasks.collation 'adapter' => k + ActiveRecord::Tasks::DatabaseTasks.collation "adapter" => k end end end @@ -410,7 +412,7 @@ module ActiveRecord ADAPTERS_TASKS.each do |k, v| define_method("test_#{k}_structure_dump") do eval("@#{v}").expects(:structure_dump).with("awesome-file.sql") - ActiveRecord::Tasks::DatabaseTasks.structure_dump({'adapter' => k}, "awesome-file.sql") + ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => k }, "awesome-file.sql") end end end @@ -421,7 +423,7 @@ module ActiveRecord ADAPTERS_TASKS.each do |k, v| define_method("test_#{k}_structure_load") do eval("@#{v}").expects(:structure_load).with("awesome-file.sql") - ActiveRecord::Tasks::DatabaseTasks.structure_load({'adapter' => k}, "awesome-file.sql") + ActiveRecord::Tasks::DatabaseTasks.structure_load({ "adapter" => k }, "awesome-file.sql") end end end @@ -435,15 +437,15 @@ module ActiveRecord class DatabaseTasksCheckSchemaFileDefaultsTest < ActiveRecord::TestCase def test_check_schema_file_defaults - ActiveRecord::Tasks::DatabaseTasks.stubs(:db_dir).returns('/tmp') - assert_equal '/tmp/schema.rb', ActiveRecord::Tasks::DatabaseTasks.schema_file + ActiveRecord::Tasks::DatabaseTasks.stubs(:db_dir).returns("/tmp") + assert_equal "/tmp/schema.rb", ActiveRecord::Tasks::DatabaseTasks.schema_file end end class DatabaseTasksCheckSchemaFileSpecifiedFormatsTest < ActiveRecord::TestCase - {ruby: 'schema.rb', sql: 'structure.sql'}.each_pair do |fmt, filename| + { ruby: "schema.rb", sql: "structure.sql" }.each_pair do |fmt, filename| define_method("test_check_schema_file_for_#{fmt}_format") do - ActiveRecord::Tasks::DatabaseTasks.stubs(:db_dir).returns('/tmp') + ActiveRecord::Tasks::DatabaseTasks.stubs(:db_dir).returns("/tmp") assert_equal "/tmp/#{filename}", ActiveRecord::Tasks::DatabaseTasks.schema_file(fmt) end end diff --git a/activerecord/test/cases/tasks/mysql_rake_test.rb b/activerecord/test/cases/tasks/mysql_rake_test.rb index 8e480bbaee..dbe935808e 100644 --- a/activerecord/test/cases/tasks/mysql_rake_test.rb +++ b/activerecord/test/cases/tasks/mysql_rake_test.rb @@ -1,345 +1,345 @@ -require 'cases/helper' -require 'active_record/tasks/database_tasks' +require "cases/helper" +require "active_record/tasks/database_tasks" if current_adapter?(:Mysql2Adapter) -module ActiveRecord - class MysqlDBCreateTest < ActiveRecord::TestCase - def setup - @connection = stub(:create_database => true) - @configuration = { - 'adapter' => 'mysql2', - 'database' => 'my-app-db' - } - - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - - $stdout, @original_stdout = StringIO.new, $stdout - $stderr, @original_stderr = StringIO.new, $stderr - end + module ActiveRecord + class MysqlDBCreateTest < ActiveRecord::TestCase + def setup + @connection = stub(create_database: true) + @configuration = { + "adapter" => "mysql2", + "database" => "my-app-db" + } + + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + + $stdout, @original_stdout = StringIO.new, $stdout + $stderr, @original_stderr = StringIO.new, $stderr + end - def teardown - $stdout, $stderr = @original_stdout, @original_stderr - end + def teardown + $stdout, $stderr = @original_stdout, @original_stderr + end - def test_establishes_connection_without_database - ActiveRecord::Base.expects(:establish_connection). - with('adapter' => 'mysql2', 'database' => nil) + def test_establishes_connection_without_database + ActiveRecord::Base.expects(:establish_connection). + with("adapter" => "mysql2", "database" => nil) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_creates_database_with_no_default_options - @connection.expects(:create_database). - with('my-app-db', {}) + def test_creates_database_with_no_default_options + @connection.expects(:create_database). + with("my-app-db", {}) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_creates_database_with_given_encoding - @connection.expects(:create_database). - with('my-app-db', charset: 'latin1') + def test_creates_database_with_given_encoding + @connection.expects(:create_database). + with("my-app-db", charset: "latin1") - ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge('encoding' => 'latin1') - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge("encoding" => "latin1") + end - def test_creates_database_with_given_collation - @connection.expects(:create_database). - with('my-app-db', collation: 'latin1_swedish_ci') + def test_creates_database_with_given_collation + @connection.expects(:create_database). + with("my-app-db", collation: "latin1_swedish_ci") - ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge('collation' => 'latin1_swedish_ci') - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge("collation" => "latin1_swedish_ci") + end - def test_establishes_connection_to_database - ActiveRecord::Base.expects(:establish_connection).with(@configuration) + def test_establishes_connection_to_database + ActiveRecord::Base.expects(:establish_connection).with(@configuration) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_when_database_created_successfully_outputs_info_to_stdout - ActiveRecord::Tasks::DatabaseTasks.create @configuration + def test_when_database_created_successfully_outputs_info_to_stdout + ActiveRecord::Tasks::DatabaseTasks.create @configuration - assert_equal $stdout.string, "Created database 'my-app-db'\n" - end + assert_equal $stdout.string, "Created database 'my-app-db'\n" + end - def test_create_when_database_exists_outputs_info_to_stderr - ActiveRecord::Base.connection.stubs(:create_database).raises( - ActiveRecord::Tasks::DatabaseAlreadyExists - ) + def test_create_when_database_exists_outputs_info_to_stderr + ActiveRecord::Base.connection.stubs(:create_database).raises( + ActiveRecord::Tasks::DatabaseAlreadyExists + ) - ActiveRecord::Tasks::DatabaseTasks.create @configuration + ActiveRecord::Tasks::DatabaseTasks.create @configuration - assert_equal $stderr.string, "Database 'my-app-db' already exists\n" + assert_equal $stderr.string, "Database 'my-app-db' already exists\n" + end end - end - class MysqlDBCreateAsRootTest < ActiveRecord::TestCase - def setup - @connection = stub("Connection", create_database: true) - @error = Mysql2::Error.new("Invalid permissions") - @configuration = { - 'adapter' => 'mysql2', - 'database' => 'my-app-db', - 'username' => 'pat', - 'password' => 'wossname' - } - - $stdin.stubs(:gets).returns("secret\n") - $stdout.stubs(:print).returns(nil) - @error.stubs(:errno).returns(1045) - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection). - raises(@error). - then.returns(true) - - $stdout, @original_stdout = StringIO.new, $stdout - $stderr, @original_stderr = StringIO.new, $stderr - end + class MysqlDBCreateAsRootTest < ActiveRecord::TestCase + def setup + @connection = stub("Connection", create_database: true) + @error = Mysql2::Error.new("Invalid permissions") + @configuration = { + "adapter" => "mysql2", + "database" => "my-app-db", + "username" => "pat", + "password" => "wossname" + } + + $stdin.stubs(:gets).returns("secret\n") + $stdout.stubs(:print).returns(nil) + @error.stubs(:errno).returns(1045) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection). + raises(@error). + then.returns(true) + + $stdout, @original_stdout = StringIO.new, $stdout + $stderr, @original_stderr = StringIO.new, $stderr + end - def teardown - $stdout, $stderr = @original_stdout, @original_stderr - end + def teardown + $stdout, $stderr = @original_stdout, @original_stderr + end - def test_root_password_is_requested - assert_permissions_granted_for("pat") - $stdin.expects(:gets).returns("secret\n") + def test_root_password_is_requested + assert_permissions_granted_for("pat") + $stdin.expects(:gets).returns("secret\n") - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_connection_established_as_root - assert_permissions_granted_for("pat") - ActiveRecord::Base.expects(:establish_connection).with( - 'adapter' => 'mysql2', - 'database' => nil, - 'username' => 'root', - 'password' => 'secret' - ) + def test_connection_established_as_root + assert_permissions_granted_for("pat") + ActiveRecord::Base.expects(:establish_connection).with( + "adapter" => "mysql2", + "database" => nil, + "username" => "root", + "password" => "secret" + ) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_database_created_by_root - assert_permissions_granted_for("pat") - @connection.expects(:create_database). - with('my-app-db', {}) + def test_database_created_by_root + assert_permissions_granted_for("pat") + @connection.expects(:create_database). + with("my-app-db", {}) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_grant_privileges_for_normal_user - assert_permissions_granted_for("pat") - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + def test_grant_privileges_for_normal_user + assert_permissions_granted_for("pat") + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_do_not_grant_privileges_for_root_user - @configuration['username'] = 'root' - @configuration['password'] = '' - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + def test_do_not_grant_privileges_for_root_user + @configuration["username"] = "root" + @configuration["password"] = "" + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_connection_established_as_normal_user - assert_permissions_granted_for("pat") - ActiveRecord::Base.expects(:establish_connection).returns do - ActiveRecord::Base.expects(:establish_connection).with( - 'adapter' => 'mysql2', - 'database' => 'my-app-db', - 'username' => 'pat', - 'password' => 'secret' - ) + def test_connection_established_as_normal_user + assert_permissions_granted_for("pat") + ActiveRecord::Base.expects(:establish_connection).returns do + ActiveRecord::Base.expects(:establish_connection).with( + "adapter" => "mysql2", + "database" => "my-app-db", + "username" => "pat", + "password" => "secret" + ) - raise @error - end + raise @error + end - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_sends_output_to_stderr_when_other_errors - @error.stubs(:errno).returns(42) + def test_sends_output_to_stderr_when_other_errors + @error.stubs(:errno).returns(42) - $stderr.expects(:puts).at_least_once.returns(nil) + $stderr.expects(:puts).at_least_once.returns(nil) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - private + private - def assert_permissions_granted_for(db_user) - db_name = @configuration['database'] - db_password = @configuration['password'] - @connection.expects(:execute).with("GRANT ALL PRIVILEGES ON #{db_name}.* TO '#{db_user}'@'localhost' IDENTIFIED BY '#{db_password}' WITH GRANT OPTION;") + def assert_permissions_granted_for(db_user) + db_name = @configuration["database"] + db_password = @configuration["password"] + @connection.expects(:execute).with("GRANT ALL PRIVILEGES ON #{db_name}.* TO '#{db_user}'@'localhost' IDENTIFIED BY '#{db_password}' WITH GRANT OPTION;") + end end - end - class MySQLDBDropTest < ActiveRecord::TestCase - def setup - @connection = stub(:drop_database => true) - @configuration = { - 'adapter' => 'mysql2', - 'database' => 'my-app-db' - } + class MySQLDBDropTest < ActiveRecord::TestCase + def setup + @connection = stub(drop_database: true) + @configuration = { + "adapter" => "mysql2", + "database" => "my-app-db" + } - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) - $stdout, @original_stdout = StringIO.new, $stdout - $stderr, @original_stderr = StringIO.new, $stderr - end + $stdout, @original_stdout = StringIO.new, $stdout + $stderr, @original_stderr = StringIO.new, $stderr + end - def teardown - $stdout, $stderr = @original_stdout, @original_stderr - end + def teardown + $stdout, $stderr = @original_stdout, @original_stderr + end - def test_establishes_connection_to_mysql_database - ActiveRecord::Base.expects(:establish_connection).with @configuration + def test_establishes_connection_to_mysql_database + ActiveRecord::Base.expects(:establish_connection).with @configuration - ActiveRecord::Tasks::DatabaseTasks.drop @configuration - end + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end - def test_drops_database - @connection.expects(:drop_database).with('my-app-db') + def test_drops_database + @connection.expects(:drop_database).with("my-app-db") - ActiveRecord::Tasks::DatabaseTasks.drop @configuration - end + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end - def test_when_database_dropped_successfully_outputs_info_to_stdout - ActiveRecord::Tasks::DatabaseTasks.drop @configuration + def test_when_database_dropped_successfully_outputs_info_to_stdout + ActiveRecord::Tasks::DatabaseTasks.drop @configuration - assert_equal $stdout.string, "Dropped database 'my-app-db'\n" + assert_equal $stdout.string, "Dropped database 'my-app-db'\n" + end end - end - class MySQLPurgeTest < ActiveRecord::TestCase - def setup - @connection = stub(:recreate_database => true) - @configuration = { - 'adapter' => 'mysql2', - 'database' => 'test-db' - } + class MySQLPurgeTest < ActiveRecord::TestCase + def setup + @connection = stub(recreate_database: true) + @configuration = { + "adapter" => "mysql2", + "database" => "test-db" + } - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - end + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end - def test_establishes_connection_to_the_appropriate_database - ActiveRecord::Base.expects(:establish_connection).with(@configuration) + def test_establishes_connection_to_the_appropriate_database + ActiveRecord::Base.expects(:establish_connection).with(@configuration) - ActiveRecord::Tasks::DatabaseTasks.purge @configuration - end + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end - def test_recreates_database_with_no_default_options - @connection.expects(:recreate_database). - with('test-db', {}) + def test_recreates_database_with_no_default_options + @connection.expects(:recreate_database). + with("test-db", {}) - ActiveRecord::Tasks::DatabaseTasks.purge @configuration - end + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end - def test_recreates_database_with_the_given_options - @connection.expects(:recreate_database). - with('test-db', charset: 'latin', collation: 'latin1_swedish_ci') + def test_recreates_database_with_the_given_options + @connection.expects(:recreate_database). + with("test-db", charset: "latin", collation: "latin1_swedish_ci") - ActiveRecord::Tasks::DatabaseTasks.purge @configuration.merge( - 'encoding' => 'latin', 'collation' => 'latin1_swedish_ci') + ActiveRecord::Tasks::DatabaseTasks.purge @configuration.merge( + "encoding" => "latin", "collation" => "latin1_swedish_ci") + end end - end - class MysqlDBCharsetTest < ActiveRecord::TestCase - def setup - @connection = stub(:create_database => true) - @configuration = { - 'adapter' => 'mysql2', - 'database' => 'my-app-db' - } + class MysqlDBCharsetTest < ActiveRecord::TestCase + def setup + @connection = stub(create_database: true) + @configuration = { + "adapter" => "mysql2", + "database" => "my-app-db" + } - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - end + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end - def test_db_retrieves_charset - @connection.expects(:charset) - ActiveRecord::Tasks::DatabaseTasks.charset @configuration + def test_db_retrieves_charset + @connection.expects(:charset) + ActiveRecord::Tasks::DatabaseTasks.charset @configuration + end end - end - class MysqlDBCollationTest < ActiveRecord::TestCase - def setup - @connection = stub(:create_database => true) - @configuration = { - 'adapter' => 'mysql2', - 'database' => 'my-app-db' - } + class MysqlDBCollationTest < ActiveRecord::TestCase + def setup + @connection = stub(create_database: true) + @configuration = { + "adapter" => "mysql2", + "database" => "my-app-db" + } - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - end + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end - def test_db_retrieves_collation - @connection.expects(:collation) - ActiveRecord::Tasks::DatabaseTasks.collation @configuration + def test_db_retrieves_collation + @connection.expects(:collation) + ActiveRecord::Tasks::DatabaseTasks.collation @configuration + end end - end - class MySQLStructureDumpTest < ActiveRecord::TestCase - def setup - @configuration = { - 'adapter' => 'mysql2', - 'database' => 'test-db' - } - end + class MySQLStructureDumpTest < ActiveRecord::TestCase + def setup + @configuration = { + "adapter" => "mysql2", + "database" => "test-db" + } + end - def test_structure_dump - filename = "awesome-file.sql" - Kernel.expects(:system).with("mysqldump", "--result-file", filename, "--no-data", "--routines", "test-db").returns(true) + def test_structure_dump + filename = "awesome-file.sql" + Kernel.expects(:system).with("mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db").returns(true) - ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) - end + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + end - def test_warn_when_external_structure_dump_command_execution_fails - filename = "awesome-file.sql" - Kernel.expects(:system) - .with("mysqldump", "--result-file", filename, "--no-data", "--routines", "test-db") - .returns(false) + def test_warn_when_external_structure_dump_command_execution_fails + filename = "awesome-file.sql" + Kernel.expects(:system) + .with("mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db") + .returns(false) - e = assert_raise(RuntimeError) { - ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) - } - assert_match(/^failed to execute: `mysqldump`$/, e.message) - end + e = assert_raise(RuntimeError) { + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + } + assert_match(/^failed to execute: `mysqldump`$/, e.message) + end - def test_structure_dump_with_port_number - filename = "awesome-file.sql" - Kernel.expects(:system).with("mysqldump", "--port=10000", "--result-file", filename, "--no-data", "--routines", "test-db").returns(true) + def test_structure_dump_with_port_number + filename = "awesome-file.sql" + Kernel.expects(:system).with("mysqldump", "--port=10000", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db").returns(true) - ActiveRecord::Tasks::DatabaseTasks.structure_dump( - @configuration.merge('port' => 10000), - filename) - end + ActiveRecord::Tasks::DatabaseTasks.structure_dump( + @configuration.merge("port" => 10000), + filename) + end - def test_structure_dump_with_ssl - filename = "awesome-file.sql" - Kernel.expects(:system).with("mysqldump", "--ssl-ca=ca.crt", "--result-file", filename, "--no-data", "--routines", "test-db").returns(true) + def test_structure_dump_with_ssl + filename = "awesome-file.sql" + Kernel.expects(:system).with("mysqldump", "--ssl-ca=ca.crt", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db").returns(true) - ActiveRecord::Tasks::DatabaseTasks.structure_dump( - @configuration.merge("sslca" => "ca.crt"), - filename) + ActiveRecord::Tasks::DatabaseTasks.structure_dump( + @configuration.merge("sslca" => "ca.crt"), + filename) + end end - end - class MySQLStructureLoadTest < ActiveRecord::TestCase - def setup - @configuration = { - 'adapter' => 'mysql2', - 'database' => 'test-db' - } - end + class MySQLStructureLoadTest < ActiveRecord::TestCase + def setup + @configuration = { + "adapter" => "mysql2", + "database" => "test-db" + } + end - def test_structure_load - filename = "awesome-file.sql" - Kernel.expects(:system).with('mysql', '--execute', %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}, "--database", "test-db") - .returns(true) + def test_structure_load + filename = "awesome-file.sql" + Kernel.expects(:system).with("mysql", "--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}, "--database", "test-db") + .returns(true) - ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + end end end end -end diff --git a/activerecord/test/cases/tasks/postgresql_rake_test.rb b/activerecord/test/cases/tasks/postgresql_rake_test.rb index 6a0c7fbcb5..b8c8ec88f0 100644 --- a/activerecord/test/cases/tasks/postgresql_rake_test.rb +++ b/activerecord/test/cases/tasks/postgresql_rake_test.rb @@ -1,304 +1,304 @@ -require 'cases/helper' -require 'active_record/tasks/database_tasks' +require "cases/helper" +require "active_record/tasks/database_tasks" if current_adapter?(:PostgreSQLAdapter) -module ActiveRecord - class PostgreSQLDBCreateTest < ActiveRecord::TestCase - def setup - @connection = stub(:create_database => true) - @configuration = { - 'adapter' => 'postgresql', - 'database' => 'my-app-db' - } - - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - - $stdout, @original_stdout = StringIO.new, $stdout - $stderr, @original_stderr = StringIO.new, $stderr - end + module ActiveRecord + class PostgreSQLDBCreateTest < ActiveRecord::TestCase + def setup + @connection = stub(create_database: true) + @configuration = { + "adapter" => "postgresql", + "database" => "my-app-db" + } + + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + + $stdout, @original_stdout = StringIO.new, $stdout + $stderr, @original_stderr = StringIO.new, $stderr + end - def teardown - $stdout, $stderr = @original_stdout, @original_stderr - end + def teardown + $stdout, $stderr = @original_stdout, @original_stderr + end - def test_establishes_connection_to_postgresql_database - ActiveRecord::Base.expects(:establish_connection).with( - 'adapter' => 'postgresql', - 'database' => 'postgres', - 'schema_search_path' => 'public' - ) + def test_establishes_connection_to_postgresql_database + ActiveRecord::Base.expects(:establish_connection).with( + "adapter" => "postgresql", + "database" => "postgres", + "schema_search_path" => "public" + ) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_creates_database_with_default_encoding - @connection.expects(:create_database). - with('my-app-db', @configuration.merge('encoding' => 'utf8')) + def test_creates_database_with_default_encoding + @connection.expects(:create_database). + with("my-app-db", @configuration.merge("encoding" => "utf8")) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_creates_database_with_given_encoding - @connection.expects(:create_database). - with('my-app-db', @configuration.merge('encoding' => 'latin')) + def test_creates_database_with_given_encoding + @connection.expects(:create_database). + with("my-app-db", @configuration.merge("encoding" => "latin")) - ActiveRecord::Tasks::DatabaseTasks.create @configuration. - merge('encoding' => 'latin') - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration. + merge("encoding" => "latin") + end - def test_creates_database_with_given_collation_and_ctype - @connection.expects(:create_database). - with('my-app-db', @configuration.merge('encoding' => 'utf8', 'collation' => 'ja_JP.UTF8', 'ctype' => 'ja_JP.UTF8')) + def test_creates_database_with_given_collation_and_ctype + @connection.expects(:create_database). + with("my-app-db", @configuration.merge("encoding" => "utf8", "collation" => "ja_JP.UTF8", "ctype" => "ja_JP.UTF8")) - ActiveRecord::Tasks::DatabaseTasks.create @configuration. - merge('collation' => 'ja_JP.UTF8', 'ctype' => 'ja_JP.UTF8') - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration. + merge("collation" => "ja_JP.UTF8", "ctype" => "ja_JP.UTF8") + end - def test_establishes_connection_to_new_database - ActiveRecord::Base.expects(:establish_connection).with(@configuration) + def test_establishes_connection_to_new_database + ActiveRecord::Base.expects(:establish_connection).with(@configuration) - ActiveRecord::Tasks::DatabaseTasks.create @configuration - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration + end - def test_db_create_with_error_prints_message - ActiveRecord::Base.stubs(:establish_connection).raises(Exception) + def test_db_create_with_error_prints_message + ActiveRecord::Base.stubs(:establish_connection).raises(Exception) - $stderr.stubs(:puts).returns(true) - $stderr.expects(:puts). - with("Couldn't create database for #{@configuration.inspect}") + $stderr.stubs(:puts).returns(true) + $stderr.expects(:puts). + with("Couldn't create database for #{@configuration.inspect}") - assert_raises(Exception) { ActiveRecord::Tasks::DatabaseTasks.create @configuration } - end + assert_raises(Exception) { ActiveRecord::Tasks::DatabaseTasks.create @configuration } + end - def test_when_database_created_successfully_outputs_info_to_stdout - ActiveRecord::Tasks::DatabaseTasks.create @configuration + def test_when_database_created_successfully_outputs_info_to_stdout + ActiveRecord::Tasks::DatabaseTasks.create @configuration - assert_equal $stdout.string, "Created database 'my-app-db'\n" - end + assert_equal $stdout.string, "Created database 'my-app-db'\n" + end - def test_create_when_database_exists_outputs_info_to_stderr - ActiveRecord::Base.connection.stubs(:create_database).raises( - ActiveRecord::Tasks::DatabaseAlreadyExists - ) + def test_create_when_database_exists_outputs_info_to_stderr + ActiveRecord::Base.connection.stubs(:create_database).raises( + ActiveRecord::Tasks::DatabaseAlreadyExists + ) - ActiveRecord::Tasks::DatabaseTasks.create @configuration + ActiveRecord::Tasks::DatabaseTasks.create @configuration - assert_equal $stderr.string, "Database 'my-app-db' already exists\n" + assert_equal $stderr.string, "Database 'my-app-db' already exists\n" + end end - end - class PostgreSQLDBDropTest < ActiveRecord::TestCase - def setup - @connection = stub(:drop_database => true) - @configuration = { - 'adapter' => 'postgresql', - 'database' => 'my-app-db' - } + class PostgreSQLDBDropTest < ActiveRecord::TestCase + def setup + @connection = stub(drop_database: true) + @configuration = { + "adapter" => "postgresql", + "database" => "my-app-db" + } - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) - $stdout, @original_stdout = StringIO.new, $stdout - $stderr, @original_stderr = StringIO.new, $stderr - end + $stdout, @original_stdout = StringIO.new, $stdout + $stderr, @original_stderr = StringIO.new, $stderr + end - def teardown - $stdout, $stderr = @original_stdout, @original_stderr - end + def teardown + $stdout, $stderr = @original_stdout, @original_stderr + end - def test_establishes_connection_to_postgresql_database - ActiveRecord::Base.expects(:establish_connection).with( - 'adapter' => 'postgresql', - 'database' => 'postgres', - 'schema_search_path' => 'public' - ) + def test_establishes_connection_to_postgresql_database + ActiveRecord::Base.expects(:establish_connection).with( + "adapter" => "postgresql", + "database" => "postgres", + "schema_search_path" => "public" + ) - ActiveRecord::Tasks::DatabaseTasks.drop @configuration - end + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end - def test_drops_database - @connection.expects(:drop_database).with('my-app-db') + def test_drops_database + @connection.expects(:drop_database).with("my-app-db") - ActiveRecord::Tasks::DatabaseTasks.drop @configuration - end + ActiveRecord::Tasks::DatabaseTasks.drop @configuration + end - def test_when_database_dropped_successfully_outputs_info_to_stdout - ActiveRecord::Tasks::DatabaseTasks.drop @configuration + def test_when_database_dropped_successfully_outputs_info_to_stdout + ActiveRecord::Tasks::DatabaseTasks.drop @configuration - assert_equal $stdout.string, "Dropped database 'my-app-db'\n" + assert_equal $stdout.string, "Dropped database 'my-app-db'\n" + end end - end - class PostgreSQLPurgeTest < ActiveRecord::TestCase - def setup - @connection = stub(:create_database => true, :drop_database => true) - @configuration = { - 'adapter' => 'postgresql', - 'database' => 'my-app-db' - } - - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:clear_active_connections!).returns(true) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - end + class PostgreSQLPurgeTest < ActiveRecord::TestCase + def setup + @connection = stub(create_database: true, drop_database: true) + @configuration = { + "adapter" => "postgresql", + "database" => "my-app-db" + } - def test_clears_active_connections - ActiveRecord::Base.expects(:clear_active_connections!) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:clear_active_connections!).returns(true) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end - ActiveRecord::Tasks::DatabaseTasks.purge @configuration - end + def test_clears_active_connections + ActiveRecord::Base.expects(:clear_active_connections!) + + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end - def test_establishes_connection_to_postgresql_database - ActiveRecord::Base.expects(:establish_connection).with( - 'adapter' => 'postgresql', - 'database' => 'postgres', - 'schema_search_path' => 'public' - ) + def test_establishes_connection_to_postgresql_database + ActiveRecord::Base.expects(:establish_connection).with( + "adapter" => "postgresql", + "database" => "postgres", + "schema_search_path" => "public" + ) - ActiveRecord::Tasks::DatabaseTasks.purge @configuration - end + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end - def test_drops_database - @connection.expects(:drop_database).with('my-app-db') + def test_drops_database + @connection.expects(:drop_database).with("my-app-db") - ActiveRecord::Tasks::DatabaseTasks.purge @configuration - end + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end - def test_creates_database - @connection.expects(:create_database). - with('my-app-db', @configuration.merge('encoding' => 'utf8')) + def test_creates_database + @connection.expects(:create_database). + with("my-app-db", @configuration.merge("encoding" => "utf8")) - ActiveRecord::Tasks::DatabaseTasks.purge @configuration - end + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end - def test_establishes_connection - ActiveRecord::Base.expects(:establish_connection).with(@configuration) + def test_establishes_connection + ActiveRecord::Base.expects(:establish_connection).with(@configuration) - ActiveRecord::Tasks::DatabaseTasks.purge @configuration + ActiveRecord::Tasks::DatabaseTasks.purge @configuration + end end - end - class PostgreSQLDBCharsetTest < ActiveRecord::TestCase - def setup - @connection = stub(:create_database => true) - @configuration = { - 'adapter' => 'postgresql', - 'database' => 'my-app-db' - } + class PostgreSQLDBCharsetTest < ActiveRecord::TestCase + def setup + @connection = stub(create_database: true) + @configuration = { + "adapter" => "postgresql", + "database" => "my-app-db" + } - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - end + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end - def test_db_retrieves_charset - @connection.expects(:encoding) - ActiveRecord::Tasks::DatabaseTasks.charset @configuration + def test_db_retrieves_charset + @connection.expects(:encoding) + ActiveRecord::Tasks::DatabaseTasks.charset @configuration + end end - end - class PostgreSQLDBCollationTest < ActiveRecord::TestCase - def setup - @connection = stub(:create_database => true) - @configuration = { - 'adapter' => 'postgresql', - 'database' => 'my-app-db' - } + class PostgreSQLDBCollationTest < ActiveRecord::TestCase + def setup + @connection = stub(create_database: true) + @configuration = { + "adapter" => "postgresql", + "database" => "my-app-db" + } - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - end + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end - def test_db_retrieves_collation - @connection.expects(:collation) - ActiveRecord::Tasks::DatabaseTasks.collation @configuration + def test_db_retrieves_collation + @connection.expects(:collation) + ActiveRecord::Tasks::DatabaseTasks.collation @configuration + end end - end - class PostgreSQLStructureDumpTest < ActiveRecord::TestCase - def setup - @connection = stub(:structure_dump => true) - @configuration = { - 'adapter' => 'postgresql', - 'database' => 'my-app-db' - } - @filename = "awesome-file.sql" - - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - Kernel.stubs(:system) - File.stubs(:open) - end + class PostgreSQLStructureDumpTest < ActiveRecord::TestCase + def setup + @connection = stub(structure_dump: true) + @configuration = { + "adapter" => "postgresql", + "database" => "my-app-db" + } + @filename = "awesome-file.sql" - def test_structure_dump - Kernel.expects(:system).with('pg_dump', '-s', '-x', '-O', '-f', @filename, 'my-app-db').returns(true) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + Kernel.stubs(:system) + File.stubs(:open) + end - ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) - end + def test_structure_dump + Kernel.expects(:system).with("pg_dump", "-s", "-x", "-O", "-f", @filename, "my-app-db").returns(true) - def test_structure_dump_with_schema_search_path - @configuration['schema_search_path'] = 'foo,bar' + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + end - Kernel.expects(:system).with('pg_dump', '-s', '-x', '-O', '-f', @filename, '--schema=foo', '--schema=bar', 'my-app-db').returns(true) + def test_structure_dump_with_schema_search_path + @configuration["schema_search_path"] = "foo,bar" - ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) - end + Kernel.expects(:system).with("pg_dump", "-s", "-x", "-O", "-f", @filename, "--schema=foo", "--schema=bar", "my-app-db").returns(true) - def test_structure_dump_with_schema_search_path_and_dump_schemas_all - @configuration['schema_search_path'] = 'foo,bar' + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + end - Kernel.expects(:system).with("pg_dump", '-s', '-x', '-O', '-f', @filename, 'my-app-db').returns(true) + def test_structure_dump_with_schema_search_path_and_dump_schemas_all + @configuration["schema_search_path"] = "foo,bar" - with_dump_schemas(:all) do - ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + Kernel.expects(:system).with("pg_dump", "-s", "-x", "-O", "-f", @filename, "my-app-db").returns(true) + + with_dump_schemas(:all) do + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + end end - end - def test_structure_dump_with_dump_schemas_string - Kernel.expects(:system).with("pg_dump", '-s', '-x', '-O', '-f', @filename, '--schema=foo', '--schema=bar', "my-app-db").returns(true) + def test_structure_dump_with_dump_schemas_string + Kernel.expects(:system).with("pg_dump", "-s", "-x", "-O", "-f", @filename, "--schema=foo", "--schema=bar", "my-app-db").returns(true) - with_dump_schemas('foo,bar') do - ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + with_dump_schemas("foo,bar") do + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + end end - end - private + private - def with_dump_schemas(value, &block) - old_dump_schemas = ActiveRecord::Base.dump_schemas - ActiveRecord::Base.dump_schemas = value - yield - ensure - ActiveRecord::Base.dump_schemas = old_dump_schemas + def with_dump_schemas(value, &block) + old_dump_schemas = ActiveRecord::Base.dump_schemas + ActiveRecord::Base.dump_schemas = value + yield + ensure + ActiveRecord::Base.dump_schemas = old_dump_schemas + end end - end - class PostgreSQLStructureLoadTest < ActiveRecord::TestCase - def setup - @connection = stub - @configuration = { - 'adapter' => 'postgresql', - 'database' => 'my-app-db' - } - - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - Kernel.stubs(:system) - end + class PostgreSQLStructureLoadTest < ActiveRecord::TestCase + def setup + @connection = stub + @configuration = { + "adapter" => "postgresql", + "database" => "my-app-db" + } - def test_structure_load - filename = "awesome-file.sql" - Kernel.expects(:system).with('psql', '-q', '-f', filename, @configuration['database']).returns(true) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + Kernel.stubs(:system) + end - ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) - end + def test_structure_load + filename = "awesome-file.sql" + Kernel.expects(:system).with("psql", "-v", "ON_ERROR_STOP=1", "-q", "-f", filename, @configuration["database"]).returns(true) - def test_structure_load_accepts_path_with_spaces - filename = "awesome file.sql" - Kernel.expects(:system).with('psql', '-q', '-f', filename, @configuration['database']).returns(true) + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + end + + def test_structure_load_accepts_path_with_spaces + filename = "awesome file.sql" + Kernel.expects(:system).with("psql", "-v", "ON_ERROR_STOP=1", "-q", "-f", filename, @configuration["database"]).returns(true) - ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + end end end end -end diff --git a/activerecord/test/cases/tasks/sqlite_rake_test.rb b/activerecord/test/cases/tasks/sqlite_rake_test.rb index 4be03c7f61..141048bfe7 100644 --- a/activerecord/test/cases/tasks/sqlite_rake_test.rb +++ b/activerecord/test/cases/tasks/sqlite_rake_test.rb @@ -1,220 +1,220 @@ -require 'cases/helper' -require 'active_record/tasks/database_tasks' -require 'pathname' +require "cases/helper" +require "active_record/tasks/database_tasks" +require "pathname" if current_adapter?(:SQLite3Adapter) -module ActiveRecord - class SqliteDBCreateTest < ActiveRecord::TestCase - def setup - @database = 'db_create.sqlite3' - @connection = stub :connection - @configuration = { - 'adapter' => 'sqlite3', - 'database' => @database - } - - File.stubs(:exist?).returns(false) - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - - $stdout, @original_stdout = StringIO.new, $stdout - $stderr, @original_stderr = StringIO.new, $stderr - end + module ActiveRecord + class SqliteDBCreateTest < ActiveRecord::TestCase + def setup + @database = "db_create.sqlite3" + @connection = stub :connection + @configuration = { + "adapter" => "sqlite3", + "database" => @database + } + + File.stubs(:exist?).returns(false) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + + $stdout, @original_stdout = StringIO.new, $stdout + $stderr, @original_stderr = StringIO.new, $stderr + end - def teardown - $stdout, $stderr = @original_stdout, @original_stderr - end + def teardown + $stdout, $stderr = @original_stdout, @original_stderr + end - def test_db_checks_database_exists - File.expects(:exist?).with(@database).returns(false) + def test_db_checks_database_exists + File.expects(:exist?).with(@database).returns(false) - ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root' - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration, "/rails/root" + end - def test_when_db_created_successfully_outputs_info_to_stdout - ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root' + def test_when_db_created_successfully_outputs_info_to_stdout + ActiveRecord::Tasks::DatabaseTasks.create @configuration, "/rails/root" - assert_equal $stdout.string, "Created database '#{@database}'\n" - end + assert_equal $stdout.string, "Created database '#{@database}'\n" + end - def test_db_create_when_file_exists - File.stubs(:exist?).returns(true) + def test_db_create_when_file_exists + File.stubs(:exist?).returns(true) - ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root' + ActiveRecord::Tasks::DatabaseTasks.create @configuration, "/rails/root" - assert_equal $stderr.string, "Database '#{@database}' already exists\n" - end + assert_equal $stderr.string, "Database '#{@database}' already exists\n" + end - def test_db_create_with_file_does_nothing - File.stubs(:exist?).returns(true) - $stderr.stubs(:puts).returns(nil) + def test_db_create_with_file_does_nothing + File.stubs(:exist?).returns(true) + $stderr.stubs(:puts).returns(nil) - ActiveRecord::Base.expects(:establish_connection).never + ActiveRecord::Base.expects(:establish_connection).never - ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root' - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration, "/rails/root" + end - def test_db_create_establishes_a_connection - ActiveRecord::Base.expects(:establish_connection).with(@configuration) + def test_db_create_establishes_a_connection + ActiveRecord::Base.expects(:establish_connection).with(@configuration) - ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root' - end + ActiveRecord::Tasks::DatabaseTasks.create @configuration, "/rails/root" + end - def test_db_create_with_error_prints_message - ActiveRecord::Base.stubs(:establish_connection).raises(Exception) + def test_db_create_with_error_prints_message + ActiveRecord::Base.stubs(:establish_connection).raises(Exception) - $stderr.stubs(:puts).returns(true) - $stderr.expects(:puts). - with("Couldn't create database for #{@configuration.inspect}") + $stderr.stubs(:puts).returns(true) + $stderr.expects(:puts). + with("Couldn't create database for #{@configuration.inspect}") - assert_raises(Exception) { ActiveRecord::Tasks::DatabaseTasks.create @configuration, '/rails/root' } + assert_raises(Exception) { ActiveRecord::Tasks::DatabaseTasks.create @configuration, "/rails/root" } + end end - end - class SqliteDBDropTest < ActiveRecord::TestCase - def setup - @database = "db_create.sqlite3" - @path = stub(:to_s => '/absolute/path', :absolute? => true) - @configuration = { - 'adapter' => 'sqlite3', - 'database' => @database - } - - Pathname.stubs(:new).returns(@path) - File.stubs(:join).returns('/former/relative/path') - FileUtils.stubs(:rm).returns(true) - - $stdout, @original_stdout = StringIO.new, $stdout - $stderr, @original_stderr = StringIO.new, $stderr - end + class SqliteDBDropTest < ActiveRecord::TestCase + def setup + @database = "db_create.sqlite3" + @path = stub(to_s: "/absolute/path", absolute?: true) + @configuration = { + "adapter" => "sqlite3", + "database" => @database + } - def teardown - $stdout, $stderr = @original_stdout, @original_stderr - end + Pathname.stubs(:new).returns(@path) + File.stubs(:join).returns("/former/relative/path") + FileUtils.stubs(:rm).returns(true) - def test_creates_path_from_database - Pathname.expects(:new).with(@database).returns(@path) + $stdout, @original_stdout = StringIO.new, $stdout + $stderr, @original_stderr = StringIO.new, $stderr + end - ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root' - end + def teardown + $stdout, $stderr = @original_stdout, @original_stderr + end - def test_removes_file_with_absolute_path - File.stubs(:exist?).returns(true) - @path.stubs(:absolute?).returns(true) + def test_creates_path_from_database + Pathname.expects(:new).with(@database).returns(@path) - FileUtils.expects(:rm).with('/absolute/path') + ActiveRecord::Tasks::DatabaseTasks.drop @configuration, "/rails/root" + end - ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root' - end + def test_removes_file_with_absolute_path + File.stubs(:exist?).returns(true) + @path.stubs(:absolute?).returns(true) - def test_generates_absolute_path_with_given_root - @path.stubs(:absolute?).returns(false) + FileUtils.expects(:rm).with("/absolute/path") - File.expects(:join).with('/rails/root', @path). - returns('/former/relative/path') + ActiveRecord::Tasks::DatabaseTasks.drop @configuration, "/rails/root" + end - ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root' - end + def test_generates_absolute_path_with_given_root + @path.stubs(:absolute?).returns(false) - def test_removes_file_with_relative_path - File.stubs(:exist?).returns(true) - @path.stubs(:absolute?).returns(false) + File.expects(:join).with("/rails/root", @path). + returns("/former/relative/path") - FileUtils.expects(:rm).with('/former/relative/path') + ActiveRecord::Tasks::DatabaseTasks.drop @configuration, "/rails/root" + end - ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root' - end + def test_removes_file_with_relative_path + File.stubs(:exist?).returns(true) + @path.stubs(:absolute?).returns(false) - def test_when_db_dropped_successfully_outputs_info_to_stdout - ActiveRecord::Tasks::DatabaseTasks.drop @configuration, '/rails/root' + FileUtils.expects(:rm).with("/former/relative/path") - assert_equal $stdout.string, "Dropped database '#{@database}'\n" - end - end + ActiveRecord::Tasks::DatabaseTasks.drop @configuration, "/rails/root" + end - class SqliteDBCharsetTest < ActiveRecord::TestCase - def setup - @database = 'db_create.sqlite3' - @connection = stub :connection - @configuration = { - 'adapter' => 'sqlite3', - 'database' => @database - } - - File.stubs(:exist?).returns(false) - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - end + def test_when_db_dropped_successfully_outputs_info_to_stdout + ActiveRecord::Tasks::DatabaseTasks.drop @configuration, "/rails/root" - def test_db_retrieves_charset - @connection.expects(:encoding) - ActiveRecord::Tasks::DatabaseTasks.charset @configuration, '/rails/root' + assert_equal $stdout.string, "Dropped database '#{@database}'\n" + end end - end - class SqliteDBCollationTest < ActiveRecord::TestCase - def setup - @database = 'db_create.sqlite3' - @connection = stub :connection - @configuration = { - 'adapter' => 'sqlite3', - 'database' => @database - } - - File.stubs(:exist?).returns(false) - ActiveRecord::Base.stubs(:connection).returns(@connection) - ActiveRecord::Base.stubs(:establish_connection).returns(true) - end + class SqliteDBCharsetTest < ActiveRecord::TestCase + def setup + @database = "db_create.sqlite3" + @connection = stub :connection + @configuration = { + "adapter" => "sqlite3", + "database" => @database + } - def test_db_retrieves_collation - assert_raise NoMethodError do - ActiveRecord::Tasks::DatabaseTasks.collation @configuration, '/rails/root' + File.stubs(:exist?).returns(false) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) end - end - end - class SqliteStructureDumpTest < ActiveRecord::TestCase - def setup - @database = "db_create.sqlite3" - @configuration = { - 'adapter' => 'sqlite3', - 'database' => @database - } + def test_db_retrieves_charset + @connection.expects(:encoding) + ActiveRecord::Tasks::DatabaseTasks.charset @configuration, "/rails/root" + end end - def test_structure_dump - dbfile = @database - filename = "awesome-file.sql" + class SqliteDBCollationTest < ActiveRecord::TestCase + def setup + @database = "db_create.sqlite3" + @connection = stub :connection + @configuration = { + "adapter" => "sqlite3", + "database" => @database + } - ActiveRecord::Tasks::DatabaseTasks.structure_dump @configuration, filename, '/rails/root' - assert File.exist?(dbfile) - assert File.exist?(filename) - ensure - FileUtils.rm_f(filename) - FileUtils.rm_f(dbfile) + File.stubs(:exist?).returns(false) + ActiveRecord::Base.stubs(:connection).returns(@connection) + ActiveRecord::Base.stubs(:establish_connection).returns(true) + end + + def test_db_retrieves_collation + assert_raise NoMethodError do + ActiveRecord::Tasks::DatabaseTasks.collation @configuration, "/rails/root" + end + end end - end - class SqliteStructureLoadTest < ActiveRecord::TestCase - def setup - @database = "db_create.sqlite3" - @configuration = { - 'adapter' => 'sqlite3', - 'database' => @database - } + class SqliteStructureDumpTest < ActiveRecord::TestCase + def setup + @database = "db_create.sqlite3" + @configuration = { + "adapter" => "sqlite3", + "database" => @database + } + end + + def test_structure_dump + dbfile = @database + filename = "awesome-file.sql" + + ActiveRecord::Tasks::DatabaseTasks.structure_dump @configuration, filename, "/rails/root" + assert File.exist?(dbfile) + assert File.exist?(filename) + ensure + FileUtils.rm_f(filename) + FileUtils.rm_f(dbfile) + end end - def test_structure_load - dbfile = @database - filename = "awesome-file.sql" + class SqliteStructureLoadTest < ActiveRecord::TestCase + def setup + @database = "db_create.sqlite3" + @configuration = { + "adapter" => "sqlite3", + "database" => @database + } + end + + def test_structure_load + dbfile = @database + filename = "awesome-file.sql" - open(filename, 'w') { |f| f.puts("select datetime('now', 'localtime');") } - ActiveRecord::Tasks::DatabaseTasks.structure_load @configuration, filename, '/rails/root' - assert File.exist?(dbfile) - ensure - FileUtils.rm_f(filename) - FileUtils.rm_f(dbfile) + open(filename, "w") { |f| f.puts("select datetime('now', 'localtime');") } + ActiveRecord::Tasks::DatabaseTasks.structure_load @configuration, filename, "/rails/root" + assert File.exist?(dbfile) + ensure + FileUtils.rm_f(filename) + FileUtils.rm_f(dbfile) + end end end end -end diff --git a/activerecord/test/cases/test_case.rb b/activerecord/test/cases/test_case.rb index 87299c0dab..8eddc5a9ed 100644 --- a/activerecord/test/cases/test_case.rb +++ b/activerecord/test/cases/test_case.rb @@ -1,19 +1,32 @@ -require 'active_support/test_case' -require 'active_support/testing/stream' +require "active_support/test_case" +require "active_support/testing/autorun" +require "active_support/testing/method_call_assertions" +require "active_support/testing/stream" +require "active_support/core_ext/regexp" +require "active_record/fixtures" + +require "cases/validations_repair_helper" module ActiveRecord # = Active Record Test Case # # Defines some test assertions to test against SQL queries. class TestCase < ActiveSupport::TestCase #:nodoc: + include ActiveSupport::Testing::MethodCallAssertions include ActiveSupport::Testing::Stream + include ActiveRecord::TestFixtures + include ActiveRecord::ValidationsRepairHelper - def teardown - SQLCounter.clear_log + self.fixture_path = FIXTURES_ROOT + self.use_instantiated_fixtures = false + self.use_transactional_tests = true + + def create_fixtures(*fixture_set_names, &block) + ActiveRecord::FixtureSet.create_fixtures(ActiveRecord::TestCase.fixture_path, fixture_set_names, fixture_class_names, &block) end - def assert_date_from_db(expected, actual, message = nil) - assert_equal expected.to_s, actual.to_s, message + def teardown + SQLCounter.clear_log end def capture_sql @@ -27,7 +40,7 @@ module ActiveRecord ensure failed_patterns = [] patterns_to_match.each do |pattern| - failed_patterns << pattern unless SQLCounter.log_all.any?{ |sql| pattern === sql } + failed_patterns << pattern unless SQLCounter.log_all.any? { |sql| pattern === sql } end assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map(&:inspect).join(', ')} not found.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}" end @@ -89,7 +102,7 @@ module ActiveRecord def clear_log; self.log = []; self.log_all = []; end end - self.clear_log + clear_log self.ignored_sql = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/] @@ -112,16 +125,13 @@ module ActiveRecord end def call(name, start, finish, message_id, values) - sql = values[:sql] - - # FIXME: this seems bad. we should probably have a better way to indicate - # the query was cached - return if 'CACHE' == values[:name] + return if values[:cached] + sql = values[:sql] self.class.log_all << sql - self.class.log << sql unless ignore =~ sql + self.class.log << sql unless ignore.match?(sql) end end - ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new) + ActiveSupport::Notifications.subscribe("sql.active_record", SQLCounter.new) end diff --git a/activerecord/test/cases/test_fixtures_test.rb b/activerecord/test/cases/test_fixtures_test.rb index 1970fe82d0..14a5faa85e 100644 --- a/activerecord/test/cases/test_fixtures_test.rb +++ b/activerecord/test/cases/test_fixtures_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" class TestFixturesTest < ActiveRecord::TestCase setup do @@ -7,7 +7,7 @@ class TestFixturesTest < ActiveRecord::TestCase end def test_deprecated_use_transactional_fixtures= - assert_deprecated 'use use_transactional_tests= instead' do + assert_deprecated "use use_transactional_tests= instead" do @klass.use_transactional_fixtures = true end end diff --git a/activerecord/test/cases/time_precision_test.rb b/activerecord/test/cases/time_precision_test.rb index 628a8eb771..03f6c234e8 100644 --- a/activerecord/test/cases/time_precision_test.rb +++ b/activerecord/test/cases/time_precision_test.rb @@ -1,84 +1,83 @@ -require 'cases/helper' -require 'support/schema_dumping_helper' +require "cases/helper" +require "support/schema_dumping_helper" if subsecond_precision_supported? -class TimePrecisionTest < ActiveRecord::TestCase - include SchemaDumpingHelper - self.use_transactional_tests = false + class TimePrecisionTest < ActiveRecord::TestCase + include SchemaDumpingHelper + self.use_transactional_tests = false - class Foo < ActiveRecord::Base; end + class Foo < ActiveRecord::Base; end - setup do - @connection = ActiveRecord::Base.connection - Foo.reset_column_information - end - - teardown do - @connection.drop_table :foos, if_exists: true - end + setup do + @connection = ActiveRecord::Base.connection + Foo.reset_column_information + end - def test_time_data_type_with_precision - @connection.create_table(:foos, force: true) - @connection.add_column :foos, :start, :time, precision: 3 - @connection.add_column :foos, :finish, :time, precision: 6 - assert_equal 3, Foo.columns_hash['start'].precision - assert_equal 6, Foo.columns_hash['finish'].precision - end + teardown do + @connection.drop_table :foos, if_exists: true + end - def test_passing_precision_to_time_does_not_set_limit - @connection.create_table(:foos, force: true) do |t| - t.time :start, precision: 3 - t.time :finish, precision: 6 + def test_time_data_type_with_precision + @connection.create_table(:foos, force: true) + @connection.add_column :foos, :start, :time, precision: 3 + @connection.add_column :foos, :finish, :time, precision: 6 + assert_equal 3, Foo.columns_hash["start"].precision + assert_equal 6, Foo.columns_hash["finish"].precision end - assert_nil Foo.columns_hash['start'].limit - assert_nil Foo.columns_hash['finish'].limit - end - def test_invalid_time_precision_raises_error - assert_raises ActiveRecord::ActiveRecordError do + def test_passing_precision_to_time_does_not_set_limit @connection.create_table(:foos, force: true) do |t| - t.time :start, precision: 7 - t.time :finish, precision: 7 + t.time :start, precision: 3 + t.time :finish, precision: 6 end + assert_nil Foo.columns_hash["start"].limit + assert_nil Foo.columns_hash["finish"].limit end - end - def test_formatting_time_according_to_precision - @connection.create_table(:foos, force: true) do |t| - t.time :start, precision: 0 - t.time :finish, precision: 4 + def test_invalid_time_precision_raises_error + assert_raises ActiveRecord::ActiveRecordError do + @connection.create_table(:foos, force: true) do |t| + t.time :start, precision: 7 + t.time :finish, precision: 7 + end + end end - time = ::Time.utc(2000, 1, 1, 12, 30, 0, 999999) - Foo.create!(start: time, finish: time) - assert foo = Foo.find_by(start: time) - assert_equal 1, Foo.where(finish: time).count - assert_equal time.to_s, foo.start.to_s - assert_equal time.to_s, foo.finish.to_s - assert_equal 000000, foo.start.usec - assert_equal 999900, foo.finish.usec - end - def test_schema_dump_includes_time_precision - @connection.create_table(:foos, force: true) do |t| - t.time :start, precision: 4 - t.time :finish, precision: 6 + def test_formatting_time_according_to_precision + @connection.create_table(:foos, force: true) do |t| + t.time :start, precision: 0 + t.time :finish, precision: 4 + end + time = ::Time.utc(2000, 1, 1, 12, 30, 0, 999999) + Foo.create!(start: time, finish: time) + assert foo = Foo.find_by(start: time) + assert_equal 1, Foo.where(finish: time).count + assert_equal time.to_s, foo.start.to_s + assert_equal time.to_s, foo.finish.to_s + assert_equal 000000, foo.start.usec + assert_equal 999900, foo.finish.usec end - output = dump_table_schema("foos") - assert_match %r{t\.time\s+"start",\s+precision: 4$}, output - assert_match %r{t\.time\s+"finish",\s+precision: 6$}, output - end - if current_adapter?(:PostgreSQLAdapter) - def test_time_precision_with_zero_should_be_dumped + def test_schema_dump_includes_time_precision @connection.create_table(:foos, force: true) do |t| - t.time :start, precision: 0 - t.time :finish, precision: 0 + t.time :start, precision: 4 + t.time :finish, precision: 6 end output = dump_table_schema("foos") - assert_match %r{t\.time\s+"start",\s+precision: 0$}, output - assert_match %r{t\.time\s+"finish",\s+precision: 0$}, output + assert_match %r{t\.time\s+"start",\s+precision: 4$}, output + assert_match %r{t\.time\s+"finish",\s+precision: 6$}, output end - end -end + if current_adapter?(:PostgreSQLAdapter) + def test_time_precision_with_zero_should_be_dumped + @connection.create_table(:foos, force: true) do |t| + t.time :start, precision: 0 + t.time :finish, precision: 0 + end + output = dump_table_schema("foos") + assert_match %r{t\.time\s+"start",\s+precision: 0$}, output + assert_match %r{t\.time\s+"finish",\s+precision: 0$}, output + end + end + end end diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb index 937b84bccc..cd83518e84 100644 --- a/activerecord/test/cases/timestamp_test.rb +++ b/activerecord/test/cases/timestamp_test.rb @@ -1,12 +1,12 @@ -require 'cases/helper' -require 'support/ddl_helper' -require 'models/developer' -require 'models/computer' -require 'models/owner' -require 'models/pet' -require 'models/toy' -require 'models/car' -require 'models/task' +require "cases/helper" +require "support/ddl_helper" +require "models/developer" +require "models/computer" +require "models/owner" +require "models/pet" +require "models/toy" +require "models/car" +require "models/task" class TimestampTest < ActiveRecord::TestCase fixtures :developers, :owners, :pets, :toys, :cars, :tasks @@ -38,8 +38,8 @@ class TimestampTest < ActiveRecord::TestCase assert_not_equal @previously_updated_at, @developer.updated_at assert_equal previous_salary + 10000, @developer.salary - assert @developer.salary_changed?, 'developer salary should have changed' - assert @developer.changed?, 'developer should be marked as changed' + assert @developer.salary_changed?, "developer salary should have changed" + assert @developer.changed?, "developer should be marked as changed" @developer.reload assert_equal previous_salary, @developer.salary end @@ -74,12 +74,12 @@ class TimestampTest < ActiveRecord::TestCase end def test_touching_updates_timestamp_with_given_time - previously_updated_at = @developer.updated_at - new_time = Time.utc(2015, 2, 16, 0, 0, 0) - @developer.touch(time: new_time) + previously_updated_at = @developer.updated_at + new_time = Time.utc(2015, 2, 16, 0, 0, 0) + @developer.touch(time: new_time) - assert_not_equal previously_updated_at, @developer.updated_at - assert_equal new_time, @developer.updated_at + assert_not_equal previously_updated_at, @developer.updated_at + assert_equal new_time, @developer.updated_at end def test_touching_an_attribute_updates_timestamp @@ -88,8 +88,8 @@ class TimestampTest < ActiveRecord::TestCase @developer.touch(:created_at) end - assert !@developer.created_at_changed? , 'created_at should not be changed' - assert !@developer.changed?, 'record should not be changed' + assert !@developer.created_at_changed? , "created_at should not be changed" + assert !@developer.changed?, "record should not be changed" assert_not_equal previously_created_at, @developer.created_at assert_not_equal @previously_updated_at, @developer.updated_at end @@ -106,9 +106,9 @@ class TimestampTest < ActiveRecord::TestCase end def test_touching_an_attribute_updates_timestamp_with_given_time - previously_updated_at = @developer.updated_at + previously_updated_at = @developer.updated_at previously_created_at = @developer.created_at - new_time = Time.utc(2015, 2, 16, 4, 54, 0) + new_time = Time.utc(2015, 2, 16, 4, 54, 0) @developer.touch(:created_at, time: new_time) assert_not_equal previously_created_at, @developer.created_at @@ -228,7 +228,7 @@ class TimestampTest < ActiveRecord::TestCase def test_saving_a_new_record_belonging_to_invalid_parent_with_touch_should_not_raise_exception klass = Class.new(Owner) do - def self.name; 'Owner'; end + def self.name; "Owner"; end validate { errors.add(:base, :invalid) } end @@ -240,8 +240,8 @@ class TimestampTest < ActiveRecord::TestCase def test_saving_a_record_with_a_belongs_to_that_specifies_touching_a_specific_attribute_the_parent_should_update_that_attribute klass = Class.new(ActiveRecord::Base) do - def self.name; 'Pet'; end - belongs_to :owner, :touch => :happy_at + def self.name; "Pet"; end + belongs_to :owner, touch: :happy_at end pet = klass.first @@ -256,8 +256,8 @@ class TimestampTest < ActiveRecord::TestCase def test_touching_a_record_with_a_belongs_to_that_uses_a_counter_cache_should_update_the_parent klass = Class.new(ActiveRecord::Base) do - def self.name; 'Pet'; end - belongs_to :owner, :counter_cache => :use_count, :touch => true + def self.name; "Pet"; end + belongs_to :owner, counter_cache: :use_count, touch: true end pet = klass.first @@ -275,8 +275,8 @@ class TimestampTest < ActiveRecord::TestCase def test_touching_a_record_touches_parent_record_and_grandparent_record klass = Class.new(ActiveRecord::Base) do - def self.name; 'Toy'; end - belongs_to :pet, :touch => true + def self.name; "Toy"; end + belongs_to :pet, touch: true end toy = klass.first @@ -293,12 +293,12 @@ class TimestampTest < ActiveRecord::TestCase def test_touching_a_record_touches_polymorphic_record klass = Class.new(ActiveRecord::Base) do - def self.name; 'Toy'; end + def self.name; "Toy"; end end wheel_klass = Class.new(ActiveRecord::Base) do - def self.name; 'Wheel'; end - belongs_to :wheelable, :polymorphic => true, :touch => true + def self.name; "Wheel"; end + belongs_to :wheelable, polymorphic: true, touch: true end toy = klass.first @@ -315,7 +315,7 @@ class TimestampTest < ActiveRecord::TestCase def test_changing_parent_of_a_record_touches_both_new_and_old_parent_record klass = Class.new(ActiveRecord::Base) do - def self.name; 'Toy'; end + def self.name; "Toy"; end belongs_to :pet, touch: true end @@ -341,12 +341,12 @@ class TimestampTest < ActiveRecord::TestCase def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record_changes_within_same_class car_class = Class.new(ActiveRecord::Base) do - def self.name; 'Car'; end + def self.name; "Car"; end end wheel_class = Class.new(ActiveRecord::Base) do - def self.name; 'Wheel'; end - belongs_to :wheelable, :polymorphic => true, :touch => true + def self.name; "Wheel"; end + belongs_to :wheelable, polymorphic: true, touch: true end car1 = car_class.find(1) @@ -368,16 +368,16 @@ class TimestampTest < ActiveRecord::TestCase def test_changing_parent_of_a_record_touches_both_new_and_old_polymorphic_parent_record_changes_with_other_class car_class = Class.new(ActiveRecord::Base) do - def self.name; 'Car'; end + def self.name; "Car"; end end toy_class = Class.new(ActiveRecord::Base) do - def self.name; 'Toy'; end + def self.name; "Toy"; end end wheel_class = Class.new(ActiveRecord::Base) do - def self.name; 'Wheel'; end - belongs_to :wheelable, :polymorphic => true, :touch => true + def self.name; "Wheel"; end + belongs_to :wheelable, polymorphic: true, touch: true end car = car_class.find(1) @@ -399,7 +399,7 @@ class TimestampTest < ActiveRecord::TestCase def test_clearing_association_touches_the_old_record klass = Class.new(ActiveRecord::Base) do - def self.name; 'Toy'; end + def self.name; "Toy"; end belongs_to :pet, touch: true end @@ -419,14 +419,14 @@ class TimestampTest < ActiveRecord::TestCase def test_timestamp_column_values_are_present_in_the_callbacks klass = Class.new(ActiveRecord::Base) do - self.table_name = 'people' + self.table_name = "people" before_create do self.born_at = self.created_at end end - person = klass.create first_name: 'David' + person = klass.create first_name: "David" assert_not_equal person.born_at, nil end @@ -462,11 +462,11 @@ class TimestampTest < ActiveRecord::TestCase def test_index_is_created_for_both_timestamps ActiveRecord::Base.connection.create_table(:foos, force: true) do |t| - t.timestamps(:foos, null: true, index: true) + t.timestamps null: true, index: true end - indexes = ActiveRecord::Base.connection.indexes('foos') - assert_equal ['created_at', 'updated_at'], indexes.flat_map(&:columns).sort + indexes = ActiveRecord::Base.connection.indexes("foos") + assert_equal ["created_at", "updated_at"], indexes.flat_map(&:columns).sort ensure ActiveRecord::Base.connection.drop_table(:foos) end diff --git a/activerecord/test/cases/touch_later_test.rb b/activerecord/test/cases/touch_later_test.rb index b47769eed7..d1e8c649d9 100644 --- a/activerecord/test/cases/touch_later_test.rb +++ b/activerecord/test/cases/touch_later_test.rb @@ -1,9 +1,9 @@ -require 'cases/helper' -require 'models/invoice' -require 'models/line_item' -require 'models/topic' -require 'models/node' -require 'models/tree' +require "cases/helper" +require "models/invoice" +require "models/line_item" +require "models/topic" +require "models/node" +require "models/tree" class TouchLaterTest < ActiveRecord::TestCase fixtures :nodes, :trees @@ -24,6 +24,15 @@ class TouchLaterTest < ActiveRecord::TestCase assert_not invoice.changed? end + def test_touch_later_respects_no_touching_policy + time = Time.now.utc - 25.days + topic = Topic.create!(updated_at: time, created_at: time) + Topic.no_touching do + topic.touch_later + end + assert_equal time.to_i, topic.updated_at.to_i + end + def test_touch_later_update_the_attributes time = Time.now.utc - 25.days topic = Topic.create!(updated_at: time, created_at: time) diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb index 8a7f19293d..bd50fe55e9 100644 --- a/activerecord/test/cases/transaction_callbacks_test.rb +++ b/activerecord/test/cases/transaction_callbacks_test.rb @@ -1,7 +1,7 @@ require "cases/helper" -require 'models/owner' -require 'models/pet' -require 'models/topic' +require "models/owner" +require "models/pet" +require "models/topic" class TransactionCallbacksTest < ActiveRecord::TestCase fixtures :topics, :owners, :pets @@ -17,7 +17,7 @@ class TransactionCallbacksTest < ActiveRecord::TestCase attr_accessor :save_on_after_create after_create do - self.save! if save_on_after_create + save! if save_on_after_create end def history @@ -68,17 +68,17 @@ class TransactionCallbacksTest < ActiveRecord::TestCase def do_before_commit(on) blocks = @before_commit[on] if defined?(@before_commit) - blocks.each{|b| b.call(self)} if blocks + blocks.each { |b| b.call(self) } if blocks end def do_after_commit(on) blocks = @after_commit[on] if defined?(@after_commit) - blocks.each{|b| b.call(self)} if blocks + blocks.each { |b| b.call(self) } if blocks end def do_after_rollback(on) blocks = @after_rollback[on] if defined?(@after_rollback) - blocks.each{|b| b.call(self)} if blocks + blocks.each { |b| b.call(self) } if blocks end end @@ -88,7 +88,7 @@ class TransactionCallbacksTest < ActiveRecord::TestCase # FIXME: Test behavior, not implementation. def test_before_commit_exception_should_pop_transaction_stack - @first.before_commit_block { raise 'better pop this txn from the stack!' } + @first.before_commit_block { raise "better pop this txn from the stack!" } original_txn = @first.class.connection.current_transaction @@ -101,8 +101,8 @@ class TransactionCallbacksTest < ActiveRecord::TestCase end def test_call_after_commit_after_transaction_commits - @first.after_commit_block{|r| r.history << :after_commit} - @first.after_rollback_block{|r| r.history << :after_rollback} + @first.after_commit_block { |r| r.history << :after_commit } + @first.after_rollback_block { |r| r.history << :after_rollback } @first.save! assert_equal [:after_commit], @first.history @@ -123,7 +123,7 @@ class TransactionCallbacksTest < ActiveRecord::TestCase end def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record - new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today) + new_record = TopicWithCallbacks.new(title: "New topic", written_on: Date.today) add_transaction_execution_blocks new_record new_record.save! @@ -131,17 +131,17 @@ class TransactionCallbacksTest < ActiveRecord::TestCase end def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record_if_create_succeeds_creating_through_association - topic = TopicWithCallbacks.create!(:title => "New topic", :written_on => Date.today) + topic = TopicWithCallbacks.create!(title: "New topic", written_on: Date.today) reply = topic.replies.create assert_equal [], reply.history end def test_only_call_after_commit_on_create_and_doesnt_leaky - r = ReplyWithCallbacks.new(content: 'foo') + r = ReplyWithCallbacks.new(content: "foo") r.save_on_after_create = true r.save! - r.content = 'bar' + r.content = "bar" r.save! r.save! assert_equal [:commit_on_create], r.history @@ -155,7 +155,7 @@ class TransactionCallbacksTest < ActiveRecord::TestCase end def test_only_call_after_commit_on_top_level_transactions - @first.after_commit_block{|r| r.history << :after_commit} + @first.after_commit_block { |r| r.history << :after_commit } assert @first.history.empty? @first.transaction do @@ -168,8 +168,8 @@ class TransactionCallbacksTest < ActiveRecord::TestCase end def test_call_after_rollback_after_transaction_rollsback - @first.after_commit_block{|r| r.history << :after_commit} - @first.after_rollback_block{|r| r.history << :after_rollback} + @first.after_commit_block { |r| r.history << :after_commit } + @first.after_rollback_block { |r| r.history << :after_rollback } Topic.transaction do @first.save! @@ -213,7 +213,7 @@ class TransactionCallbacksTest < ActiveRecord::TestCase end def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_record - new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today) + new_record = TopicWithCallbacks.new(title: "New topic", written_on: Date.today) add_transaction_execution_blocks new_record Topic.transaction do @@ -245,18 +245,18 @@ class TransactionCallbacksTest < ActiveRecord::TestCase def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end def @first.commits(i=0); @commits ||= 0; @commits += i if i; end - @first.after_rollback_block{|r| r.rollbacks(1)} - @first.after_commit_block{|r| r.commits(1)} + @first.after_rollback_block { |r| r.rollbacks(1) } + @first.after_commit_block { |r| r.commits(1) } second = TopicWithCallbacks.find(3) def second.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end def second.commits(i=0); @commits ||= 0; @commits += i if i; end - second.after_rollback_block{|r| r.rollbacks(1)} - second.after_commit_block{|r| r.commits(1)} + second.after_rollback_block { |r| r.rollbacks(1) } + second.after_commit_block { |r| r.commits(1) } Topic.transaction do @first.save! - Topic.transaction(:requires_new => true) do + Topic.transaction(requires_new: true) do second.save! raise ActiveRecord::Rollback end @@ -272,16 +272,16 @@ class TransactionCallbacksTest < ActiveRecord::TestCase def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end def @first.commits(i=0); @commits ||= 0; @commits += i if i; end - @first.after_rollback_block{|r| r.rollbacks(1)} - @first.after_commit_block{|r| r.commits(1)} + @first.after_rollback_block { |r| r.rollbacks(1) } + @first.after_commit_block { |r| r.commits(1) } Topic.transaction do @first.save - Topic.transaction(:requires_new => true) do + Topic.transaction(requires_new: true) do @first.save! raise ActiveRecord::Rollback end - Topic.transaction(:requires_new => true) do + Topic.transaction(requires_new: true) do @first.save! raise ActiveRecord::Rollback end @@ -292,7 +292,7 @@ class TransactionCallbacksTest < ActiveRecord::TestCase end def test_after_commit_callback_should_not_swallow_errors - @first.after_commit_block{ fail "boom" } + @first.after_commit_block { fail "boom" } assert_raises(RuntimeError) do Topic.transaction do @first.save! @@ -303,8 +303,8 @@ class TransactionCallbacksTest < ActiveRecord::TestCase def test_after_commit_callback_when_raise_should_not_restore_state first = TopicWithCallbacks.new second = TopicWithCallbacks.new - first.after_commit_block{ fail "boom" } - second.after_commit_block{ fail "boom" } + first.after_commit_block { fail "boom" } + second.after_commit_block { fail "boom" } begin Topic.transaction do @@ -322,7 +322,7 @@ class TransactionCallbacksTest < ActiveRecord::TestCase def test_after_rollback_callback_should_not_swallow_errors_when_set_to_raise error_class = Class.new(StandardError) - @first.after_rollback_block{ raise error_class } + @first.after_rollback_block { raise error_class } assert_raises(error_class) do Topic.transaction do @first.save! @@ -336,8 +336,8 @@ class TransactionCallbacksTest < ActiveRecord::TestCase first = TopicWithCallbacks.new second = TopicWithCallbacks.new - first.after_rollback_block{ raise error_class } - second.after_rollback_block{ raise error_class } + first.after_rollback_block { raise error_class } + second.after_rollback_block { raise error_class } begin Topic.transaction do @@ -355,13 +355,13 @@ class TransactionCallbacksTest < ActiveRecord::TestCase def test_after_rollback_callbacks_should_validate_on_condition assert_raise(ArgumentError) { Topic.after_rollback(on: :save) } - e = assert_raise(ArgumentError) { Topic.after_rollback(on: 'create') } + e = assert_raise(ArgumentError) { Topic.after_rollback(on: "create") } assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message) end def test_after_commit_callbacks_should_validate_on_condition assert_raise(ArgumentError) { Topic.after_commit(on: :save) } - e = assert_raise(ArgumentError) { Topic.after_commit(on: 'create') } + e = assert_raise(ArgumentError) { Topic.after_commit(on: "create") } assert_match(/:on conditions for after_commit and after_rollback callbacks have to be one of \[:create, :destroy, :update\]/, e.message) end @@ -449,9 +449,7 @@ class CallbacksOnMultipleActionsTest < ActiveRecord::TestCase end end - class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase - class TopicWithoutTransactionalEnrollmentCallbacks < ActiveRecord::Base self.table_name = :topics @@ -470,7 +468,7 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase def test_commit_does_not_run_transactions_callbacks_without_enrollment @topic.transaction do - @topic.content = 'foo' + @topic.content = "foo" @topic.save! end assert @topic.history.empty? @@ -479,7 +477,7 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase def test_commit_run_transactions_callbacks_with_explicit_enrollment @topic.transaction do 2.times do - @topic.content = 'foo' + @topic.content = "foo" @topic.save! end @topic.class.connection.add_transaction_record(@topic) @@ -489,7 +487,7 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase def test_rollback_does_not_run_transactions_callbacks_without_enrollment @topic.transaction do - @topic.content = 'foo' + @topic.content = "foo" @topic.save! raise ActiveRecord::Rollback end @@ -499,7 +497,7 @@ class TransactionEnrollmentCallbacksTest < ActiveRecord::TestCase def test_rollback_run_transactions_callbacks_with_explicit_enrollment @topic.transaction do 2.times do - @topic.content = 'foo' + @topic.content = "foo" @topic.save! end @topic.class.connection.add_transaction_record(@topic) diff --git a/activerecord/test/cases/transaction_isolation_test.rb b/activerecord/test/cases/transaction_isolation_test.rb index 2f7d208ed2..58abfadaf4 100644 --- a/activerecord/test/cases/transaction_isolation_test.rb +++ b/activerecord/test/cases/transaction_isolation_test.rb @@ -1,4 +1,4 @@ -require 'cases/helper' +require "cases/helper" unless ActiveRecord::Base.connection.supports_transaction_isolation? class TransactionIsolationUnsupportedTest < ActiveRecord::TestCase @@ -9,7 +9,7 @@ unless ActiveRecord::Base.connection.supports_transaction_isolation? test "setting the isolation level raises an error" do assert_raises(ActiveRecord::TransactionIsolationError) do - Tag.transaction(isolation: :serializable) { } + Tag.transaction(isolation: :serializable) {} end end end @@ -20,11 +20,11 @@ if ActiveRecord::Base.connection.supports_transaction_isolation? self.use_transactional_tests = false class Tag < ActiveRecord::Base - self.table_name = 'tags' + self.table_name = "tags" end class Tag2 < ActiveRecord::Base - self.table_name = 'tags' + self.table_name = "tags" end setup do @@ -63,18 +63,18 @@ if ActiveRecord::Base.connection.supports_transaction_isolation? # We are testing that a nonrepeatable read does not happen if ActiveRecord::Base.connection.transaction_isolation_levels.include?(:repeatable_read) test "repeatable read" do - tag = Tag.create(name: 'jon') + tag = Tag.create(name: "jon") Tag.transaction(isolation: :repeatable_read) do tag.reload - Tag2.find(tag.id).update(name: 'emily') + Tag2.find(tag.id).update(name: "emily") tag.reload - assert_equal 'jon', tag.name + assert_equal "jon", tag.name end tag.reload - assert_equal 'emily', tag.name + assert_equal "emily", tag.name end end @@ -90,7 +90,7 @@ if ActiveRecord::Base.connection.supports_transaction_isolation? test "setting isolation when joining a transaction raises an error" do Tag.transaction do assert_raises(ActiveRecord::TransactionIsolationError) do - Tag.transaction(isolation: :serializable) { } + Tag.transaction(isolation: :serializable) {} end end end @@ -98,7 +98,7 @@ if ActiveRecord::Base.connection.supports_transaction_isolation? test "setting isolation when starting a nested transaction raises error" do Tag.transaction do assert_raises(ActiveRecord::TransactionIsolationError) do - Tag.transaction(requires_new: true, isolation: :serializable) { } + Tag.transaction(requires_new: true, isolation: :serializable) {} end end end diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index 791b895d02..834365660f 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -1,12 +1,12 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' -require 'models/developer' -require 'models/computer' -require 'models/book' -require 'models/author' -require 'models/post' -require 'models/movie' +require "models/topic" +require "models/reply" +require "models/developer" +require "models/computer" +require "models/book" +require "models/author" +require "models/post" +require "models/movie" class TransactionTest < ActiveRecord::TestCase self.use_transactional_tests = false @@ -144,7 +144,7 @@ class TransactionTest < ActiveRecord::TestCase def test_raising_exception_in_callback_rollbacks_in_save def @first.after_save_for_transaction - raise 'Make the transaction rollback' + raise "Make the transaction rollback" end @first.approved = true @@ -170,7 +170,7 @@ class TransactionTest < ActiveRecord::TestCase topic = Topic.new def topic.after_save_for_transaction - raise 'Make the transaction rollback' + raise "Make the transaction rollback" end assert_raises(RuntimeError) do @@ -181,7 +181,7 @@ class TransactionTest < ActiveRecord::TestCase end def test_transaction_state_is_cleared_when_record_is_persisted - author = Author.create! name: 'foo' + author = Author.create! name: "foo" author.name = nil assert_not author.save assert_not author.new_record? @@ -230,7 +230,7 @@ class TransactionTest < ActiveRecord::TestCase send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic", @first) nbooks_before_save = Book.count original_author_name = @first.author_name - @first.author_name += '_this_should_not_end_up_in_the_db' + @first.author_name += "_this_should_not_end_up_in_the_db" status = @first.save assert !status assert_equal original_author_name, @first.reload.author_name @@ -241,7 +241,7 @@ class TransactionTest < ActiveRecord::TestCase send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic", @first) nbooks_before_save = Book.count original_author_name = @first.author_name - @first.author_name += '_this_should_not_end_up_in_the_db' + @first.author_name += "_this_should_not_end_up_in_the_db" begin @first.save! @@ -256,18 +256,18 @@ class TransactionTest < ActiveRecord::TestCase def test_callback_rollback_in_create topic = Class.new(Topic) { def after_create_for_transaction - raise 'Make the transaction rollback' + raise "Make the transaction rollback" end } - new_topic = topic.new(:title => "A new topic", - :author_name => "Ben", - :author_email_address => "ben@example.com", - :written_on => "2003-07-16t15:28:11.2233+01:00", - :last_read => "2004-04-15", - :bonus_time => "2005-01-30t15:28:00.00+01:00", - :content => "Have a nice day", - :approved => false) + new_topic = topic.new(title: "A new topic", + author_name: "Ben", + author_email_address: "ben@example.com", + written_on: "2003-07-16t15:28:11.2233+01:00", + last_read: "2004-04-15", + bonus_time: "2005-01-30t15:28:00.00+01:00", + content: "Have a nice day", + approved: false) new_record_snapshot = !new_topic.persisted? id_present = new_topic.has_attribute?(Topic.primary_key) @@ -291,7 +291,7 @@ class TransactionTest < ActiveRecord::TestCase end } - new_topic = topic.create(:title => "A new topic") + new_topic = topic.create(title: "A new topic") assert !new_topic.persisted?, "The topic should not be persisted" assert_nil new_topic.id, "The topic should not have an ID" end @@ -329,7 +329,7 @@ class TransactionTest < ActiveRecord::TestCase def test_invalid_keys_for_transaction assert_raise ArgumentError do - Topic.transaction :nested => true do + Topic.transaction nested: true do end end end @@ -342,7 +342,7 @@ class TransactionTest < ActiveRecord::TestCase @second.save! begin - Topic.transaction :requires_new => true do + Topic.transaction requires_new: true do @first.happy = false @first.save! raise @@ -363,7 +363,7 @@ class TransactionTest < ActiveRecord::TestCase @second.save! begin - @second.transaction :requires_new => true do + @second.transaction requires_new: true do @first.happy = false @first.save! raise @@ -403,17 +403,17 @@ class TransactionTest < ActiveRecord::TestCase @first.save! begin - Topic.transaction :requires_new => true do + Topic.transaction requires_new: true do @first.content = "Two" @first.save! begin - Topic.transaction :requires_new => true do + Topic.transaction requires_new: true do @first.content = "Three" @first.save! begin - Topic.transaction :requires_new => true do + Topic.transaction requires_new: true do @first.content = "Four" @first.save! raise @@ -493,7 +493,7 @@ class TransactionTest < ActiveRecord::TestCase def test_rollback_when_commit_raises assert_called(Topic.connection, :begin_db_transaction) do - Topic.connection.stub(:commit_db_transaction, ->{ raise('OH NOES') }) do + Topic.connection.stub(:commit_db_transaction, -> { raise("OH NOES") }) do assert_called(Topic.connection, :rollback_db_transaction) do e = assert_raise RuntimeError do @@ -501,22 +501,23 @@ class TransactionTest < ActiveRecord::TestCase # do nothing end end - assert_equal 'OH NOES', e.message + assert_equal "OH NOES", e.message end end end end def test_rollback_when_saving_a_frozen_record - topic = Topic.new(:title => 'test') + topic = Topic.new(title: "test") topic.freeze e = assert_raise(RuntimeError) { topic.save } - assert_match(/frozen/i, e.message) # Not good enough, but we can't do much - # about it since there is no specific error - # for frozen objects. - assert !topic.persisted?, 'not persisted' + # Not good enough, but we can't do much + # about it since there is no specific error + # for frozen objects. + assert_match(/frozen/i, e.message) + assert !topic.persisted?, "not persisted" assert_nil topic.id - assert topic.frozen?, 'not frozen' + assert topic.frozen?, "not frozen" end def test_rollback_when_thread_killed @@ -549,12 +550,12 @@ class TransactionTest < ActiveRecord::TestCase def test_restore_active_record_state_for_all_records_in_a_transaction topic_without_callbacks = Class.new(ActiveRecord::Base) do - self.table_name = 'topics' + self.table_name = "topics" end - topic_1 = Topic.new(:title => 'test_1') - topic_2 = Topic.new(:title => 'test_2') - topic_3 = topic_without_callbacks.new(:title => 'test_3') + topic_1 = Topic.new(title: "test_1") + topic_2 = Topic.new(title: "test_2") + topic_3 = topic_without_callbacks.new(title: "test_3") Topic.transaction do assert topic_1.save @@ -562,27 +563,27 @@ class TransactionTest < ActiveRecord::TestCase assert topic_3.save @first.save @second.destroy - assert topic_1.persisted?, 'persisted' + assert topic_1.persisted?, "persisted" assert_not_nil topic_1.id - assert topic_2.persisted?, 'persisted' + assert topic_2.persisted?, "persisted" assert_not_nil topic_2.id - assert topic_3.persisted?, 'persisted' + assert topic_3.persisted?, "persisted" assert_not_nil topic_3.id - assert @first.persisted?, 'persisted' + assert @first.persisted?, "persisted" assert_not_nil @first.id - assert @second.destroyed?, 'destroyed' + assert @second.destroyed?, "destroyed" raise ActiveRecord::Rollback end - assert !topic_1.persisted?, 'not persisted' + assert !topic_1.persisted?, "not persisted" assert_nil topic_1.id - assert !topic_2.persisted?, 'not persisted' + assert !topic_2.persisted?, "not persisted" assert_nil topic_2.id - assert !topic_3.persisted?, 'not persisted' + assert !topic_3.persisted?, "not persisted" assert_nil topic_3.id - assert @first.persisted?, 'persisted' + assert @first.persisted?, "persisted" assert_not_nil @first.id - assert !@second.destroyed?, 'not destroyed' + assert !@second.destroyed?, "not destroyed" end def test_restore_frozen_state_after_double_destroy @@ -606,7 +607,7 @@ class TransactionTest < ActiveRecord::TestCase topic.destroy raise ActiveRecord::Rollback end - assert topic.frozen?, 'frozen' + assert topic.frozen?, "frozen" end def test_rollback_for_freshly_persisted_records @@ -615,7 +616,7 @@ class TransactionTest < ActiveRecord::TestCase topic.destroy raise ActiveRecord::Rollback end - assert topic.persisted?, 'persisted' + assert topic.persisted?, "persisted" end def test_sqlite_add_column_in_transaction @@ -629,27 +630,27 @@ class TransactionTest < ActiveRecord::TestCase assert_nothing_raised do Topic.reset_column_information - Topic.connection.add_column('topics', 'stuff', :string) - assert Topic.column_names.include?('stuff') + Topic.connection.add_column("topics", "stuff", :string) + assert_includes Topic.column_names, "stuff" Topic.reset_column_information - Topic.connection.remove_column('topics', 'stuff') - assert !Topic.column_names.include?('stuff') + Topic.connection.remove_column("topics", "stuff") + assert_not_includes Topic.column_names, "stuff" end if Topic.connection.supports_ddl_transactions? assert_nothing_raised do - Topic.transaction { Topic.connection.add_column('topics', 'stuff', :string) } + Topic.transaction { Topic.connection.add_column("topics", "stuff", :string) } end else Topic.transaction do - assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) } + assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column("topics", "stuff", :string) } raise ActiveRecord::Rollback end end ensure begin - Topic.connection.remove_column('topics', 'stuff') + Topic.connection.remove_column("topics", "stuff") rescue ensure Topic.reset_column_information @@ -687,12 +688,12 @@ class TransactionTest < ActiveRecord::TestCase def test_transaction_rollback_with_primarykeyless_tables connection = ActiveRecord::Base.connection connection.create_table(:transaction_without_primary_keys, force: true, id: false) do |t| - t.integer :thing_id + t.integer :thing_id end klass = Class.new(ActiveRecord::Base) do - self.table_name = 'transaction_without_primary_keys' - after_commit { } # necessary to trigger the has_transactional_callbacks branch + self.table_name = "transaction_without_primary_keys" + after_commit {} # necessary to trigger the has_transactional_callbacks branch end assert_no_difference(-> { klass.count }) do @@ -702,20 +703,20 @@ class TransactionTest < ActiveRecord::TestCase end end ensure - connection.drop_table 'transaction_without_primary_keys', if_exists: true + connection.drop_table "transaction_without_primary_keys", if_exists: true end private - %w(validation save destroy).each do |filter| - define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do |topic| - meta = class << topic; self; end - meta.send("define_method", "before_#{filter}_for_transaction") do - Book.create - throw(:abort) + %w(validation save destroy).each do |filter| + define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do |topic| + meta = class << topic; self; end + meta.send("define_method", "before_#{filter}_for_transaction") do + Book.create + throw(:abort) + end end end - end end class TransactionsWithTransactionalFixturesTest < ActiveRecord::TestCase diff --git a/activerecord/test/cases/type/integer_test.rb b/activerecord/test/cases/type/integer_test.rb index c0932d5357..368b6d7199 100644 --- a/activerecord/test/cases/type/integer_test.rb +++ b/activerecord/test/cases/type/integer_test.rb @@ -6,13 +6,13 @@ module ActiveRecord class IntegerTest < ActiveRecord::TestCase test "casting ActiveRecord models" do type = Type::Integer.new - firm = Firm.create(:name => 'Apple') + firm = Firm.create(name: "Apple") assert_nil type.cast(firm) end test "values which are out of range can be re-assigned" do klass = Class.new(ActiveRecord::Base) do - self.table_name = 'posts' + self.table_name = "posts" attribute :foo, :integer end model = klass.new diff --git a/activerecord/test/cases/type/string_test.rb b/activerecord/test/cases/type/string_test.rb index 6fe6d46711..a95da864fa 100644 --- a/activerecord/test/cases/type/string_test.rb +++ b/activerecord/test/cases/type/string_test.rb @@ -1,21 +1,21 @@ -require 'cases/helper' +require "cases/helper" module ActiveRecord class StringTypeTest < ActiveRecord::TestCase test "string mutations are detected" do klass = Class.new(Base) - klass.table_name = 'authors' + klass.table_name = "authors" - author = klass.create!(name: 'Sean') + author = klass.create!(name: "Sean") assert_not author.changed? - author.name << ' Griffin' + author.name << " Griffin" assert author.name_changed? author.save! author.reload - assert_equal 'Sean Griffin', author.name + assert_equal "Sean Griffin", author.name assert_not author.changed? end end diff --git a/activerecord/test/cases/type/type_map_test.rb b/activerecord/test/cases/type/type_map_test.rb index 172c6dfc4c..2959d36466 100644 --- a/activerecord/test/cases/type/type_map_test.rb +++ b/activerecord/test/cases/type/type_map_test.rb @@ -15,7 +15,7 @@ module ActiveRecord mapping.register_type(/boolean/i, boolean) - assert_equal mapping.lookup('boolean'), boolean + assert_equal mapping.lookup("boolean"), boolean end def test_overriding_registered_types @@ -26,7 +26,7 @@ module ActiveRecord mapping.register_type(/time/i, time) mapping.register_type(/time/i, timestamp) - assert_equal mapping.lookup('time'), timestamp + assert_equal mapping.lookup("time"), timestamp end def test_fuzzy_lookup @@ -35,7 +35,7 @@ module ActiveRecord mapping.register_type(/varchar/i, string) - assert_equal mapping.lookup('varchar(20)'), string + assert_equal mapping.lookup("varchar(20)"), string end def test_aliasing_types @@ -43,9 +43,9 @@ module ActiveRecord mapping = TypeMap.new mapping.register_type(/string/i, string) - mapping.alias_type(/varchar/i, 'string') + mapping.alias_type(/varchar/i, "string") - assert_equal mapping.lookup('varchar'), string + assert_equal mapping.lookup("varchar"), string end def test_changing_type_changes_aliases @@ -54,20 +54,20 @@ module ActiveRecord mapping = TypeMap.new mapping.register_type(/timestamp/i, time) - mapping.alias_type(/datetime/i, 'timestamp') + mapping.alias_type(/datetime/i, "timestamp") mapping.register_type(/timestamp/i, timestamp) - assert_equal mapping.lookup('datetime'), timestamp + assert_equal mapping.lookup("datetime"), timestamp end def test_aliases_keep_metadata mapping = TypeMap.new mapping.register_type(/decimal/i) { |sql_type| sql_type } - mapping.alias_type(/number/i, 'decimal') + mapping.alias_type(/number/i, "decimal") - assert_equal mapping.lookup('number(20)'), 'decimal(20)' - assert_equal mapping.lookup('number'), 'decimal' + assert_equal mapping.lookup("number(20)"), "decimal(20)" + assert_equal mapping.lookup("number"), "decimal" end def test_register_proc @@ -76,15 +76,15 @@ module ActiveRecord mapping = TypeMap.new mapping.register_type(/varchar/i) do |type| - if type.include?('(') + if type.include?("(") string else binary end end - assert_equal mapping.lookup('varchar(20)'), string - assert_equal mapping.lookup('varchar'), binary + assert_equal mapping.lookup("varchar(20)"), string + assert_equal mapping.lookup("varchar"), binary end def test_additional_lookup_args @@ -92,16 +92,16 @@ module ActiveRecord mapping.register_type(/varchar/i) do |type, limit| if limit > 255 - 'text' + "text" else - 'string' + "string" end end - mapping.alias_type(/string/i, 'varchar') + mapping.alias_type(/string/i, "varchar") - assert_equal mapping.lookup('varchar', 200), 'string' - assert_equal mapping.lookup('varchar', 400), 'text' - assert_equal mapping.lookup('string', 400), 'text' + assert_equal mapping.lookup("varchar", 200), "string" + assert_equal mapping.lookup("varchar", 400), "text" + assert_equal mapping.lookup("string", 400), "text" end def test_requires_value_or_block @@ -115,13 +115,13 @@ module ActiveRecord def test_lookup_non_strings mapping = HashLookupTypeMap.new - mapping.register_type(1, 'string') - mapping.register_type(2, 'int') + mapping.register_type(1, "string") + mapping.register_type(2, "int") mapping.alias_type(3, 1) - assert_equal mapping.lookup(1), 'string' - assert_equal mapping.lookup(2), 'int' - assert_equal mapping.lookup(3), 'string' + assert_equal mapping.lookup(1), "string" + assert_equal mapping.lookup(2), "int" + assert_equal mapping.lookup(3), "string" assert_kind_of Type::Value, mapping.lookup(4) end @@ -174,4 +174,3 @@ module ActiveRecord end end end - diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb index 81fcf04a27..11476ea0ef 100644 --- a/activerecord/test/cases/types_test.rb +++ b/activerecord/test/cases/types_test.rb @@ -9,7 +9,7 @@ module ActiveRecord raise end klass = Class.new(ActiveRecord::Base) do - self.table_name = 'posts' + self.table_name = "posts" attribute :foo, type_which_cannot_go_to_the_database end model = klass.new diff --git a/activerecord/test/cases/validations/absence_validation_test.rb b/activerecord/test/cases/validations/absence_validation_test.rb index c0b3750bcc..870619e4e7 100644 --- a/activerecord/test/cases/validations/absence_validation_test.rb +++ b/activerecord/test/cases/validations/absence_validation_test.rb @@ -1,8 +1,8 @@ require "cases/helper" -require 'models/face' -require 'models/interest' -require 'models/man' -require 'models/topic' +require "models/face" +require "models/interest" +require "models/man" +require "models/topic" class AbsenceValidationTest < ActiveRecord::TestCase def test_non_association @@ -52,7 +52,7 @@ class AbsenceValidationTest < ActiveRecord::TestCase end face_with_to_a = Face.new - def face_with_to_a.to_a; ['(/)', '(\)']; end + def face_with_to_a.to_a; ["(/)", '(\)']; end assert_nothing_raised { boy_klass.new(face: face_with_to_a).valid? } end @@ -62,10 +62,10 @@ class AbsenceValidationTest < ActiveRecord::TestCase Interest.send(:attr_accessor, :token) Interest.validates_absence_of(:token) - interest = Interest.create!(topic: 'Thought Leadering') + interest = Interest.create!(topic: "Thought Leadering") assert interest.valid? - interest.token = 'tl' + interest.token = "tl" assert interest.invalid? end diff --git a/activerecord/test/cases/validations/association_validation_test.rb b/activerecord/test/cases/validations/association_validation_test.rb index 584a3dc0d8..66d6ecb928 100644 --- a/activerecord/test/cases/validations/association_validation_test.rb +++ b/activerecord/test/cases/validations/association_validation_test.rb @@ -1,8 +1,8 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' -require 'models/man' -require 'models/interest' +require "models/topic" +require "models/reply" +require "models/man" +require "models/interest" class AssociationValidationTest < ActiveRecord::TestCase fixtures :topics @@ -25,7 +25,7 @@ class AssociationValidationTest < ActiveRecord::TestCase end def test_validates_associated_one - Reply.validates :topic, :associated => true + Reply.validates :topic, associated: true Topic.validates_presence_of( :content ) r = Reply.new("title" => "A reply", "content" => "with content!") r.topic = Topic.create("title" => "uhohuhoh") @@ -58,7 +58,7 @@ class AssociationValidationTest < ActiveRecord::TestCase end def test_validates_associated_with_custom_message_using_quotes - Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes" + Reply.validates_associated :topic, message: "This string contains 'single' and \"double\" quotes" Topic.validates_presence_of :content r = Reply.create("title" => "A reply", "content" => "with content!") r.topic = Topic.create("title" => "uhohuhoh") @@ -80,8 +80,8 @@ class AssociationValidationTest < ActiveRecord::TestCase repair_validations(Interest) do # Note that Interest and Man have the :inverse_of option set Interest.validates_presence_of(:man) - man = Man.new(:name => 'John') - interest = man.interests.build(:topic => 'Airplanes') + man = Man.new(name: "John") + interest = man.interests.build(topic: "Airplanes") assert interest.valid?, "Expected interest to be valid, but was not. Interest should have a man object associated" end end @@ -89,8 +89,8 @@ class AssociationValidationTest < ActiveRecord::TestCase def test_validates_presence_of_belongs_to_association__existing_parent repair_validations(Interest) do Interest.validates_presence_of(:man) - man = Man.create!(:name => 'John') - interest = man.interests.build(:topic => 'Airplanes') + man = Man.create!(name: "John") + interest = man.interests.build(topic: "Airplanes") assert interest.valid?, "Expected interest to be valid, but was not. Interest should have a man object associated" end end diff --git a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb index 13d4d85afa..a57065ba75 100644 --- a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb @@ -1,5 +1,5 @@ require "cases/helper" -require 'models/topic' +require "models/topic" class I18nGenerateMessageValidationTest < ActiveRecord::TestCase def setup @@ -20,20 +20,20 @@ class I18nGenerateMessageValidationTest < ActiveRecord::TestCase # validates_associated: generate_message(attr_name, :invalid, :message => custom_message, :value => value) def test_generate_message_invalid_with_default_message - assert_equal 'is invalid', @topic.errors.generate_message(:title, :invalid, :value => 'title') + assert_equal "is invalid", @topic.errors.generate_message(:title, :invalid, value: "title") end def test_generate_message_invalid_with_custom_message - assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :message => 'custom message %{value}', :value => 'title') + assert_equal "custom message title", @topic.errors.generate_message(:title, :invalid, message: "custom message %{value}", value: "title") end # validates_uniqueness_of: generate_message(attr_name, :taken, :message => custom_message) def test_generate_message_taken_with_default_message - assert_equal "has already been taken", @topic.errors.generate_message(:title, :taken, :value => 'title') + assert_equal "has already been taken", @topic.errors.generate_message(:title, :taken, value: "title") end def test_generate_message_taken_with_custom_message - assert_equal 'custom message title', @topic.errors.generate_message(:title, :taken, :message => 'custom message %{value}', :value => 'title') + assert_equal "custom message title", @topic.errors.generate_message(:title, :taken, message: "custom message %{value}", value: "title") end # ActiveRecord#RecordInvalid exception @@ -47,7 +47,7 @@ class I18nGenerateMessageValidationTest < ActiveRecord::TestCase test "RecordInvalid exception translation falls back to the :errors namespace" do reset_i18n_load_path do - I18n.backend.store_translations 'en', :errors => {:messages => {:record_invalid => 'fallback message'}} + I18n.backend.store_translations "en", errors: { messages: { record_invalid: "fallback message" } } topic = Topic.new topic.errors.add(:title, :blank) assert_equal "fallback message", ActiveRecord::RecordInvalid.new(topic).message @@ -56,29 +56,29 @@ class I18nGenerateMessageValidationTest < ActiveRecord::TestCase test "translation for 'taken' can be overridden" do reset_i18n_load_path do - I18n.backend.store_translations "en", {errors: {attributes: {title: {taken: "Custom taken message" }}}} - assert_equal "Custom taken message", @topic.errors.generate_message(:title, :taken, :value => 'title') + I18n.backend.store_translations "en", errors: { attributes: { title: { taken: "Custom taken message" } } } + assert_equal "Custom taken message", @topic.errors.generate_message(:title, :taken, value: "title") end end test "translation for 'taken' can be overridden in activerecord scope" do reset_i18n_load_path do - I18n.backend.store_translations "en", {activerecord: {errors: {messages: {taken: "Custom taken message" }}}} - assert_equal "Custom taken message", @topic.errors.generate_message(:title, :taken, :value => 'title') + I18n.backend.store_translations "en", activerecord: { errors: { messages: { taken: "Custom taken message" } } } + assert_equal "Custom taken message", @topic.errors.generate_message(:title, :taken, value: "title") end end test "translation for 'taken' can be overridden in activerecord model scope" do reset_i18n_load_path do - I18n.backend.store_translations "en", {activerecord: {errors: {models: {topic: {taken: "Custom taken message" }}}}} - assert_equal "Custom taken message", @topic.errors.generate_message(:title, :taken, :value => 'title') + I18n.backend.store_translations "en", activerecord: { errors: { models: { topic: { taken: "Custom taken message" } } } } + assert_equal "Custom taken message", @topic.errors.generate_message(:title, :taken, value: "title") end end test "translation for 'taken' can be overridden in activerecord attributes scope" do reset_i18n_load_path do - I18n.backend.store_translations "en", {activerecord: {errors: {models: {topic: {attributes: {title: {taken: "Custom taken message" }}}}}}} - assert_equal "Custom taken message", @topic.errors.generate_message(:title, :taken, :value => 'title') + I18n.backend.store_translations "en", activerecord: { errors: { models: { topic: { attributes: { title: { taken: "Custom taken message" } } } } } } + assert_equal "Custom taken message", @topic.errors.generate_message(:title, :taken, value: "title") end end end diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb index b8307d6665..fd88a3ea67 100644 --- a/activerecord/test/cases/validations/i18n_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_validation_test.rb @@ -1,6 +1,6 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' +require "models/topic" +require "models/reply" class I18nValidationTest < ActiveRecord::TestCase repair_validations(Topic, Reply) @@ -12,7 +12,7 @@ class I18nValidationTest < ActiveRecord::TestCase @old_load_path, @old_backend = I18n.load_path.dup, I18n.backend I18n.load_path.clear I18n.backend = I18n::Backend::Simple.new - I18n.backend.store_translations('en', :errors => {:messages => {:custom => nil}}) + I18n.backend.store_translations("en", errors: { messages: { custom: nil } }) end teardown do @@ -21,12 +21,12 @@ class I18nValidationTest < ActiveRecord::TestCase end def unique_topic - @unique ||= Topic.create :title => 'unique!' + @unique ||= Topic.create title: "unique!" end def replied_topic @replied_topic ||= begin - topic = Topic.create(:title => "topic") + topic = Topic.create(title: "topic") topic.replies << Reply.new topic end @@ -36,22 +36,20 @@ class I18nValidationTest < ActiveRecord::TestCase # are used to generate tests to keep things DRY # COMMON_CASES = [ - # [ case, validation_options, generate_message_options] + # [ case, validation_options, generate_message_options] [ "given no options", {}, {}], - [ "given custom message", {:message => "custom"}, {:message => "custom"}], - [ "given if condition", {:if => lambda { true }}, {}], - [ "given unless condition", {:unless => lambda { false }}, {}], - [ "given option that is not reserved", {:format => "jpg"}, {:format => "jpg" }] - # TODO Add :on case, but below doesn't work, because then the validation isn't run for some reason - # even when using .save instead .valid? - # [ "given on condition", {on: :save}, {}] + [ "given custom message", { message: "custom" }, { message: "custom" }], + [ "given if condition", { if: lambda { true } }, {}], + [ "given unless condition", { unless: lambda { false } }, {}], + [ "given option that is not reserved", { format: "jpg" }, { format: "jpg" }], + [ "given on condition", { on: [:create, :update] }, {}] ] COMMON_CASES.each do |name, validation_options, generate_message_options| test "validates_uniqueness_of on generated message #{name}" do Topic.validates_uniqueness_of :title, validation_options @topic.title = unique_topic.title - assert_called_with(@topic.errors, :generate_message, [:title, :taken, generate_message_options.merge(:value => 'unique!')]) do + assert_called_with(@topic.errors, :generate_message, [:title, :taken, generate_message_options.merge(value: "unique!")]) do @topic.valid? end end @@ -60,27 +58,26 @@ class I18nValidationTest < ActiveRecord::TestCase COMMON_CASES.each do |name, validation_options, generate_message_options| test "validates_associated on generated message #{name}" do Topic.validates_associated :replies, validation_options - assert_called_with(replied_topic.errors, :generate_message, [:replies, :invalid, generate_message_options.merge(:value => replied_topic.replies)]) do + assert_called_with(replied_topic.errors, :generate_message, [:replies, :invalid, generate_message_options.merge(value: replied_topic.replies)]) do replied_topic.save end end end def test_validates_associated_finds_custom_model_key_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:replies => {:invalid => 'custom message'}}}}}} - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}} + I18n.backend.store_translations "en", activerecord: { errors: { models: { topic: { attributes: { replies: { invalid: "custom message" } } } } } } + I18n.backend.store_translations "en", activerecord: { errors: { messages: { invalid: "global message" } } } Topic.validates_associated :replies replied_topic.valid? - assert_equal ['custom message'], replied_topic.errors[:replies].uniq + assert_equal ["custom message"], replied_topic.errors[:replies].uniq end def test_validates_associated_finds_global_default_translation - I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:invalid => 'global message'}}} + I18n.backend.store_translations "en", activerecord: { errors: { messages: { invalid: "global message" } } } Topic.validates_associated :replies replied_topic.valid? - assert_equal ['global message'], replied_topic.errors[:replies] + assert_equal ["global message"], replied_topic.errors[:replies] end - end diff --git a/activerecord/test/cases/validations/length_validation_test.rb b/activerecord/test/cases/validations/length_validation_test.rb index 78263fd955..ba45c6dcc1 100644 --- a/activerecord/test/cases/validations/length_validation_test.rb +++ b/activerecord/test/cases/validations/length_validation_test.rb @@ -1,47 +1,46 @@ require "cases/helper" -require 'models/owner' -require 'models/pet' -require 'models/person' +require "models/owner" +require "models/pet" +require "models/person" class LengthValidationTest < ActiveRecord::TestCase fixtures :owners setup do @owner = Class.new(Owner) do - def self.name; 'Owner'; end + def self.name; "Owner"; end end end - def test_validates_size_of_association assert_nothing_raised { @owner.validates_size_of :pets, minimum: 1 } - o = @owner.new('name' => 'nopets') + o = @owner.new("name" => "nopets") assert !o.save assert o.errors[:pets].any? - o.pets.build('name' => 'apet') + o.pets.build("name" => "apet") assert o.valid? end def test_validates_size_of_association_using_within assert_nothing_raised { @owner.validates_size_of :pets, within: 1..2 } - o = @owner.new('name' => 'nopets') + o = @owner.new("name" => "nopets") assert !o.save assert o.errors[:pets].any? - o.pets.build('name' => 'apet') + o.pets.build("name" => "apet") assert o.valid? - 2.times { o.pets.build('name' => 'apet') } + 2.times { o.pets.build("name" => "apet") } assert !o.save assert o.errors[:pets].any? end def test_validates_size_of_association_utf8 @owner.validates_size_of :pets, minimum: 1 - o = @owner.new('name' => 'あいうえおかきくけこ') + o = @owner.new("name" => "あいうえおかきくけこ") assert !o.save assert o.errors[:pets].any? - o.pets.build('name' => 'あいうえおかきくけこ') + o.pets.build("name" => "あいうえおかきくけこ") assert o.valid? end @@ -55,7 +54,7 @@ class LengthValidationTest < ActiveRecord::TestCase assert owner.save pet_count = Pet.count - assert_not owner.update_attributes pets_attributes: [ {_destroy: 1, id: pet.id} ] + assert_not owner.update_attributes pets_attributes: [ { _destroy: 1, id: pet.id } ] assert_not owner.valid? assert owner.errors[:pets].any? assert_equal pet_count, Pet.count @@ -67,11 +66,11 @@ class LengthValidationTest < ActiveRecord::TestCase Pet.validates_length_of(:name, minimum: 1) Pet.validates_length_of(:nickname, minimum: 1) - pet = Pet.create!(name: 'Fancy Pants', nickname: 'Fancy') + pet = Pet.create!(name: "Fancy Pants", nickname: "Fancy") assert pet.valid? - pet.nickname = '' + pet.nickname = "" assert pet.invalid? end diff --git a/activerecord/test/cases/validations/presence_validation_test.rb b/activerecord/test/cases/validations/presence_validation_test.rb index 868d111b8c..13956e26ec 100644 --- a/activerecord/test/cases/validations/presence_validation_test.rb +++ b/activerecord/test/cases/validations/presence_validation_test.rb @@ -1,9 +1,9 @@ require "cases/helper" -require 'models/man' -require 'models/face' -require 'models/interest' -require 'models/speedometer' -require 'models/dashboard' +require "models/man" +require "models/face" +require "models/interest" +require "models/speedometer" +require "models/dashboard" class PresenceValidationTest < ActiveRecord::TestCase class Boy < Man; end @@ -57,7 +57,7 @@ class PresenceValidationTest < ActiveRecord::TestCase dash = Dashboard.new # dashboard has to_a method - def dash.to_a; ['(/)', '(\)']; end + def dash.to_a; ["(/)", '(\)']; end s = speedometer.new s.dashboard = dash @@ -71,10 +71,10 @@ class PresenceValidationTest < ActiveRecord::TestCase Interest.validates_presence_of(:topic) Interest.validates_presence_of(:abbreviation) - interest = Interest.create!(topic: 'Thought Leadering', abbreviation: 'tl') + interest = Interest.create!(topic: "Thought Leadering", abbreviation: "tl") assert interest.valid? - interest.abbreviation = '' + interest.abbreviation = "" assert interest.invalid? end diff --git a/activerecord/test/cases/validations/uniqueness_validation_test.rb b/activerecord/test/cases/validations/uniqueness_validation_test.rb index 4b0a590adb..44b4e28777 100644 --- a/activerecord/test/cases/validations/uniqueness_validation_test.rb +++ b/activerecord/test/cases/validations/uniqueness_validation_test.rb @@ -1,11 +1,11 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' -require 'models/warehouse_thing' -require 'models/guid' -require 'models/event' -require 'models/dashboard' -require 'models/uuid_item' +require "models/topic" +require "models/reply" +require "models/warehouse_thing" +require "models/guid" +require "models/event" +require "models/dashboard" +require "models/uuid_item" class Wizard < ActiveRecord::Base self.abstract_class = true @@ -26,7 +26,7 @@ end class ReplyTitle; end class ReplyWithTitleObject < Reply - validates_uniqueness_of :content, :scope => :title + validates_uniqueness_of :content, scope: :title def title; ReplyTitle.new; end end @@ -38,13 +38,13 @@ end class BigIntTest < ActiveRecord::Base INT_MAX_VALUE = 2147483647 - self.table_name = 'cars' + self.table_name = "cars" validates :engines_count, uniqueness: true, inclusion: { in: 0..INT_MAX_VALUE } end class BigIntReverseTest < ActiveRecord::Base INT_MAX_VALUE = 2147483647 - self.table_name = 'cars' + self.table_name = "cars" validates :engines_count, inclusion: { in: 0..INT_MAX_VALUE } validates :engines_count, uniqueness: true end @@ -57,14 +57,14 @@ class TopicWithAfterCreate < Topic after_create :set_author def set_author - update_attributes!(:author_name => "#{title} #{id}") + update_attributes!(author_name: "#{title} #{id}") end end class UniquenessValidationTest < ActiveRecord::TestCase INT_MAX_VALUE = 2147483647 - fixtures :topics, 'warehouse-things' + fixtures :topics, "warehouse-things" repair_validations(Topic, Reply) @@ -90,7 +90,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase Topic.alias_attribute :new_title, :title Topic.validates_uniqueness_of(:new_title) - topic = Topic.new(new_title: 'abc') + topic = Topic.new(new_title: "abc") assert topic.valid? end @@ -107,33 +107,33 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validates_uniqueness_with_validates - Topic.validates :title, :uniqueness => true - Topic.create!('title' => 'abc') + Topic.validates :title, uniqueness: true + Topic.create!("title" => "abc") - t2 = Topic.new('title' => 'abc') + t2 = Topic.new("title" => "abc") assert !t2.valid? assert t2.errors[:title] end def test_validate_uniqueness_when_integer_out_of_range entry = BigIntTest.create(engines_count: INT_MAX_VALUE + 1) - assert_equal entry.errors[:engines_count], ['is not included in the list'] + assert_equal entry.errors[:engines_count], ["is not included in the list"] end def test_validate_uniqueness_when_integer_out_of_range_show_order_does_not_matter entry = BigIntReverseTest.create(engines_count: INT_MAX_VALUE + 1) - assert_equal entry.errors[:engines_count], ['is not included in the list'] + assert_equal entry.errors[:engines_count], ["is not included in the list"] end def test_validates_uniqueness_with_newline_chars - Topic.validates_uniqueness_of(:title, :case_sensitive => false) + Topic.validates_uniqueness_of(:title, case_sensitive: false) t = Topic.new("title" => "new\nline") assert t.save, "Should save t as unique" end def test_validate_uniqueness_with_scope - Reply.validates_uniqueness_of(:content, :scope => "parent_id") + Reply.validates_uniqueness_of(:content, scope: "parent_id") t = Topic.create("title" => "I'm unique!") @@ -152,7 +152,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_uniqueness_with_object_scope - Reply.validates_uniqueness_of(:content, :scope => :topic) + Reply.validates_uniqueness_of(:content, scope: :topic) t = Topic.create("title" => "I'm unique!") @@ -199,7 +199,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_uniqueness_with_scope_array - Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id]) + Reply.validates_uniqueness_of(:author_name, scope: [:author_email_address, :parent_id]) t = Topic.create("title" => "The earth is actually flat!") @@ -223,7 +223,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_case_insensitive_uniqueness - Topic.validates_uniqueness_of(:title, :parent_id, :case_sensitive => false, :allow_nil => true) + Topic.validates_uniqueness_of(:title, :parent_id, case_sensitive: false, allow_nil: true) t = Topic.new("title" => "I'm unique!", :parent_id => 2) assert t.save, "Should save t as unique" @@ -256,7 +256,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase assert t_utf8.save, "Should save t_utf8 as unique" # If database hasn't UTF-8 character set, this test fails - if Topic.all.merge!(:select => 'LOWER(title) AS title').find(t_utf8.id).title == "я тоже уникальный!" + if Topic.all.merge!(select: "LOWER(title) AS title").find(t_utf8.id).title == "я тоже уникальный!" t2_utf8 = Topic.new("title" => "я тоже УНИКАЛЬНЫЙ!") assert !t2_utf8.valid?, "Shouldn't be valid" assert !t2_utf8.save, "Shouldn't save t2_utf8 as unique" @@ -264,7 +264,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_case_sensitive_uniqueness_with_special_sql_like_chars - Topic.validates_uniqueness_of(:title, :case_sensitive => true) + Topic.validates_uniqueness_of(:title, case_sensitive: true) t = Topic.new("title" => "I'm unique!") assert t.save, "Should save t as unique" @@ -277,7 +277,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_case_insensitive_uniqueness_with_special_sql_like_chars - Topic.validates_uniqueness_of(:title, :case_sensitive => false) + Topic.validates_uniqueness_of(:title, case_sensitive: false) t = Topic.new("title" => "I'm unique!") assert t.save, "Should save t as unique" @@ -290,7 +290,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_case_sensitive_uniqueness - Topic.validates_uniqueness_of(:title, :case_sensitive => true, :allow_nil => true) + Topic.validates_uniqueness_of(:title, case_sensitive: true, allow_nil: true) t = Topic.new("title" => "I'm unique!") assert t.save, "Should save t as unique" @@ -314,16 +314,16 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_case_sensitive_uniqueness_with_attribute_passed_as_integer - Topic.validates_uniqueness_of(:title, :case_sensitive => true) - Topic.create!('title' => 101) + Topic.validates_uniqueness_of(:title, case_sensitive: true) + Topic.create!("title" => 101) - t2 = Topic.new('title' => 101) + t2 = Topic.new("title" => 101) assert !t2.valid? assert t2.errors[:title] end def test_validate_uniqueness_with_non_standard_table_names - i1 = WarehouseThing.create(:value => 1000) + i1 = WarehouseThing.create(value: 1000) assert !i1.valid?, "i1 should not be valid" assert i1.errors[:value].any?, "Should not be empty" end @@ -331,7 +331,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase def test_validates_uniqueness_inside_scoping Topic.validates_uniqueness_of(:title) - Topic.where(:author_name => "David").scoping do + Topic.where(author_name: "David").scoping do t1 = Topic.new("title" => "I'm unique!", "author_name" => "Mary") assert t1.save t2 = Topic.new("title" => "I'm unique!", "author_name" => "David") @@ -387,29 +387,29 @@ class UniquenessValidationTest < ActiveRecord::TestCase end def test_validate_straight_inheritance_uniqueness - w1 = IneptWizard.create(:name => "Rincewind", :city => "Ankh-Morpork") + w1 = IneptWizard.create(name: "Rincewind", city: "Ankh-Morpork") assert w1.valid?, "Saving w1" # Should use validation from base class (which is abstract) - w2 = IneptWizard.new(:name => "Rincewind", :city => "Quirm") + w2 = IneptWizard.new(name: "Rincewind", city: "Quirm") assert !w2.valid?, "w2 shouldn't be valid" assert w2.errors[:name].any?, "Should have errors for name" assert_equal ["has already been taken"], w2.errors[:name], "Should have uniqueness message for name" - w3 = Conjurer.new(:name => "Rincewind", :city => "Quirm") + w3 = Conjurer.new(name: "Rincewind", city: "Quirm") assert !w3.valid?, "w3 shouldn't be valid" assert w3.errors[:name].any?, "Should have errors for name" assert_equal ["has already been taken"], w3.errors[:name], "Should have uniqueness message for name" - w4 = Conjurer.create(:name => "The Amazing Bonko", :city => "Quirm") + w4 = Conjurer.create(name: "The Amazing Bonko", city: "Quirm") assert w4.valid?, "Saving w4" - w5 = Thaumaturgist.new(:name => "The Amazing Bonko", :city => "Lancre") + w5 = Thaumaturgist.new(name: "The Amazing Bonko", city: "Lancre") assert !w5.valid?, "w5 shouldn't be valid" assert w5.errors[:name].any?, "Should have errors for name" assert_equal ["has already been taken"], w5.errors[:name], "Should have uniqueness message for name" - w6 = Thaumaturgist.new(:name => "Mustrum Ridcully", :city => "Quirm") + w6 = Thaumaturgist.new(name: "Mustrum Ridcully", city: "Quirm") assert !w6.valid?, "w6 shouldn't be valid" assert w6.errors[:city].any?, "Should have errors for city" assert_equal ["has already been taken"], w6.errors[:city], "Should have uniqueness message for city" @@ -439,7 +439,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase topic = TopicWithUniqEvent.new(event: event) assert_not topic.valid? - assert_equal ['has already been taken'], topic.errors[:event] + assert_equal ["has already been taken"], topic.errors[:event] end def test_validate_uniqueness_on_empty_relation @@ -501,30 +501,30 @@ class UniquenessValidationTest < ActiveRecord::TestCase def test_validate_uniqueness_with_after_create_performing_save TopicWithAfterCreate.validates_uniqueness_of(:title) - topic = TopicWithAfterCreate.create!(:title => "Title1") + topic = TopicWithAfterCreate.create!(title: "Title1") assert topic.author_name.start_with?("Title1") - topic2 = TopicWithAfterCreate.new(:title => "Title1") + topic2 = TopicWithAfterCreate.new(title: "Title1") refute topic2.valid? assert_equal(["has already been taken"], topic2.errors[:title]) end def test_validate_uniqueness_uuid skip unless current_adapter?(:PostgreSQLAdapter) - item = UuidItem.create!(uuid: SecureRandom.uuid, title: 'item1') - item.update(title: 'item1-title2') + item = UuidItem.create!(uuid: SecureRandom.uuid, title: "item1") + item.update(title: "item1-title2") assert_empty item.errors - item2 = UuidValidatingItem.create!(uuid: SecureRandom.uuid, title: 'item2') - item2.update(title: 'item2-title2') + item2 = UuidValidatingItem.create!(uuid: SecureRandom.uuid, title: "item2") + item2.update(title: "item2-title2") assert_empty item2.errors end def test_validate_uniqueness_regular_id - item = CoolTopic.create!(title: 'MyItem') + item = CoolTopic.create!(title: "MyItem") assert_empty item.errors - item2 = CoolTopic.new(id: item.id, title: 'MyItem2') + item2 = CoolTopic.new(id: item.id, title: "MyItem2") refute item2.valid? assert_equal(["has already been taken"], item2.errors[:id]) diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index 85e33d2218..5d9aa99497 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -1,11 +1,11 @@ require "cases/helper" -require 'models/topic' -require 'models/reply' -require 'models/person' -require 'models/developer' -require 'models/computer' -require 'models/parrot' -require 'models/company' +require "models/topic" +require "models/reply" +require "models/person" +require "models/developer" +require "models/computer" +require "models/parrot" +require "models/company" class ValidationsTest < ActiveRecord::TestCase fixtures :topics, :developers @@ -36,7 +36,7 @@ class ValidationsTest < ActiveRecord::TestCase end def test_valid_using_special_context - r = WrongReply.new(:title => "Valid title") + r = WrongReply.new(title: "Valid title") assert !r.valid?(:special_case) assert_equal "Invalid", r.errors[:author_name].join @@ -53,7 +53,7 @@ class ValidationsTest < ActiveRecord::TestCase end def test_invalid_using_multiple_contexts - r = WrongReply.new(:title => 'Wrong Create') + r = WrongReply.new(title: "Wrong Create") assert r.invalid?([:special_case, :create]) assert_equal "Invalid", r.errors[:author_name].join assert_equal "is Wrong Create", r.errors[:title].join @@ -95,7 +95,7 @@ class ValidationsTest < ActiveRecord::TestCase assert_raise(ActiveRecord::RecordInvalid) do WrongReply.new.validate!(:special_case) end - r = WrongReply.new(:title => "Valid title", :author_name => "secret", :content => "Good") + r = WrongReply.new(title: "Valid title", author_name: "secret", content: "Good") assert r.validate!(:special_case) end @@ -107,7 +107,7 @@ class ValidationsTest < ActiveRecord::TestCase def test_exception_on_create_bang_with_block assert_raise(ActiveRecord::RecordInvalid) do - WrongReply.create!({ "title" => "OK" }) do |r| + WrongReply.create!("title" => "OK") do |r| r.content = nil end end @@ -124,7 +124,7 @@ class ValidationsTest < ActiveRecord::TestCase def test_save_without_validation reply = WrongReply.new assert !reply.save - assert reply.save(:validate => false) + assert reply.save(validate: false) end def test_validates_acceptance_of_with_non_existent_table @@ -156,22 +156,20 @@ class ValidationsTest < ActiveRecord::TestCase end def test_numericality_validation_with_mutation - Topic.class_eval do + klass = Class.new(Topic) do attribute :wibble, :string validates_numericality_of :wibble, only_integer: true end - topic = Topic.new(wibble: '123-4567') - topic.wibble.gsub!('-', '') + topic = klass.new(wibble: "123-4567") + topic.wibble.gsub!("-", "") assert topic.valid? - ensure - Topic.reset_column_information end def test_acceptance_validator_doesnt_require_db_connection klass = Class.new(ActiveRecord::Base) do - self.table_name = 'posts' + self.table_name = "posts" end klass.reset_column_information diff --git a/activerecord/test/cases/view_test.rb b/activerecord/test/cases/view_test.rb index f3c2d2f30e..0e38cee334 100644 --- a/activerecord/test/cases/view_test.rb +++ b/activerecord/test/cases/view_test.rb @@ -60,7 +60,7 @@ module ViewBehavior end def test_attributes - assert_equal({"id" => 2, "name" => "Ruby for Rails", "status" => 0}, + assert_equal({ "id" => 2, "name" => "Ruby for Rails", "status" => 0 }, Ebook.first.attributes) end @@ -78,139 +78,139 @@ module ViewBehavior end if ActiveRecord::Base.connection.supports_views? -class ViewWithPrimaryKeyTest < ActiveRecord::TestCase - include ViewBehavior + class ViewWithPrimaryKeyTest < ActiveRecord::TestCase + include ViewBehavior - private - def create_view(name, query) - @connection.execute "CREATE VIEW #{name} AS #{query}" - end - - def drop_view(name) - @connection.execute "DROP VIEW #{name}" if @connection.view_exists? name - end -end - -class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase - include SchemaDumpingHelper - fixtures :books - - class Paperback < ActiveRecord::Base; end - - setup do - @connection = ActiveRecord::Base.connection - @connection.execute <<-SQL - CREATE VIEW paperbacks - AS SELECT name, status FROM books WHERE format = 'paperback' - SQL - end - - teardown do - @connection.execute "DROP VIEW paperbacks" if @connection.view_exists? "paperbacks" - end - - def test_reading - books = Paperback.all - assert_equal ["Agile Web Development with Rails"], books.map(&:name) - end + private + def create_view(name, query) + @connection.execute "CREATE VIEW #{name} AS #{query}" + end - def test_views - assert_equal [Paperback.table_name], @connection.views - end - - def test_view_exists - view_name = Paperback.table_name - assert @connection.view_exists?(view_name), "'#{view_name}' view should exist" + def drop_view(name) + @connection.execute "DROP VIEW #{name}" if @connection.view_exists? name + end end - def test_table_exists - view_name = Paperback.table_name - # TODO: switch this assertion around once we changed #tables to not return views. - ActiveSupport::Deprecation.silence { assert @connection.table_exists?(view_name), "'#{view_name}' table should exist" } - end + class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase + include SchemaDumpingHelper + fixtures :books - def test_column_definitions - assert_equal([["name", :string], - ["status", :integer]], Paperback.columns.map { |c| [c.name, c.type] }) - end + class Paperback < ActiveRecord::Base; end - def test_attributes - assert_equal({"name" => "Agile Web Development with Rails", "status" => 2}, - Paperback.first.attributes) - end + setup do + @connection = ActiveRecord::Base.connection + @connection.execute <<-SQL + CREATE VIEW paperbacks + AS SELECT name, status FROM books WHERE format = 'paperback' + SQL + end - def test_does_not_have_a_primary_key - assert_nil Paperback.primary_key - end + teardown do + @connection.execute "DROP VIEW paperbacks" if @connection.view_exists? "paperbacks" + end - def test_does_not_dump_view_as_table - schema = dump_table_schema "paperbacks" - assert_no_match %r{create_table "paperbacks"}, schema - end -end + def test_reading + books = Paperback.all + assert_equal ["Agile Web Development with Rails"], books.map(&:name) + end -# sqlite dose not support CREATE, INSERT, and DELETE for VIEW -if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter) -class UpdateableViewTest < ActiveRecord::TestCase - self.use_transactional_tests = false - fixtures :books + def test_views + assert_equal [Paperback.table_name], @connection.views + end - class PrintedBook < ActiveRecord::Base - self.primary_key = "id" - end + def test_view_exists + view_name = Paperback.table_name + assert @connection.view_exists?(view_name), "'#{view_name}' view should exist" + end - setup do - @connection = ActiveRecord::Base.connection - @connection.execute <<-SQL - CREATE VIEW printed_books - AS SELECT id, name, status, format FROM books WHERE format = 'paperback' - SQL - end + def test_table_exists + view_name = Paperback.table_name + # TODO: switch this assertion around once we changed #tables to not return views. + ActiveSupport::Deprecation.silence { assert @connection.table_exists?(view_name), "'#{view_name}' table should exist" } + end - teardown do - @connection.execute "DROP VIEW printed_books" if @connection.view_exists? "printed_books" - end + def test_column_definitions + assert_equal([["name", :string], + ["status", :integer]], Paperback.columns.map { |c| [c.name, c.type] }) + end - def test_update_record - book = PrintedBook.first - book.name = "AWDwR" - book.save! - book.reload - assert_equal "AWDwR", book.name - end + def test_attributes + assert_equal({ "name" => "Agile Web Development with Rails", "status" => 2 }, + Paperback.first.attributes) + end - def test_insert_record - PrintedBook.create! name: "Rails in Action", status: 0, format: "paperback" + def test_does_not_have_a_primary_key + assert_nil Paperback.primary_key + end - new_book = PrintedBook.last - assert_equal "Rails in Action", new_book.name + def test_does_not_dump_view_as_table + schema = dump_table_schema "paperbacks" + assert_no_match %r{create_table "paperbacks"}, schema + end end - def test_update_record_to_fail_view_conditions - book = PrintedBook.first - book.format = "ebook" - book.save! - - assert_raises ActiveRecord::RecordNotFound do - book.reload + # sqlite dose not support CREATE, INSERT, and DELETE for VIEW + if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter) + class UpdateableViewTest < ActiveRecord::TestCase + self.use_transactional_tests = false + fixtures :books + + class PrintedBook < ActiveRecord::Base + self.primary_key = "id" + end + + setup do + @connection = ActiveRecord::Base.connection + @connection.execute <<-SQL + CREATE VIEW printed_books + AS SELECT id, name, status, format FROM books WHERE format = 'paperback' + SQL + end + + teardown do + @connection.execute "DROP VIEW printed_books" if @connection.view_exists? "printed_books" + end + + def test_update_record + book = PrintedBook.first + book.name = "AWDwR" + book.save! + book.reload + assert_equal "AWDwR", book.name + end + + def test_insert_record + PrintedBook.create! name: "Rails in Action", status: 0, format: "paperback" + + new_book = PrintedBook.last + assert_equal "Rails in Action", new_book.name + end + + def test_update_record_to_fail_view_conditions + book = PrintedBook.first + book.format = "ebook" + book.save! + + assert_raises ActiveRecord::RecordNotFound do + book.reload + end + end end - end -end -end # end fo `if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)` + end # end fo `if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter)` end # end fo `if ActiveRecord::Base.connection.supports_views?` if ActiveRecord::Base.connection.respond_to?(:supports_materialized_views?) && ActiveRecord::Base.connection.supports_materialized_views? -class MaterializedViewTest < ActiveRecord::PostgreSQLTestCase - include ViewBehavior + class MaterializedViewTest < ActiveRecord::PostgreSQLTestCase + include ViewBehavior - private - def create_view(name, query) - @connection.execute "CREATE MATERIALIZED VIEW #{name} AS #{query}" - end + private + def create_view(name, query) + @connection.execute "CREATE MATERIALIZED VIEW #{name} AS #{query}" + end - def drop_view(name) - @connection.execute "DROP MATERIALIZED VIEW #{name}" if @connection.view_exists? name + def drop_view(name) + @connection.execute "DROP MATERIALIZED VIEW #{name}" if @connection.view_exists? name + end end end -end diff --git a/activerecord/test/cases/yaml_serialization_test.rb b/activerecord/test/cases/yaml_serialization_test.rb index 56909a8630..5192e5050a 100644 --- a/activerecord/test/cases/yaml_serialization_test.rb +++ b/activerecord/test/cases/yaml_serialization_test.rb @@ -1,15 +1,15 @@ -require 'cases/helper' -require 'models/topic' -require 'models/reply' -require 'models/post' -require 'models/author' +require "cases/helper" +require "models/topic" +require "models/reply" +require "models/post" +require "models/author" class YamlSerializationTest < ActiveRecord::TestCase fixtures :topics, :authors, :posts def test_to_yaml_with_time_with_zone_should_not_raise_exception with_timezone_config aware_attributes: true, zone: "Pacific Time (US & Canada)" do - topic = Topic.new(:written_on => DateTime.now) + topic = Topic.new(written_on: DateTime.now) assert_nothing_raised { topic.to_yaml } end end @@ -22,8 +22,8 @@ class YamlSerializationTest < ActiveRecord::TestCase end def test_roundtrip_serialized_column - topic = Topic.new(:content => {:omg=>:lol}) - assert_equal({:omg=>:lol}, YAML.load(YAML.dump(topic)).content) + topic = Topic.new(content: { omg: :lol }) + assert_equal({ omg: :lol }, YAML.load(YAML.dump(topic)).content) end def test_psych_roundtrip @@ -67,16 +67,16 @@ class YamlSerializationTest < ActiveRecord::TestCase assert_not topic.new_record?, "Saved records are not new" assert_not YAML.load(YAML.dump(topic)).new_record?, "Saved record should not be new after deserialization" - topic = Topic.select('title').last + topic = Topic.select("title").last assert_not topic.new_record?, "Loaded records without ID are not new" assert_not YAML.load(YAML.dump(topic)).new_record?, "Record should not be new after deserialization" end def test_types_of_virtual_columns_are_not_changed_on_round_trip - author = Author.select('authors.*, count(posts.id) as posts_count') + author = Author.select("authors.*, count(posts.id) as posts_count") .joins(:posts) - .group('authors.id') + .group("authors.id") .first dumped = YAML.load(YAML.dump(author)) @@ -88,7 +88,7 @@ class YamlSerializationTest < ActiveRecord::TestCase coder = {} Topic.first.encode_with(coder) - assert coder['active_record_yaml_version'] + assert coder["active_record_yaml_version"] end def test_deserializing_rails_41_yaml @@ -109,13 +109,23 @@ class YamlSerializationTest < ActiveRecord::TestCase assert_equal("Have a nice day", topic.content) end - private + def test_yaml_encoding_keeps_mutations + author = Author.first + author.name = "Sean" + dumped = YAML.load(YAML.dump(author)) - def yaml_fixture(file_name) - path = File.expand_path( - "../../support/yaml_compatibility_fixtures/#{file_name}.yml", - __FILE__ - ) - File.read(path) + assert_equal "Sean", dumped.name + assert_equal author.name_was, dumped.name_was + assert_equal author.changes, dumped.changes end + + private + + def yaml_fixture(file_name) + path = File.expand_path( + "../../support/yaml_compatibility_fixtures/#{file_name}.yml", + __FILE__ + ) + File.read(path) + end end |