From 0aad463cfbe9853fd3a7ab0f8e4e0a34715fd62c Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Thu, 5 Dec 2013 12:20:03 -0500 Subject: `find_in_batches` now returns an `Enumerator` when called without a block, so that it can be chained with other `Enumerable` methods. --- activerecord/test/cases/batches_test.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 38c2560d69..3b94d46710 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -170,4 +170,17 @@ class EachTest < ActiveRecord::TestCase end end end + + def test_find_in_batches_should_return_an_enumerator + enum = nil + assert_queries(0) do + enum = Post.find_in_batches(:batch_size => 1) + end + assert_queries(4) do + enum.first(4) do |batch| + assert_kind_of Array, batch + assert_kind_of Post, batch.first + end + end + end end -- cgit v1.2.3 From a099d7d97f80236185f1994a76a4366b2a5e21ab Mon Sep 17 00:00:00 2001 From: Jonathan Baudanza Date: Sun, 12 Jan 2014 17:53:16 -0500 Subject: psql implementation of #index_name_exists? --- activerecord/test/cases/adapters/postgresql/schema_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index e8dd188ec8..c67997c5a1 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -240,6 +240,18 @@ class SchemaTest < ActiveRecord::TestCase assert_nothing_raised { with_schema_search_path nil } end + def test_index_name_exists + with_schema_search_path(SCHEMA_NAME) do + assert @connection.index_name_exists?(TABLE_NAME, INDEX_A_NAME, true) + assert @connection.index_name_exists?(TABLE_NAME, INDEX_B_NAME, true) + assert @connection.index_name_exists?(TABLE_NAME, INDEX_C_NAME, true) + 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) + end + end + def test_dump_indexes_for_schema_one do_dump_index_tests_for_schema(SCHEMA_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S1, INDEX_D_COLUMN, INDEX_E_COLUMN) end -- cgit v1.2.3 From 0e9144dcecb1a21627ec66ca3578308c43368ee9 Mon Sep 17 00:00:00 2001 From: Anna Carey Date: Fri, 17 Jan 2014 16:49:10 -0500 Subject: set encoding to binmode for pipe --- activerecord/test/cases/base_test.rb | 2 ++ activerecord/test/cases/connection_management_test.rb | 2 ++ 2 files changed, 4 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 983bcd9826..ef1ebbb400 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1380,6 +1380,8 @@ class BasicsTest < ActiveRecord::TestCase }) rd, wr = IO.pipe + rd.binmode + wr.binmode ActiveRecord::Base.connection_handler.clear_all_connections! diff --git a/activerecord/test/cases/connection_management_test.rb b/activerecord/test/cases/connection_management_test.rb index 00667cc52e..77d9ae9b8e 100644 --- a/activerecord/test/cases/connection_management_test.rb +++ b/activerecord/test/cases/connection_management_test.rb @@ -31,6 +31,8 @@ module ActiveRecord object_id = ActiveRecord::Base.connection.object_id rd, wr = IO.pipe + rd.binmode + wr.binmode pid = fork { rd.close -- cgit v1.2.3 From 7386ffc781fca07a0c656db49fdb54678caef809 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Sat, 18 Jan 2014 04:36:45 -0800 Subject: Restore ActiveRecord states after a rollback for models w/o callbacks This fixes a regression (#13744) that was caused by 67d8bb9. In 67d8bb9, we introduced lazy rollback for records, such that the record's internal states and attributes are not restored immediately after a transaction rollback, but deferred until they are first accessed. This optimization is only performed when the model does not have any transactional callbacks (e.g. `after_commit` and `after_create`). Unfortunately, the models used to test the affected codepaths all comes with some sort of transactional callbacks. Therefore this codepath remains largely untested until now and as a result there are a few issues in the implementation that remains hidden until now. First, the `sync_with_transaction_state` (or more accurately, `update_attributes_from_transaction_state`) would perform the synchronization prematurely before a transaction is finalized (i.e. comitted or rolled back). As a result, when the actuall rollback happens, the record will incorrectly assumes that its internal states match the transaction state, and neglect to perform the restore. Second, `update_attributes_from_transaction_state` calls `committed!` in some cases. This in turns checks for the `destroyed?` state which also requires synchronization with the transaction stae, which causes an infnite recurrsion. This fix works by deferring the synchronization until the transaction has been finalized (addressing the first point), and also unrolled the `committed!` and `rolledback!` logic in-place (addressing the second point). It should be noted that the primary purpose of the `committed!` and `rolledback!` methods are to trigger the relevant transactional callbacks. Since this code path is only entered when there are no transactional callbacks on the model, this shouldn't be necessary. By unrolling the method calls, the intention here (to restore the states when necessary) becomes more clear. --- activerecord/test/cases/transactions_test.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index 89dab16975..1664f1a096 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -430,17 +430,26 @@ class TransactionTest < ActiveRecord::TestCase end def test_restore_active_record_state_for_all_records_in_a_transaction + topic_without_callbacks = Class.new(ActiveRecord::Base) do + 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.transaction do assert topic_1.save assert topic_2.save + assert topic_3.save @first.save @second.destroy assert topic_1.persisted?, 'persisted' assert_not_nil topic_1.id assert topic_2.persisted?, 'persisted' assert_not_nil topic_2.id + assert topic_3.persisted?, 'persisted' + assert_not_nil topic_3.id assert @first.persisted?, 'persisted' assert_not_nil @first.id assert @second.destroyed?, 'destroyed' @@ -451,6 +460,8 @@ class TransactionTest < ActiveRecord::TestCase assert_nil topic_1.id assert !topic_2.persisted?, 'not persisted' assert_nil topic_2.id + assert !topic_3.persisted?, 'not persisted' + assert_nil topic_3.id assert @first.persisted?, 'persisted' assert_not_nil @first.id assert !@second.destroyed?, 'not destroyed' -- cgit v1.2.3 From cafe31a078276dbf941bd8b30f0caddc878c0830 Mon Sep 17 00:00:00 2001 From: Jason Meller Date: Sat, 18 Jan 2014 00:51:34 -0500 Subject: Ensure #second acts like #first AR finder This commit bring the famous ordinal Array instance methods defined in ActiveSupport into ActiveRecord as fully-fledged finders. These finders ensure a default ascending order of the table's primary key, and utilize the OFFSET SQL verb to locate the user's desired record. If an offset is defined in the query, calling #second adds to the offset to get the actual desired record. Fixes #13743. --- activerecord/test/cases/base_test.rb | 2 +- activerecord/test/cases/calculations_test.rb | 18 +++-- activerecord/test/cases/finder_test.rb | 90 +++++++++++++++++++++- activerecord/test/cases/relations_test.rb | 24 +++--- .../test/cases/scoping/named_scoping_test.rb | 8 +- activerecord/test/fixtures/topics.yml | 7 ++ 6 files changed, 123 insertions(+), 26 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index ef1ebbb400..8a0b0b9589 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -321,7 +321,7 @@ class BasicsTest < ActiveRecord::TestCase def test_load topics = Topic.all.merge!(:order => 'id').to_a - assert_equal(4, topics.size) + assert_equal(5, topics.size) assert_equal(topics(:first).title, topics.first.title) end diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 2f6913167d..0bc81ffe56 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -466,14 +466,14 @@ class CalculationsTest < ActiveRecord::TestCase def test_distinct_is_honored_when_used_with_count_operation_after_group # Count the number of authors for approved topics approved_topics_count = Topic.group(:approved).count(:author_name)[true] - assert_equal approved_topics_count, 3 + assert_equal approved_topics_count, 4 # Count the number of distinct authors for approved Topics distinct_authors_for_approved_count = Topic.group(:approved).distinct.count(:author_name)[true] - assert_equal distinct_authors_for_approved_count, 2 + assert_equal distinct_authors_for_approved_count, 3 end def test_pluck - assert_equal [1,2,3,4], Topic.order(:id).pluck(:id) + assert_equal [1,2,3,4,5], Topic.order(:id).pluck(:id) end def test_pluck_without_column_names @@ -509,7 +509,7 @@ class CalculationsTest < ActiveRecord::TestCase end def test_pluck_with_qualified_column_name - assert_equal [1,2,3,4], Topic.order(:id).pluck("topics.id") + assert_equal [1,2,3,4,5], Topic.order(:id).pluck("topics.id") end def test_pluck_auto_table_name_prefix @@ -557,11 +557,13 @@ class CalculationsTest < ActiveRecord::TestCase def test_pluck_multiple_columns assert_equal [ [1, "The First Topic"], [2, "The Second Topic of the day"], - [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"] + [3, "The Third Topic of the day"], [4, "The Fourth Topic of the day"], + [5, "The Fifth Topic of the day"] ], Topic.order(:id).pluck(:id, :title) assert_equal [ [1, "The First Topic", "David"], [2, "The Second Topic of the day", "Mary"], - [3, "The Third Topic of the day", "Carl"], [4, "The Fourth Topic of the day", "Carl"] + [3, "The Third Topic of the day", "Carl"], [4, "The Fourth Topic of the day", "Carl"], + [5, "The Fifth Topic of the day", "Jason"] ], Topic.order(:id).pluck(:id, :title, :author_name) end @@ -587,7 +589,7 @@ class CalculationsTest < ActiveRecord::TestCase def test_pluck_replaces_select_clause taks_relation = Topic.select(:approved, :id).order(:id) - assert_equal [1,2,3,4], taks_relation.pluck(:id) - assert_equal [false, true, true, true], taks_relation.pluck(:approved) + assert_equal [1,2,3,4,5], taks_relation.pluck(:id) + assert_equal [false, true, true, true, true], taks_relation.pluck(:approved) end end diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 9b575557de..9cd1e0ace8 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -254,6 +254,94 @@ class FinderTest < ActiveRecord::TestCase end end + def test_second + assert_equal topics(:second).title, Topic.second.title + end + + def test_second_with_offset + assert_equal topics(:fifth), Topic.offset(3).second + end + + def test_second_have_primary_key_order_by_default + expected = topics(:second) + expected.touch # PostgreSQL changes the default order if no order clause is used + assert_equal expected, Topic.second + end + + def test_model_class_responds_to_second_bang + assert Topic.second! + Topic.delete_all + assert_raises ActiveRecord::RecordNotFound do + Topic.second! + end + end + + def test_third + assert_equal topics(:third).title, Topic.third.title + end + + def test_third_with_offset + assert_equal topics(:fifth), Topic.offset(2).third + end + + def test_third_have_primary_key_order_by_default + expected = topics(:third) + expected.touch # PostgreSQL changes the default order if no order clause is used + assert_equal expected, Topic.third + end + + def test_model_class_responds_to_third_bang + assert Topic.third! + Topic.delete_all + assert_raises ActiveRecord::RecordNotFound do + Topic.third! + end + end + + def test_fourth + assert_equal topics(:fourth).title, Topic.fourth.title + end + + def test_fourth_with_offset + assert_equal topics(:fifth), Topic.offset(1).fourth + end + + def test_fourth_have_primary_key_order_by_default + expected = topics(:fourth) + expected.touch # PostgreSQL changes the default order if no order clause is used + assert_equal expected, Topic.fourth + end + + def test_model_class_responds_to_fourth_bang + assert Topic.fourth! + Topic.delete_all + assert_raises ActiveRecord::RecordNotFound do + Topic.fourth! + end + end + + def test_fifth + assert_equal topics(:fifth).title, Topic.fifth.title + end + + def test_fifth_with_offset + assert_equal topics(:fifth), Topic.offset(0).fifth + end + + def test_fifth_have_primary_key_order_by_default + expected = topics(:fifth) + expected.touch # PostgreSQL changes the default order if no order clause is used + assert_equal expected, Topic.fifth + end + + def test_model_class_responds_to_fifth_bang + assert Topic.fifth! + Topic.delete_all + assert_raises ActiveRecord::RecordNotFound do + Topic.fifth! + end + end + def test_last_bang_present assert_nothing_raised do assert_equal topics(:second), Topic.where("title = 'The Second Topic of the day'").last! @@ -267,7 +355,7 @@ class FinderTest < ActiveRecord::TestCase end def test_model_class_responds_to_last_bang - assert_equal topics(:fourth), Topic.last! + assert_equal topics(:fifth), Topic.last! assert_raises ActiveRecord::RecordNotFound do Topic.delete_all Topic.last! diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index afd5a69cef..9227c2b72f 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -65,7 +65,7 @@ class RelationTest < ActiveRecord::TestCase def test_scoped topics = Topic.all assert_kind_of ActiveRecord::Relation, topics - assert_equal 4, topics.size + assert_equal 5, topics.size end def test_to_json @@ -86,14 +86,14 @@ class RelationTest < ActiveRecord::TestCase def test_scoped_all topics = Topic.all.to_a assert_kind_of Array, topics - assert_no_queries { assert_equal 4, topics.size } + assert_no_queries { assert_equal 5, topics.size } end def test_loaded_all topics = Topic.all assert_queries(1) do - 2.times { assert_equal 4, topics.to_a.size } + 2.times { assert_equal 5, topics.to_a.size } end assert topics.loaded? @@ -164,27 +164,27 @@ class RelationTest < ActiveRecord::TestCase def test_finding_with_order topics = Topic.order('id') - assert_equal 4, topics.to_a.size + assert_equal 5, topics.to_a.size assert_equal topics(:first).title, topics.first.title end def test_finding_with_arel_order topics = Topic.order(Topic.arel_table[:id].asc) - assert_equal 4, topics.to_a.size + assert_equal 5, topics.to_a.size assert_equal topics(:first).title, topics.first.title end def test_finding_with_assoc_order topics = Topic.order(:id => :desc) - assert_equal 4, topics.to_a.size - assert_equal topics(:fourth).title, topics.first.title + 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 - assert_equal 4, topics.to_a.size - assert_equal topics(:fourth).title, topics.first.title + assert_equal 5, topics.to_a.size + assert_equal topics(:fifth).title, topics.first.title end def test_order_with_hash_and_symbol_generates_the_same_sql @@ -197,19 +197,19 @@ class RelationTest < ActiveRecord::TestCase def test_finding_last_with_arel_order topics = Topic.order(Topic.arel_table[:id].asc) - assert_equal topics(:fourth).title, topics.last.title + assert_equal topics(:fifth).title, topics.last.title end def test_finding_with_order_concatenated topics = Topic.order('author_name').order('title') - assert_equal 4, topics.to_a.size + assert_equal 5, topics.to_a.size assert_equal topics(:fourth).title, topics.first.title end def test_finding_with_reorder topics = Topic.order('author_name').order('title').reorder('id').to_a topics_titles = topics.map{ |t| t.title } - assert_equal ['The First Topic', 'The Second Topic of the day', 'The Third Topic of the day', 'The Fourth 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_order_and_take diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb index 72c9787b84..086977d9a2 100644 --- a/activerecord/test/cases/scoping/named_scoping_test.rb +++ b/activerecord/test/cases/scoping/named_scoping_test.rb @@ -344,13 +344,13 @@ class NamedScopingTest < ActiveRecord::TestCase end def test_scopes_batch_finders - assert_equal 3, Topic.approved.count + assert_equal 4, Topic.approved.count - assert_queries(4) do + assert_queries(5) do Topic.approved.find_each(:batch_size => 1) {|t| assert t.approved? } end - assert_queries(2) do + assert_queries(3) do Topic.approved.find_in_batches(:batch_size => 2) do |group| group.each {|t| assert t.approved? } end @@ -366,7 +366,7 @@ class NamedScopingTest < ActiveRecord::TestCase def test_scopes_on_relations # Topic.replied approved_topics = Topic.all.approved.order('id DESC') - assert_equal topics(:fourth), approved_topics.first + assert_equal topics(:fifth), approved_topics.first replied_approved_topics = approved_topics.replied assert_equal topics(:third), replied_approved_topics.first diff --git a/activerecord/test/fixtures/topics.yml b/activerecord/test/fixtures/topics.yml index 2b042bd135..bf049abbf1 100644 --- a/activerecord/test/fixtures/topics.yml +++ b/activerecord/test/fixtures/topics.yml @@ -40,3 +40,10 @@ fourth: type: Reply parent_id: 3 +fifth: + id: 5 + title: The Fifth Topic of the day + author_name: Jason + written_on: 2013-07-13t12:11:00.0099+01:00 + content: Omakase + approved: true -- cgit v1.2.3 From 691709dd6741757e5c4459c8942857ee019b68a0 Mon Sep 17 00:00:00 2001 From: Alexander Balashov Date: Thu, 28 Mar 2013 16:03:02 +0400 Subject: Fail early with "Primary key not included in the custom select clause" in find_in_batches Before this patch find_in_batches raises this error only on second iteration. So you will know about the problem only when you get the batch size threshold. --- activerecord/test/cases/batches_test.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 38c2560d69..ebb36e4940 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -46,7 +46,9 @@ class EachTest < ActiveRecord::TestCase def test_each_should_raise_if_select_is_set_without_id assert_raise(RuntimeError) do - Post.select(:title).find_each(:batch_size => 1) { |post| post } + Post.select(:title).find_each(batch_size: 1) { |post| + flunk "should not call this block" + } end end -- cgit v1.2.3 From a57a2bcf4a2c29519d553277e4439790ca443cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 20 Jan 2014 21:59:20 -0200 Subject: Make enum feature work with dirty methods To make this possible we have to override the save_changed_attribute hook. --- activerecord/test/cases/enum_test.rb | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 1f98801e93..0fe7dfe4ea 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -51,6 +51,46 @@ class EnumTest < ActiveRecord::TestCase assert @book.written? end + test "enum changed attributes" do + old_status = @book.status + @book.status = :published + assert_equal old_status, @book.changed_attributes[:status] + end + + test "enum changes" do + old_status = @book.status + @book.status = :published + assert_equal [old_status, 'published'], @book.changes[:status] + end + + test "enum attribute was" do + old_status = @book.status + @book.status = :published + assert_equal old_status, @book.attribute_was(:status) + end + + test "enum attribute changed" do + @book.status = :published + assert @book.attribute_changed?(:status) + end + + test "enum attribute changed to" do + @book.status = :published + assert @book.attribute_changed?(:status, to: 'published') + end + + test "enum attribute changed from" do + old_status = @book.status + @book.status = :published + assert @book.attribute_changed?(:status, from: old_status) + end + + test "enum attribute changed from old status to new status" do + old_status = @book.status + @book.status = :published + assert @book.attribute_changed?(:status, from: old_status, to: 'published') + end + test "assign non existing value raises an error" do e = assert_raises(ArgumentError) do @book.status = :unknown -- cgit v1.2.3 From a0520fceff9148ebfbb2e09745ba1416bceef2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Mon, 20 Jan 2014 23:10:48 -0200 Subject: Add more tests for the dirty feature for enums --- activerecord/test/cases/enum_test.rb | 32 ++++++++++++++++++++++++++++++++ activerecord/test/models/book.rb | 1 + activerecord/test/schema/schema.rb | 1 + 3 files changed, 34 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 0fe7dfe4ea..9fbfebcca2 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -91,6 +91,38 @@ class EnumTest < ActiveRecord::TestCase assert @book.attribute_changed?(:status, from: old_status, to: 'published') end + test "enum didn't change" do + old_status = @book.status + @book.status = old_status + assert_not @book.attribute_changed?(:status) + end + + test "persist changes that are dirty" do + old_status = @book.status + @book.status = :published + assert @book.attribute_changed?(:status) + @book.status = :written + assert @book.attribute_changed?(:status) + end + + test "reverted changes that are not dirty" do + old_status = @book.status + @book.status = :published + assert @book.attribute_changed?(:status) + @book.status = old_status + assert_not @book.attribute_changed?(:status) + end + + test "reverted changes are not dirty going from nil to value and back" do + book = Book.create!(nullable_status: nil) + + book.nullable_status = :married + assert book.attribute_changed?(:nullable_status) + + book.nullable_status = nil + assert_not book.attribute_changed?(:nullable_status) + end + test "assign non existing value raises an error" do e = assert_raises(ArgumentError) do @book.status = :unknown diff --git a/activerecord/test/models/book.rb b/activerecord/test/models/book.rb index 4cb2c7606b..2170018068 100644 --- a/activerecord/test/models/book.rb +++ b/activerecord/test/models/book.rb @@ -9,6 +9,7 @@ class Book < ActiveRecord::Base enum status: [:proposed, :written, :published] enum read_status: {unread: 0, reading: 2, read: 3} + enum nullable_status: [:single, :married] def published! super diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 9a7d918a25..99a53434f6 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -97,6 +97,7 @@ ActiveRecord::Schema.define do t.column :name, :string t.column :status, :integer, default: 0 t.column :read_status, :integer, default: 0 + t.column :nullable_status, :integer end create_table :booleans, force: true do |t| -- cgit v1.2.3 From e011258c30b61f30e40fb2d9b2f58eb1f700dfd5 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Tue, 21 Jan 2014 17:17:13 +0100 Subject: prepend table name for `Relation#select` columns. This fixes a bug where `select(:id)` combined with `joins()` raised: ``` ActiveRecord::StatementInvalid: SQLite3::SQLException: ambiguous column name: id: SELECT id, authors.author_address_id FROM "posts" INNER JOIN "authors" ON "authors"."id" = "posts"."author_id" ORDER BY posts.id LIMIT 3 ``` The `select_values` are still String and Symbols because other parts (mainly calculations.rb) rely on that fact. /cc @tenderlove --- activerecord/test/cases/relations_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 9227c2b72f..e874c93110 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -1505,6 +1505,12 @@ class RelationTest < ActiveRecord::TestCase end end + test "joins with select" do + posts = Post.joins(:author).select("id", "authors.author_address_id").order("posts.id").limit(3) + assert_equal [1, 2, 4], posts.map(&:id) + assert_equal [1, 1, 1], posts.map(&:author_address_id) + end + test "delegations do not leak to other classes" do Topic.all.by_lifo assert Topic.all.class.method_defined?(:by_lifo) -- cgit v1.2.3 From b0a8ef140e4cc95fa5d3888699fd3d72fd720172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 21 Jan 2014 14:33:16 -0200 Subject: `has_one` and `belongs_to` accessors don't add ORDER BY to the queries anymore. Since Rails 4.0, we add an ORDER BY in the `first` method to ensure consistent results among different database engines. But for singular associations this behavior is not needed since we will have one record to return. As this ORDER BY option can lead some performance issues we are removing it for singular associations accessors. Fixes #12623. --- .../test/cases/associations/belongs_to_associations_test.rb | 7 +++++++ activerecord/test/cases/associations/has_one_associations_test.rb | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 3205d0c28b..2283ba66db 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -28,6 +28,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal companies(:first_firm).name, firm.name end + def test_belongs_to_does_not_use_order_by + 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' + end + def test_belongs_to_with_primary_key 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 diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index 5a41461edf..d4edef03d6 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -22,6 +22,13 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit end + def test_has_one_does_not_use_order_by + 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' + end + def test_has_one_cache_nils firm = companies(:another_firm) assert_queries(1) { assert_nil firm.account } -- cgit v1.2.3 From 03855e790de2224519f55382e3c32118be31eeff Mon Sep 17 00:00:00 2001 From: Jason Meller Date: Tue, 21 Jan 2014 17:34:39 -0500 Subject: Ensure AR #second, #third, etc. finders work through associations This commit fixes two regressions introduced in cafe31a078 where newly created finder methods #second, #third, #forth, and #fifth caused a NoMethodError error on reload associations and where we were pulling the wrong element out of cached associations. Examples: some_book.authors.reload.second # Before # => NoMethodError: undefined method 'first' for nil:NilClass # After # => # some_book.first.authors.first some_book.first.authors.second # Before # => # # => # # After # => # # => # Fixes #13783. --- .../associations/has_many_associations_test.rb | 151 ++++++++++++--------- .../test/cases/autosave_association_test.rb | 10 +- activerecord/test/cases/calculations_test.rb | 4 +- activerecord/test/cases/finder_test.rb | 4 +- activerecord/test/cases/inheritance_test.rb | 4 +- activerecord/test/fixtures/companies.yml | 8 ++ 6 files changed, 109 insertions(+), 72 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index e45efb0161..9fdace8ac1 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -215,6 +215,31 @@ class HasManyAssociationsTest < ActiveRecord::TestCase 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.last() bulbs.last({}) @@ -242,11 +267,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase # 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 2, 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 2, 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 @@ -254,7 +279,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_counting_with_column_name_and_hash - assert_equal 2, 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 @@ -264,17 +289,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_finding - assert_equal 2, 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 2, 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 assert_equal 1, companies(:first_firm).limited_clients.size assert_equal 1, companies(:first_firm).limited_clients.to_a.size - assert_equal 2, companies(:first_firm).limited_clients.limit(nil).to_a.size + assert_equal 3, companies(:first_firm).limited_clients.limit(nil).to_a.size end def test_find_should_append_to_association_order @@ -283,8 +308,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_dynamic_find_should_respect_association_order - assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.where("type = 'Client'").first - assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client') + 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') end def test_cant_save_has_many_readonly_association @@ -297,7 +322,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_finding_with_different_class_name_and_order - assert_equal "Microsoft", 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 @@ -355,7 +380,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_find_all firm = Firm.all.merge!(:order => "id").first - assert_equal 2, firm.clients.where("#{QUOTED_TYPE} = 'Client'").to_a.length + assert_equal 3, firm.clients.where("#{QUOTED_TYPE} = 'Client'").to_a.length assert_equal 1, firm.clients.where("name = 'Summit'").to_a.length end @@ -364,7 +389,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert ! firm.clients.loaded? - assert_queries(3) do + assert_queries(4) do firm.clients.find_each(:batch_size => 1) {|c| assert_equal firm.id, c.firm_id } end @@ -434,15 +459,15 @@ class HasManyAssociationsTest < ActiveRecord::TestCase 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 - assert_equal 2, all_clients_of_firm1.size + assert_equal 3, all_clients_of_firm1.size assert_equal 1, grouped_clients_of_firm1.size end def test_find_scoped_grouped assert_equal 1, companies(:first_firm).clients_grouped_by_firm_id.size assert_equal 1, companies(:first_firm).clients_grouped_by_firm_id.length - assert_equal 2, companies(:first_firm).clients_grouped_by_name.size - assert_equal 2, companies(:first_firm).clients_grouped_by_name.length + assert_equal 3, companies(:first_firm).clients_grouped_by_name.size + assert_equal 3, companies(:first_firm).clients_grouped_by_name.length end def test_find_scoped_grouped_having @@ -470,17 +495,17 @@ class HasManyAssociationsTest < ActiveRecord::TestCase force_signal37_to_load_all_clients_of_firm natural = Client.new("name" => "Natural Company") companies(:first_firm).clients_of_firm << natural - assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection - assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db + assert_equal 3, companies(:first_firm).clients_of_firm.size # checking via the collection + assert_equal 3, companies(:first_firm).clients_of_firm(true).size # checking using the db assert_equal natural, companies(:first_firm).clients_of_firm.last end def test_adding_using_create first_firm = companies(:first_firm) - assert_equal 2, first_firm.plain_clients.size - first_firm.plain_clients.create(:name => "Natural Company") - assert_equal 3, first_firm.plain_clients.length assert_equal 3, first_firm.plain_clients.size + 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 def test_create_with_bang_on_has_many_when_parent_is_new_raises @@ -519,8 +544,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_adding_a_collection force_signal37_to_load_all_clients_of_firm companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")]) - assert_equal 3, companies(:first_firm).clients_of_firm.size - assert_equal 3, companies(:first_firm).clients_of_firm(true).size + assert_equal 4, companies(:first_firm).clients_of_firm.size + assert_equal 4, companies(:first_firm).clients_of_firm(true).size end def test_transactions_when_adding_to_persisted @@ -573,7 +598,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase company = companies(:first_firm) # company already has one client company.clients_of_firm.build("name" => "Another Client") company.clients_of_firm.build("name" => "Yet Another Client") - assert_equal 3, company.clients_of_firm.size + assert_equal 4, company.clients_of_firm.size end def test_collection_not_empty_after_building @@ -649,14 +674,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase Firm.column_names Client.column_names - assert_equal 1, first_firm.clients_of_firm.size + assert_equal 2, first_firm.clients_of_firm.size first_firm.clients_of_firm.reset assert_queries(1) do first_firm.clients_of_firm.create(:name => "Superstars") end - assert_equal 2, first_firm.clients_of_firm.size + assert_equal 3, first_firm.clients_of_firm.size end def test_create @@ -669,7 +694,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_create_many companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}]) - assert_equal 3, companies(:first_firm).clients_of_firm(true).size + assert_equal 4, companies(:first_firm).clients_of_firm(true).size end def test_create_followed_by_save_does_not_load_target @@ -681,8 +706,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_deleting force_signal37_to_load_all_clients_of_firm companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first) - assert_equal 0, companies(:first_firm).clients_of_firm.size - assert_equal 0, companies(:first_firm).clients_of_firm(true).size + assert_equal 1, companies(:first_firm).clients_of_firm.size + assert_equal 1, companies(:first_firm).clients_of_firm(true).size end def test_deleting_before_save @@ -779,8 +804,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_deleting_a_collection force_signal37_to_load_all_clients_of_firm companies(:first_firm).clients_of_firm.create("name" => "Another Client") - assert_equal 2, 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]]) + 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]]) assert_equal 0, companies(:first_firm).clients_of_firm.size assert_equal 0, companies(:first_firm).clients_of_firm(true).size end @@ -789,7 +814,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase force_signal37_to_load_all_clients_of_firm companies(:first_firm).dependent_clients_of_firm.create("name" => "Another Client") clients = companies(:first_firm).dependent_clients_of_firm.to_a - assert_equal 2, clients.count + assert_equal 3, clients.count assert_difference "Client.count", -(clients.count) do companies(:first_firm).dependent_clients_of_firm.delete_all @@ -799,7 +824,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_delete_all_with_not_yet_loaded_association_collection force_signal37_to_load_all_clients_of_firm companies(:first_firm).clients_of_firm.create("name" => "Another Client") - assert_equal 2, companies(:first_firm).clients_of_firm.size + assert_equal 3, companies(:first_firm).clients_of_firm.size companies(:first_firm).clients_of_firm.reset companies(:first_firm).clients_of_firm.delete_all assert_equal 0, companies(:first_firm).clients_of_firm.size @@ -832,7 +857,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_clearing_an_association_collection firm = companies(:first_firm) client_id = firm.clients_of_firm.first.id - assert_equal 1, firm.clients_of_firm.size + assert_equal 2, firm.clients_of_firm.size firm.clients_of_firm.clear @@ -866,7 +891,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_clearing_a_dependent_association_collection firm = companies(:first_firm) client_id = firm.dependent_clients_of_firm.first.id - assert_equal 1, firm.dependent_clients_of_firm.size + assert_equal 2, firm.dependent_clients_of_firm.size assert_equal 1, Client.find_by_id(client_id).client_of # :delete_all is called on each client since the dependent options is :destroy @@ -897,7 +922,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_clearing_an_exclusively_dependent_association_collection firm = companies(:first_firm) client_id = firm.exclusively_dependent_clients_of_firm.first.id - assert_equal 1, firm.exclusively_dependent_clients_of_firm.size + assert_equal 2, firm.exclusively_dependent_clients_of_firm.size assert_equal [], Client.destroyed_client_ids[firm.id] @@ -953,10 +978,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_delete_all_association_with_primary_key_deletes_correct_records firm = Firm.first # break the vanilla firm_id foreign key - assert_equal 2, firm.clients.count + assert_equal 3, firm.clients.count firm.clients.first.update_columns(firm_id: nil) - assert_equal 1, firm.clients(true).count - assert_equal 1, firm.clients_using_primary_key_with_delete_all.count + assert_equal 2, firm.clients(true).count + assert_equal 2, firm.clients_using_primary_key_with_delete_all.count old_record = firm.clients_using_primary_key_with_delete_all.first firm = Firm.first firm.destroy @@ -988,8 +1013,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase force_signal37_to_load_all_clients_of_firm summit = Client.find_by_name('Summit') companies(:first_firm).clients_of_firm.delete(summit) - assert_equal 1, companies(:first_firm).clients_of_firm.size - assert_equal 1, companies(:first_firm).clients_of_firm(true).size + assert_equal 2, companies(:first_firm).clients_of_firm.size + assert_equal 2, companies(:first_firm).clients_of_firm(true).size assert_equal 2, summit.client_of end @@ -1026,8 +1051,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first) end - assert_equal 0, companies(:first_firm).reload.clients_of_firm.size - assert_equal 0, companies(:first_firm).clients_of_firm(true).size + assert_equal 1, companies(:first_firm).reload.clients_of_firm.size + assert_equal 1, companies(:first_firm).clients_of_firm(true).size end def test_destroying_by_fixnum_id @@ -1037,8 +1062,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first.id) end - assert_equal 0, companies(:first_firm).reload.clients_of_firm.size - assert_equal 0, companies(:first_firm).clients_of_firm(true).size + assert_equal 1, companies(:first_firm).reload.clients_of_firm.size + assert_equal 1, companies(:first_firm).clients_of_firm(true).size end def test_destroying_by_string_id @@ -1048,21 +1073,21 @@ class HasManyAssociationsTest < ActiveRecord::TestCase companies(:first_firm).clients_of_firm.destroy(companies(:first_firm).clients_of_firm.first.id.to_s) end - assert_equal 0, companies(:first_firm).reload.clients_of_firm.size - assert_equal 0, companies(:first_firm).clients_of_firm(true).size + assert_equal 1, companies(:first_firm).reload.clients_of_firm.size + assert_equal 1, companies(:first_firm).clients_of_firm(true).size end def test_destroying_a_collection force_signal37_to_load_all_clients_of_firm companies(:first_firm).clients_of_firm.create("name" => "Another Client") - assert_equal 2, companies(:first_firm).clients_of_firm.size + assert_equal 3, companies(:first_firm).clients_of_firm.size assert_difference "Client.count", -2 do companies(:first_firm).clients_of_firm.destroy([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]]) end - assert_equal 0, companies(:first_firm).reload.clients_of_firm.size - assert_equal 0, companies(:first_firm).clients_of_firm(true).size + assert_equal 1, companies(:first_firm).reload.clients_of_firm.size + assert_equal 1, companies(:first_firm).clients_of_firm(true).size end def test_destroy_all @@ -1078,7 +1103,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_dependence firm = companies(:first_firm) - assert_equal 2, firm.clients.size + assert_equal 3, firm.clients.size firm.destroy assert Client.all.merge!(:where => "firm_id=#{firm.id}").to_a.empty? end @@ -1091,14 +1116,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase 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 - assert_equal 2, firm.clients.size + assert_equal 3, firm.clients.size client = firm.clients.first firm.clients.delete(client) assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) } assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) } - assert_equal 1, firm.clients.size + assert_equal 2, firm.clients.size end def test_three_levels_of_dependence @@ -1113,12 +1138,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_dependence_with_transaction_support_on_failure firm = companies(:first_firm) clients = firm.clients - assert_equal 2, clients.length + assert_equal 3, clients.length clients.last.instance_eval { def overwrite_to_raise() raise "Trigger rollback" end } firm.destroy rescue "do nothing" - assert_equal 2, 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 @@ -1239,7 +1264,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_get_ids - assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids + assert_equal [companies(:first_client).id, companies(:second_client).id, companies(:another_first_firm_client).id], companies(:first_firm).client_ids end def test_get_ids_for_loaded_associations @@ -1254,7 +1279,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_get_ids_for_unloaded_associations_does_not_load_them company = companies(:first_firm) assert !company.clients.loaded? - assert_equal [companies(:first_client).id, companies(:second_client).id], company.client_ids + assert_equal [companies(:first_client).id, companies(:second_client).id, companies(:another_first_firm_client).id], company.client_ids assert !company.clients.loaded? end @@ -1263,7 +1288,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end def test_get_ids_for_ordered_association - assert_equal [companies(:second_client).id, companies(:first_client).id], companies(:first_firm).clients_ordered_by_name_ids + assert_equal [companies(:another_first_firm_client).id, companies(:second_client).id, companies(:first_client).id], companies(:first_firm).clients_ordered_by_name_ids end def test_get_ids_for_association_on_new_record_does_not_try_to_find_records @@ -1357,9 +1382,10 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal false, firm.clients.include?(client) end - def test_calling_first_or_last_on_association_should_not_load_association + def test_calling_first_nth_or_last_on_association_should_not_load_association firm = companies(:first_firm) firm.clients.first + firm.clients.second firm.clients.last assert !firm.clients.loaded? end @@ -1384,30 +1410,33 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_queries 1 do firm.clients.first + firm.clients.second firm.clients.last end assert firm.clients.loaded? end - def test_calling_first_or_last_on_existing_record_with_create_should_not_load_association + 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') assert !firm.clients.loaded? - assert_queries 2 do + assert_queries 3 do firm.clients.first + firm.clients.second firm.clients.last end assert !firm.clients.loaded? end - def test_calling_first_or_last_on_new_record_should_not_run_queries + def test_calling_first_nth_or_last_on_new_record_should_not_run_queries firm = Firm.new assert_no_queries do firm.clients.first + firm.clients.second firm.clients.last end end @@ -1494,7 +1523,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase def test_calling_many_should_return_true_if_more_than_one firm = companies(:first_firm) assert firm.clients.many? - assert_equal 2, firm.clients.size + assert_equal 3, firm.clients.size end def test_joins_with_namespaced_model_should_use_correct_type diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index fe5de44409..703f805188 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -401,7 +401,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa assert_equal new_client, companies(:first_firm).clients_of_firm.last assert !companies(:first_firm).save assert !new_client.persisted? - assert_equal 1, companies(:first_firm).clients_of_firm(true).size + assert_equal 2, companies(:first_firm).clients_of_firm(true).size end def test_adding_before_save @@ -455,7 +455,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa company.name += '-changed' assert_queries(2) { assert company.save } assert new_client.persisted? - assert_equal 2, company.clients_of_firm(true).size + assert_equal 3, company.clients_of_firm(true).size end def test_build_many_before_save @@ -464,7 +464,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa company.name += '-changed' assert_queries(3) { assert company.save } - assert_equal 3, company.clients_of_firm(true).size + assert_equal 4, company.clients_of_firm(true).size end def test_build_via_block_before_save @@ -475,7 +475,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa company.name += '-changed' assert_queries(2) { assert company.save } assert new_client.persisted? - assert_equal 2, company.clients_of_firm(true).size + assert_equal 3, company.clients_of_firm(true).size end def test_build_many_via_block_before_save @@ -488,7 +488,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa company.name += '-changed' assert_queries(3) { assert company.save } - assert_equal 3, company.clients_of_firm(true).size + assert_equal 4, company.clients_of_firm(true).size end def test_replace_on_new_object diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 0bc81ffe56..db999f90ab 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -278,7 +278,7 @@ class CalculationsTest < ActiveRecord::TestCase c = Company.group("UPPER(#{QUOTED_TYPE})").count(:all) assert_equal 2, c[nil] assert_equal 1, c['DEPENDENTFIRM'] - assert_equal 4, c['CLIENT'] + assert_equal 5, c['CLIENT'] assert_equal 2, c['FIRM'] end @@ -286,7 +286,7 @@ class CalculationsTest < ActiveRecord::TestCase c = Company.group("UPPER(companies.#{QUOTED_TYPE})").count(:all) assert_equal 2, c[nil] assert_equal 1, c['DEPENDENTFIRM'] - assert_equal 4, c['CLIENT'] + assert_equal 5, c['CLIENT'] assert_equal 2, c['FIRM'] end diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 9cd1e0ace8..47c2217161 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -900,8 +900,8 @@ class FinderTest < ActiveRecord::TestCase end def test_select_values - assert_equal ["1","2","3","4","5","6","7","8","9", "10"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s } - assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy", "Ex Nihilo Part Deux"], Company.connection.select_values("SELECT name FROM companies ORDER BY id") + assert_equal ["1","2","3","4","5","6","7","8","9", "10", "11"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s } + assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy", "Ex Nihilo Part Deux", "Apex"], Company.connection.select_values("SELECT name FROM companies ORDER BY id") end def test_select_rows diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index d2b5a06b55..e2ff2aa451 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -222,9 +222,9 @@ class InheritanceTest < ActiveRecord::TestCase end def test_inheritance_condition - assert_equal 10, Company.count + assert_equal 11, Company.count assert_equal 2, Firm.count - assert_equal 4, Client.count + assert_equal 5, Client.count end def test_alt_inheritance_condition diff --git a/activerecord/test/fixtures/companies.yml b/activerecord/test/fixtures/companies.yml index 0766e92027..ab9d5378ad 100644 --- a/activerecord/test/fixtures/companies.yml +++ b/activerecord/test/fixtures/companies.yml @@ -57,3 +57,11 @@ odegy: id: 9 name: Odegy type: ExclusivelyDependentFirm + +another_first_firm_client: + id: 11 + type: Client + firm_id: 1 + client_of: 1 + name: Apex + firm_name: 37signals -- cgit v1.2.3 From 43675f014c8d0913650823a5a3e92c8555a3caed Mon Sep 17 00:00:00 2001 From: Kelsey Schlarman Date: Tue, 21 Jan 2014 18:19:51 -0800 Subject: Calling reset on a collection association should unload the assocation Need to define #reset on CollectionProxy. --- activerecord/test/cases/associations_test.rb | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 48e6fc5cd4..f663b5490c 100644 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -255,6 +255,15 @@ class AssociationProxyTest < ActiveRecord::TestCase assert_equal man, man.interests.where("1=1").first.man end end + + def test_reset_unloads_target + david = authors(:david) + david.posts.reload + + assert david.posts.loaded? + david.posts.reset + assert !david.posts.loaded? + end end class OverridingAssociationsTest < ActiveRecord::TestCase -- cgit v1.2.3 From 9b254df181373578a0d78dbf8ae14d55b65289c1 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Fri, 24 Jan 2014 12:14:02 +0530 Subject: Remove unused assignment to fix warnings in enum test. --- activerecord/test/cases/enum_test.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 9fbfebcca2..8719f45e76 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -98,7 +98,6 @@ class EnumTest < ActiveRecord::TestCase end test "persist changes that are dirty" do - old_status = @book.status @book.status = :published assert @book.attribute_changed?(:status) @book.status = :written -- cgit v1.2.3 From 3a0ddf33945219ea65777c1813902d783245739d Mon Sep 17 00:00:00 2001 From: Kuldeep Aggarwal Date: Sat, 25 Jan 2014 02:29:23 +0530 Subject: Fix `ActiveRecord::RecordNotFound` error message with custom primary key --- activerecord/test/cases/finder_test.rb | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 47c2217161..b1eded6494 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -951,14 +951,23 @@ class FinderTest < ActiveRecord::TestCase end def test_find_one_message_with_custom_primary_key - Toy.primary_key = :name - begin - Toy.find 'Hello World!' - rescue ActiveRecord::RecordNotFound => e - assert_equal 'Couldn\'t find Toy with name=Hello World!', e.message + table_with_custom_primary_key do |model| + model.primary_key = :name + e = assert_raises(ActiveRecord::RecordNotFound) do + model.find 'Hello World!' + end + assert_equal %Q{Couldn't find MercedesCar with 'name'=Hello World!}, e.message + end + end + + def test_find_some_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!' + end + assert_equal %Q{Couldn't find all MercedesCars with 'name': (Hello, World!) (found 0 results, but was looking for 2)}, e.message end - ensure - Toy.reset_primary_key end def test_find_without_primary_key @@ -979,4 +988,12 @@ class FinderTest < ActiveRecord::TestCase ActiveRecord::Base.send(:replace_bind_variables, statement, vars) end end + + def table_with_custom_primary_key + yield(Class.new(Toy) do + def self.name + 'MercedesCar' + end + end) + end end -- cgit v1.2.3 From 20317f3d4df3ef0e876b5b213551f0d7d81d0c19 Mon Sep 17 00:00:00 2001 From: Kuldeep Aggarwal Date: Tue, 28 Jan 2014 00:13:35 +0530 Subject: use the new clear_validators! api everywhere to reset validators in tests --- activerecord/test/cases/persistence_test.rb | 4 ++-- .../test/cases/validations/i18n_generate_message_validation_test.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 6f1e518f45..b9f0624f76 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -740,7 +740,7 @@ class PersistenceTest < ActiveRecord::TestCase assert_raise(ActiveRecord::RecordInvalid) { reply.update!(title: nil, content: "Have a nice evening") } ensure - Reply.reset_callbacks(:validate) + Reply.clear_validators! end def test_update_attributes! @@ -761,7 +761,7 @@ class PersistenceTest < ActiveRecord::TestCase assert_raise(ActiveRecord::RecordInvalid) { reply.update_attributes!(title: nil, content: "Have a nice evening") } ensure - Reply.reset_callbacks(:validate) + Reply.clear_validators! end def test_destroyed_returns_boolean 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 a73c3bf1af..13d4d85afa 100644 --- a/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb +++ b/activerecord/test/cases/validations/i18n_generate_message_validation_test.rb @@ -3,7 +3,7 @@ require 'models/topic' class I18nGenerateMessageValidationTest < ActiveRecord::TestCase def setup - Topic.reset_callbacks(:validate) + Topic.clear_validators! @topic = Topic.new I18n.backend = I18n::Backend::Simple.new end -- cgit v1.2.3 From b9cd5a29dd4c6142b19c861fbf1a67452320b3dd Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Tue, 28 Jan 2014 08:16:20 -0200 Subject: Fix indent on test case [ci skip] --- activerecord/test/cases/associations/has_many_associations_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 9fdace8ac1..cf1e50890e 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -487,9 +487,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal [1], posts(:welcome).comments.select { |c| c.id == 1 }.map(&:id) end - def test_select_without_foreign_key + def test_select_without_foreign_key assert_equal companies(:first_firm).accounts.first.credit_limit, companies(:first_firm).accounts.select(:credit_limit).first.credit_limit - end + end def test_adding force_signal37_to_load_all_clients_of_firm -- cgit v1.2.3 From c1d99344476e1046a609f64776621542b399c929 Mon Sep 17 00:00:00 2001 From: Tsutomu Kuroda Date: Fri, 9 Aug 2013 23:46:27 +0900 Subject: Handle aliased attributes in AR::Relation#select, #order, etc. With this we can write `Model#select(:aliased)`, `Model#order(:aliased)`, `Model#reoder(aliased: :desc)`, etc. Supplementary work to 54122067acaad39b277a5363c6d11d6804c7bf6b. --- activerecord/test/cases/relation/mutation_test.rb | 4 +++ activerecord/test/cases/relations_test.rb | 31 +++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/relation/mutation_test.rb b/activerecord/test/cases/relation/mutation_test.rb index 7cb2a19bee..4fafa668fb 100644 --- a/activerecord/test/cases/relation/mutation_test.rb +++ b/activerecord/test/cases/relation/mutation_test.rb @@ -14,6 +14,10 @@ module ActiveRecord def relation_delegate_class(klass) self.class.relation_delegate_class(klass) end + + def attribute_alias?(name) + false + end end def relation diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index e874c93110..e390d37871 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -206,12 +206,36 @@ class RelationTest < ActiveRecord::TestCase assert_equal topics(:fourth).title, topics.first.title end + def test_finding_with_order_by_aliased_attributes + topics = Topic.order(:heading) + assert_equal 5, topics.to_a.size + assert_equal topics(:fifth).title, topics.first.title + end + + def test_finding_with_assoc_order_by_aliased_attributes + topics = Topic.order(heading: :desc) + assert_equal 5, topics.to_a.size + assert_equal topics(:third).title, topics.first.title + end + def test_finding_with_reorder topics = Topic.order('author_name').order('title').reorder('id').to_a topics_titles = topics.map{ |t| t.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 end + def test_finding_with_reorder_by_aliased_attributes + 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) + assert_equal 5, topics.to_a.size + assert_equal topics(:third).title, topics.first.title + end + def test_finding_with_order_and_take entrants = Entrant.order("id ASC").limit(2).to_a @@ -775,6 +799,13 @@ class RelationTest < ActiveRecord::TestCase assert_equal david.salary, developer.salary end + def test_select_takes_an_aliased_attribute + first = topics(:first) + + topic = Topic.where(id: first.id).select(:heading).first + assert_equal first.heading, topic.heading + end + def test_select_argument_error assert_raises(ArgumentError) { Developer.select } end -- cgit v1.2.3 From 66e533f9b13f2ea1f56a19246af55621cc368489 Mon Sep 17 00:00:00 2001 From: Mauricio Linhares Date: Wed, 29 Jan 2014 01:56:20 -0300 Subject: Correctly send the string given to lock! and reload(:lock) to the lock scope - fixes #13788 As per the documentation at lock!, if the :lock option is a string it should use the given SQL to generate the lock statement. --- activerecord/test/cases/locking_test.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index a16ed963fe..c373dc1511 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -431,6 +431,17 @@ unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db? assert_equal old, person.reload.first_name end + if current_adapter?(:PostgreSQLAdapter) + def test_lock_sending_custom_lock_statement + Person.transaction do + person = Person.find(1) + assert_sql(/LIMIT 1 FOR SHARE NOWAIT/) do + person.lock!('FOR SHARE NOWAIT') + end + end + end + end + if current_adapter?(:PostgreSQLAdapter, :OracleAdapter) def test_no_locks_no_wait first, second = duel { Person.find 1 } -- cgit v1.2.3 From 9ed66648b59b160b43c83c349263e8cb97eaa088 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Fri, 24 Jan 2014 18:05:33 -0800 Subject: Fixed a bug in AR::Base#respond_to? Before: >> ActiveRecord::Base.respond_to?(:find_by_something) NoMethodError: undefined method `abstract_class?' for Object:Class After: >> ActiveRecord::Base.respond_to?(:find_by_something) => false --- activerecord/test/cases/finder_respond_to_test.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/finder_respond_to_test.rb b/activerecord/test/cases/finder_respond_to_test.rb index 3ff22f222f..6ab2657c44 100644 --- a/activerecord/test/cases/finder_respond_to_test.rb +++ b/activerecord/test/cases/finder_respond_to_test.rb @@ -5,6 +5,11 @@ class FinderRespondToTest < ActiveRecord::TestCase fixtures :topics + def test_should_preserve_normal_respond_to_behaviour_on_base + assert_respond_to ActiveRecord::Base, :new + assert !ActiveRecord::Base.respond_to?(:find_by_something) + 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) { } assert_respond_to Topic, :method_added_for_finder_respond_to_test -- cgit v1.2.3 From 7e8e91c439c1a877f867cd7ba634f7297ccef04b Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Fri, 24 Jan 2014 18:28:05 -0800 Subject: `scope` now raises on "dangerous" name conflicts Similar to dangerous attribute methods, a scope name conflict is dangerous if it conflicts with an existing class method defined within `ActiveRecord::Base` but not its ancestors. See also #13389. *Godfrey Chan*, *Philippe Creux* --- .../test/cases/scoping/named_scoping_test.rb | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb index 086977d9a2..9dc26cfd4d 100644 --- a/activerecord/test/cases/scoping/named_scoping_test.rb +++ b/activerecord/test/cases/scoping/named_scoping_test.rb @@ -266,6 +266,63 @@ class NamedScopingTest < ActiveRecord::TestCase assert_equal 'lifo', topic.author_name end + def test_reserved_scope_names + klass = Class.new(ActiveRecord::Base) do + self.table_name = "topics" + + scope :approved, -> { where(approved: true) } + + class << self + public + def pub; end + + private + def pri; end + + protected + def pro; end + end + end + + subklass = Class.new(klass) + + conflicts = [ + :create, # public class method on AR::Base + :relation, # private class method on AR::Base + :new, # redefined class method on AR::Base + :all, # a default scope + ] + + non_conflicts = [ + :find_by_title, # dynamic finder method + :approved, # existing scope + :pub, # existing public class method + :pri, # existing private class method + :pro, # existing protected class method + :open, # a ::Kernel method + ] + + conflicts.each do |name| + assert_raises(ArgumentError, "scope `#{name}` should not be allowed") do + klass.class_eval { scope name, ->{ where(approved: true) } } + end + + assert_raises(ArgumentError, "scope `#{name}` should not be allowed") do + subklass.class_eval { scope name, ->{ where(approved: true) } } + end + end + + non_conflicts.each do |name| + assert_nothing_raised do + klass.class_eval { scope name, ->{ where(approved: true) } } + end + + assert_nothing_raised do + subklass.class_eval { scope name, ->{ where(approved: true) } } + end + end + end + # Method delegation for scope names which look like /\A[a-zA-Z_]\w*[!?]?\z/ # has been done by evaluating a string with a plain def statement. For scope # names which contain spaces this approach doesn't work. -- cgit v1.2.3 From 40f0257e05d8735d94684043ea7be7295fbbae57 Mon Sep 17 00:00:00 2001 From: Godfrey Chan Date: Mon, 27 Jan 2014 01:39:52 -0800 Subject: `enum` now raises on "dangerous" name conflicts Dangerous name conflicts includes instance or class method conflicts with methods defined within `ActiveRecord::Base` but not its ancestors, as well as conflicts with methods generated by other enums on the same class. Fixes #13389. --- activerecord/test/cases/enum_test.rb | 59 ++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 8719f45e76..5cac630a3a 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -163,4 +163,63 @@ class EnumTest < ActiveRecord::TestCase test "_before_type_cast returns the enum label (required for form fields)" do assert_equal "proposed", @book.status_before_type_cast end + + test "reserved enum names" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = "books" + enum status: [:proposed, :written, :published] + end + + conflicts = [ + :column, # generates class method .columns, which conflicts with an AR method + :logger, # generates #logger, which conflicts with an AR method + :attributes, # generates #attributes=, which conflicts with an AR method + ] + + conflicts.each_with_index do |name, i| + assert_raises(ArgumentError, "enum name `#{name}` should not be allowed") do + klass.class_eval { enum name => ["value_#{i}"] } + end + end + end + + test "reserved enum values" do + klass = Class.new(ActiveRecord::Base) do + self.table_name = "books" + enum status: [:proposed, :written, :published] + end + + conflicts = [ + :new, # generates a scope that conflicts with an AR class method + :valid, # generates #valid?, which conflicts with an AR method + :save, # generates #save!, which conflicts with an AR method + :proposed, # same value as an existing enum + ] + + conflicts.each_with_index do |value, i| + assert_raises(ArgumentError, "enum value `#{value}` should not be allowed") do + klass.class_eval { enum "status_#{i}" => [value] } + end + end + end + + test "overriding enum method should not raise" do + assert_nothing_raised do + klass = Class.new(ActiveRecord::Base) do + self.table_name = "books" + + def published! + super + "do publish work..." + end + + enum status: [:proposed, :written, :published] + + def written! + super + "do written work..." + end + end + end + end end -- cgit v1.2.3 From c9346322b15c15f51234c33a3db1b3895ffe84ab Mon Sep 17 00:00:00 2001 From: Mauricio Linhares Date: Wed, 29 Jan 2014 00:54:13 -0300 Subject: Fixing issue with activerecord serialization not being able to dump a record after loading it from YAML - fixes #13861 --- activerecord/test/cases/store_test.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb index 6f632b4d8d..e24df6abe9 100644 --- a/activerecord/test/cases/store_test.rb +++ b/activerecord/test/cases/store_test.rb @@ -166,4 +166,27 @@ class StoreTest < ActiveRecord::TestCase test "YAML coder initializes the store when a Nil value is given" do assert_equal({}, @john.params) end + + test "attributes_for_coder should return stored fields already serialized" do + attributes = { + "id" => @john.id, + "name"=> @john.name, + "settings" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ncolor: black\n", + "preferences" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nremember_login: true\n", + "json_data" => "{\"height\":\"tall\"}", "json_data_empty"=>"{\"is_a_good_guy\":true}", + "params" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess {}\n", + "account_id"=> @john.account_id } + assert_equal attributes, @john.attributes_for_coder + end + + test "dump, load and dump again a model" do + dumped = YAML.dump( @john ) + loaded = YAML.load( dumped ) + assert_equal @john, loaded + + second_dump = YAML.dump( loaded ) + assert_equal dumped, second_dump + assert_equal @john, YAML.load( second_dump ) + end + end -- cgit v1.2.3 From 5977e7e4d534463c53af1acef960bccade8c8ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 29 Jan 2014 20:48:43 -0200 Subject: Aesthetic --- activerecord/test/cases/store_test.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/store_test.rb b/activerecord/test/cases/store_test.rb index e24df6abe9..978cee9cfb 100644 --- a/activerecord/test/cases/store_test.rb +++ b/activerecord/test/cases/store_test.rb @@ -175,18 +175,19 @@ class StoreTest < ActiveRecord::TestCase "preferences" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nremember_login: true\n", "json_data" => "{\"height\":\"tall\"}", "json_data_empty"=>"{\"is_a_good_guy\":true}", "params" => "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess {}\n", - "account_id"=> @john.account_id } + "account_id"=> @john.account_id + } + assert_equal attributes, @john.attributes_for_coder end test "dump, load and dump again a model" do - dumped = YAML.dump( @john ) - loaded = YAML.load( dumped ) + dumped = YAML.dump(@john) + loaded = YAML.load(dumped) assert_equal @john, loaded - second_dump = YAML.dump( loaded ) + second_dump = YAML.dump(loaded) assert_equal dumped, second_dump - assert_equal @john, YAML.load( second_dump ) + assert_equal @john, YAML.load(second_dump) end - end -- cgit v1.2.3 From 642106e277334e75ff1ae8d8a03f5fef37cf0671 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Wed, 29 Jan 2014 15:02:13 -0500 Subject: find_in_batches should not mutate its argument --- activerecord/test/cases/batches_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 1161b57514..8216d74cb3 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -153,6 +153,12 @@ class EachTest < ActiveRecord::TestCase assert_equal special_posts_ids, posts.map(&:id) end + def test_find_in_batches_should_not_modify_passed_options + assert_nothing_raised do + 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') start_nick = nick_order_subscribers.second.nick -- cgit v1.2.3 From 7abb6e00c0f1d6cc98b10b0e7620dfb9786449a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Wed, 29 Jan 2014 22:41:30 -0200 Subject: Remove automatic removal of Date/Time stubs after each test case This behavior is only work out-of-box with minitest and also add a downside to run after each test case, even if we don't used the travel or travel_to methods --- activerecord/test/cases/mixin_test.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/mixin_test.rb b/activerecord/test/cases/mixin_test.rb index ad0d5cce27..7ddb2bfee1 100644 --- a/activerecord/test/cases/mixin_test.rb +++ b/activerecord/test/cases/mixin_test.rb @@ -6,10 +6,14 @@ end class TouchTest < ActiveRecord::TestCase fixtures :mixins - def setup + setup do travel_to Time.now end + teardown do + travel_back + end + def test_update stamped = Mixin.new -- cgit v1.2.3 From b7fcad8ff04411a8d00f85094b172b6b99402190 Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Wed, 29 Jan 2014 21:17:10 -0500 Subject: Fix regression on `.select_*` methods. This was a common pattern: ``` query = author.posts.select(:title) connection.select_one(query) ``` However `.select` returns a ActiveRecord::AssociationRelation, which has the bind information, so we can use that to get the right sql query. Also fix select_rows on postgress and sqlite3 that were not using the binds [fixes #7538] [fixes #12017] [related #13731] [related #12056] --- activerecord/test/cases/adapter_test.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index b67e70ec7e..0eb1231c79 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -1,5 +1,7 @@ require "cases/helper" require "models/book" +require "models/post" +require "models/author" module ActiveRecord class AdapterTest < ActiveRecord::TestCase @@ -179,6 +181,27 @@ module ActiveRecord assert result.is_a?(ActiveRecord::Result) 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.select(:title) + assert_equal({"title" => "foo"}, @connection.select_one(query.arel, nil, query.bind_values)) + 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.bind_values)) + 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 + test "type_to_sql returns a String for unmapped types" do assert_equal "special_db_type", @connection.type_to_sql(:special_db_type) end -- cgit v1.2.3 From abc19c37aea561e7b087cee9d60c5698483f3136 Mon Sep 17 00:00:00 2001 From: Washington Luiz Date: Tue, 28 Jan 2014 00:59:11 -0300 Subject: Let `unscope` ignore non Arel scope.where_values --- activerecord/test/cases/scoping/default_scoping_test.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/scoping/default_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb index 71754cf0a2..170e9a49eb 100644 --- a/activerecord/test/cases/scoping/default_scoping_test.rb +++ b/activerecord/test/cases/scoping/default_scoping_test.rb @@ -149,6 +149,16 @@ class DefaultScopingTest < ActiveRecord::TestCase assert_equal expected, received end + def test_unscope_string_where_clauses_involved + dev_relation = Developer.order('salary DESC').where("created_at > ?", 1.year.ago) + expected = dev_relation.collect { |dev| dev.name } + + dev_ordered_relation = DeveloperOrderedBySalary.where(name: 'Jamis').where("created_at > ?", 1.year.ago) + received = dev_ordered_relation.unscope(where: [:name]).collect { |dev| dev.name } + + assert_equal expected, received + end + def test_unscope_with_grouping_attributes expected = Developer.order('salary DESC').collect { |dev| dev.name } received = DeveloperOrderedBySalary.group(:name).unscope(:group).collect { |dev| dev.name } -- cgit v1.2.3 From 4506dd2f07be824fd7e0eb6165c29994aeb1bfcd Mon Sep 17 00:00:00 2001 From: Lauro Caetano Date: Thu, 30 Jan 2014 22:58:00 -0200 Subject: Associations now raise `ArgumentError` on name conflicts. Dangerous association names conflicts include instance or class methods already defined by `ActiveRecord::Base`. --- .../test/cases/associations/belongs_to_associations_test.rb | 10 ++++++++++ .../test/cases/associations/has_many_associations_test.rb | 10 ++++++++++ .../test/cases/associations/has_one_associations_test.rb | 10 ++++++++++ 3 files changed, 30 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 2283ba66db..9340bc0a83 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -853,4 +853,14 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert post.save assert_equal post.author_id, author2.id end + + 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 + end + end + end + 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 cf1e50890e..a86fb15719 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -1820,4 +1820,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase topic.approved_replies.create! end end + + 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 + end + end + end + end end diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index d4edef03d6..a4650ccdf2 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -564,4 +564,14 @@ class HasOneAssociationsTest < ActiveRecord::TestCase end end end + + 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 + end + end + end + end end -- cgit v1.2.3 From 16648979f72e4543cb62cf803dc6c4c6b03715d4 Mon Sep 17 00:00:00 2001 From: Tim Fenney Date: Fri, 31 Jan 2014 00:50:09 -0500 Subject: Remove unused variable. --- activerecord/test/cases/enum_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb index 5cac630a3a..1b95708cb3 100644 --- a/activerecord/test/cases/enum_test.rb +++ b/activerecord/test/cases/enum_test.rb @@ -205,7 +205,7 @@ class EnumTest < ActiveRecord::TestCase test "overriding enum method should not raise" do assert_nothing_raised do - klass = Class.new(ActiveRecord::Base) do + Class.new(ActiveRecord::Base) do self.table_name = "books" def published! -- cgit v1.2.3 From a34c10f73e739142794a2e6366328051fcc91238 Mon Sep 17 00:00:00 2001 From: Mauricio Linhares Date: Sat, 1 Feb 2014 01:11:03 -0300 Subject: Fixes issue with parsing whitespace content back from database - fixes #13907 --- activerecord/test/cases/adapters/postgresql/array_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb index d71e2aa2bb..3090f4478f 100644 --- a/activerecord/test/cases/adapters/postgresql/array_test.rb +++ b/activerecord/test/cases/adapters/postgresql/array_test.rb @@ -93,6 +93,18 @@ class PostgresqlArrayTest < ActiveRecord::TestCase assert_cycle(:tags, [[['1'], ['2']], [['2'], ['3']]]) end + def test_with_empty_strings + assert_cycle(:tags, [ '1', '2', '', '4', '', '5' ]) + end + + def test_with_multi_dimensional_empty_strings + assert_cycle(:tags, [[['1', '2'], ['', '4'], ['', '5']]]) + end + + def test_with_arbitrary_whitespace + assert_cycle(:tags, [[['1', '2'], [' ', '4'], [' ', '5']]]) + end + def test_multi_dimensional_with_integers assert_cycle(:ratings, [[[1], [7]], [[8], [10]]]) end -- cgit v1.2.3 From 682a579b25deb1142b8f445ad9ae0c661bc58564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Sat, 1 Feb 2014 16:27:58 -0200 Subject: Remove warnings for already defined methods --- activerecord/test/cases/scoping/named_scoping_test.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb index 9dc26cfd4d..f0ad9ebb8a 100644 --- a/activerecord/test/cases/scoping/named_scoping_test.rb +++ b/activerecord/test/cases/scoping/named_scoping_test.rb @@ -314,7 +314,9 @@ class NamedScopingTest < ActiveRecord::TestCase non_conflicts.each do |name| assert_nothing_raised do - klass.class_eval { scope name, ->{ where(approved: true) } } + silence_warnings do + klass.class_eval { scope name, ->{ where(approved: true) } } + end end assert_nothing_raised do -- cgit v1.2.3 From 00ebbb79456dccd45d813886d81f1619c0161af4 Mon Sep 17 00:00:00 2001 From: Kevin Casey Date: Sun, 2 Feb 2014 11:47:06 -0800 Subject: fix HABTM w/out primary key errors on destruction --- .../associations/has_and_belongs_to_many_associations_test.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'activerecord/test') 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 8aee7ff40e..bac1cb8e2d 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 @@ -775,6 +775,16 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert project.developers.include?(developer) end + def test_destruction_does_not_error_without_primary_key + redbeard = pirates(:redbeard) + george = parrots(:george) + redbeard.parrots << george + assert_equal 2, george.pirates.count + Pirate.includes(:parrots).where(parrot: redbeard.parrot).find(redbeard.id).destroy + assert_equal 1, george.pirates.count + assert_equal [], Pirate.where(id: redbeard.id) + end + test "has and belongs to many associations on new records use null relations" do projects = Developer.new.projects assert_no_queries do -- cgit v1.2.3 From 584a46479b3cbcac37b948a7fe38fa3acc71c35b Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Mon, 3 Feb 2014 14:48:59 +0100 Subject: pass `habtm :autosave` to underlying `hm:t` association. Closes #13923. --- .../test/cases/autosave_association_test.rb | 33 +++++++++++++++++----- activerecord/test/models/pirate.rb | 1 + 2 files changed, 27 insertions(+), 7 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 703f805188..7a0c335627 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -1183,15 +1183,15 @@ module AutosaveAssociationOnACollectionAssociationTests end def test_should_default_invalid_error_from_i18n - I18n.backend.store_translations(:en, :activerecord => {:errors => { :models => - { @association_name.to_s.singularize.to_sym => { :blank => "cannot be blank" } } + 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"] - assert_equal ["#{@association_name.to_s.titleize} name cannot be blank"], @pirate.errors.full_messages + assert_equal ["#{@association_name.to_s.humanize} name cannot be blank"], @pirate.errors.full_messages assert @pirate.errors[@association_name].empty? ensure I18n.backend = I18n::Backend::Simple.new @@ -1307,6 +1307,7 @@ class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase def setup super @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') @@ -1319,14 +1320,32 @@ end class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::TestCase self.use_transactional_fixtures = false unless supports_savepoints? + def setup + super + @association_name = :autosaved_parrots + @associated_model_name = :parrot + @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') + end + + include AutosaveAssociationOnACollectionAssociationTests +end + +class TestAutosaveAssociationOnAHasAndBelongsToManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase + self.use_transactional_fixtures = false unless supports_savepoints? + def setup super @association_name = :parrots + @associated_model_name = :parrot @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') + @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') end include AutosaveAssociationOnACollectionAssociationTests diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb index 170fc2ffe3..7bb0caf44b 100644 --- a/activerecord/test/models/pirate.rb +++ b/activerecord/test/models/pirate.rb @@ -13,6 +13,7 @@ class Pirate < ActiveRecord::Base :after_add => proc {|p,pa| p.ship_log << "after_adding_proc_parrot_#{pa.id || ''}"}, :before_remove => proc {|p,pa| p.ship_log << "before_removing_proc_parrot_#{pa.id}"}, :after_remove => proc {|p,pa| p.ship_log << "after_removing_proc_parrot_#{pa.id}"} + has_and_belongs_to_many :autosaved_parrots, class_name: "Parrot", autosave: true has_many :treasures, :as => :looter has_many :treasure_estimates, :through => :treasures, :source => :price_estimates -- cgit v1.2.3 From 9b66d6d47f87d31fb360f48542520d9216e77dc9 Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Mon, 3 Feb 2014 15:29:26 -0500 Subject: Make sure transaction state resets after commit [fixes #12566] --- activerecord/test/cases/transaction_callbacks_test.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb index 7e7d95841b..3d64ecb464 100644 --- a/activerecord/test/cases/transaction_callbacks_test.rb +++ b/activerecord/test/cases/transaction_callbacks_test.rb @@ -16,6 +16,11 @@ class TransactionCallbacksTest < ActiveRecord::TestCase after_commit :do_after_commit, on: :create + attr_accessor :save_on_after_create + after_create do + self.save! if save_on_after_create + end + def history @history ||= [] end @@ -107,6 +112,16 @@ class TransactionCallbacksTest < ActiveRecord::TestCase assert_equal [], reply.history end + def test_only_call_after_commit_on_create_and_doesnt_leaky + r = ReplyWithCallbacks.new(content: 'foo') + r.save_on_after_create = true + r.save! + r.content = 'bar' + r.save! + r.save! + assert_equal [:commit_on_create], r.history + end + def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record_on_touch add_transaction_execution_blocks @first -- cgit v1.2.3 From 3ba0eeda02e85c312d2867afc4aa9afea50d93ec Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Wed, 5 Feb 2014 08:52:59 +0100 Subject: docs, AR already auto-detects primary keys. Closes #13946. [ci skip] This behavior was introduced since Rails 3.1 (207f266ccaaa9cd04cd2a7513ae5598c4358b510) but the docs were still out of date. --- activerecord/test/cases/primary_keys_test.rb | 6 +++++- activerecord/test/models/mixed_case_monkey.rb | 2 -- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb index 1b915387be..51ddd406ed 100644 --- a/activerecord/test/cases/primary_keys_test.rb +++ b/activerecord/test/cases/primary_keys_test.rb @@ -180,6 +180,11 @@ class PrimaryKeysTest < ActiveRecord::TestCase assert !col1.equal?(col2) end end + + def test_auto_detect_primary_key_from_schema + MixedCaseMonkey.reset_primary_key + assert_equal "monkeyID", MixedCaseMonkey.primary_key + end end class PrimaryKeyWithNoConnectionTest < ActiveRecord::TestCase @@ -214,4 +219,3 @@ if current_adapter?(:MysqlAdapter, :Mysql2Adapter) end end end - diff --git a/activerecord/test/models/mixed_case_monkey.rb b/activerecord/test/models/mixed_case_monkey.rb index 4d37371777..1c35006665 100644 --- a/activerecord/test/models/mixed_case_monkey.rb +++ b/activerecord/test/models/mixed_case_monkey.rb @@ -1,5 +1,3 @@ class MixedCaseMonkey < ActiveRecord::Base - self.primary_key = 'monkeyID' - belongs_to :man end -- cgit v1.2.3 From 38777949f0796d5bb64e3e7470057b376948873d Mon Sep 17 00:00:00 2001 From: Vajrasky Kok Date: Wed, 5 Feb 2014 16:51:34 +0800 Subject: Fixed typo in column_definition_test.rb. --- activerecord/test/cases/column_definition_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb index dbb2f223cd..c7b64f29c3 100644 --- a/activerecord/test/cases/column_definition_test.rb +++ b/activerecord/test/cases/column_definition_test.rb @@ -82,7 +82,7 @@ module ActiveRecord assert_equal "", not_null_text_column.default end - def test_has_default_should_return_false_for_blog_and_test_data_types + def test_has_default_should_return_false_for_blob_and_text_data_types blob_column = MysqlAdapter::Column.new("title", nil, "blob") assert !blob_column.has_default? @@ -116,7 +116,7 @@ module ActiveRecord assert_equal "", not_null_text_column.default end - def test_has_default_should_return_false_for_blog_and_test_data_types + def test_has_default_should_return_false_for_blob_and_text_data_types blob_column = Mysql2Adapter::Column.new("title", nil, "blob") assert !blob_column.has_default? -- cgit v1.2.3 From 4499ab5fdeca46416cfc4a50a376eba4eb8e16b4 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 4 Feb 2014 01:47:40 -0500 Subject: Strengthen test with different nb of rows and columns --- activerecord/test/cases/result_test.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb index b6c583dbf5..edaeb85211 100644 --- a/activerecord/test/cases/result_test.rb +++ b/activerecord/test/cases/result_test.rb @@ -5,14 +5,16 @@ module ActiveRecord 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 2 col 1', 'row 2 col 2'], + ['row 3 col 1', 'row 3 col 2'], ]) end def test_to_hash_returns_row_hashes 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 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 -- cgit v1.2.3 From d37f395be86d131d0218dadd189771f99b06874f Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Wed, 29 Jan 2014 14:53:54 -0500 Subject: Return sized enumerator from Batches#find_in_batches --- activerecord/test/cases/batches_test.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 8216d74cb3..4ee09a640e 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -191,4 +191,14 @@ class EachTest < ActiveRecord::TestCase end end 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 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 + end + end end -- cgit v1.2.3 From 13d2696c10726afecd393753fcac88c5a9907d8c Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Wed, 29 Jan 2014 15:42:07 -0500 Subject: Return sized enumerator from Batches#find_each --- activerecord/test/cases/batches_test.rb | 8 ++++++++ activerecord/test/cases/result_test.rb | 6 ++++++ 2 files changed, 14 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb index 4ee09a640e..c12fa03015 100644 --- a/activerecord/test/cases/batches_test.rb +++ b/activerecord/test/cases/batches_test.rb @@ -35,6 +35,14 @@ class EachTest < ActiveRecord::TestCase end end + if Enumerator.method_defined? :size + def test_each_should_return_a_sized_enumerator + assert_equal 11, Post.find_each(:batch_size => 1).size + assert_equal 5, Post.find_each(:batch_size => 2, :start => 7).size + assert_equal 11, Post.find_each(:batch_size => 10_000).size + end + end + 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| diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb index edaeb85211..2131b32a0c 100644 --- a/activerecord/test/cases/result_test.rb +++ b/activerecord/test/cases/result_test.rb @@ -30,5 +30,11 @@ module ActiveRecord assert_kind_of Integer, index end end + + if Enumerator.method_defined? :size + def test_each_without_block_returns_a_sized_enumerator + assert_equal 3, result.each.size + end + end end end -- cgit v1.2.3 From 3f90787cd25a45a621fbb7238f69ee96f26e8f74 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Fri, 7 Feb 2014 17:08:09 -0800 Subject: Adjust test value so that timezone has no effect If the test is run in a timezone that is behind UTC it fails because the time generated is ahead of 0000-01-01 00:00:00. Just increase the time subtracted so that timezone has no effect. --- activerecord/test/cases/adapters/postgresql/timestamp_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb index 89210866f0..4d29a20e66 100644 --- a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb +++ b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb @@ -77,7 +77,7 @@ class TimestampTest < ActiveRecord::TestCase end def test_bc_timestamp - date = Date.new(0) - 1.second + date = Date.new(0) - 1.week Developer.create!(:name => "aaron", :updated_at => date) assert_equal date, Developer.find_by_name("aaron").updated_at end -- cgit v1.2.3 From 5e3d466d52fa4e9a42c3a1f8773a7c31da875e48 Mon Sep 17 00:00:00 2001 From: Kevin Casey Date: Sat, 8 Feb 2014 08:44:10 -0800 Subject: context in validation goes through has many relationship --- .../test/cases/associations/has_many_associations_test.rb | 10 ++++++++++ activerecord/test/models/pirate.rb | 8 ++++++++ activerecord/test/models/ship.rb | 8 ++++++++ 3 files changed, 26 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index a86fb15719..321440cab7 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -22,6 +22,8 @@ require 'models/engine' require 'models/categorization' require 'models/minivan' require 'models/speedometer' +require 'models/pirate' +require 'models/ship' class HasManyAssociationsTestForReorderWithJoinDependency < ActiveRecord::TestCase fixtures :authors, :posts, :comments @@ -1830,4 +1832,12 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end end end + + test 'has_many_association passes context validation to validate children' do + pirate = FamousPirate.new + pirate.famous_ships << ship = FamousShip.new + assert_equal true, pirate.valid? + assert_equal false, pirate.valid?(:conference) + assert_equal "can't be blank", ship.errors[:name].first + end end diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb index 7bb0caf44b..8510c596a7 100644 --- a/activerecord/test/models/pirate.rb +++ b/activerecord/test/models/pirate.rb @@ -85,3 +85,11 @@ end class DestructivePirate < Pirate has_one :dependent_ship, :class_name => 'Ship', :foreign_key => :pirate_id, :dependent => :destroy end + +class FamousPirate < ActiveRecord::Base + self.table_name = 'pirates' + + has_many :famous_ships + + validates_presence_of :catchphrase, on: :conference +end diff --git a/activerecord/test/models/ship.rb b/activerecord/test/models/ship.rb index 3da031946f..7a369b9d9a 100644 --- a/activerecord/test/models/ship.rb +++ b/activerecord/test/models/ship.rb @@ -17,3 +17,11 @@ class Ship < ActiveRecord::Base false end end + +class FamousShip < ActiveRecord::Base + self.table_name = 'ships' + + belongs_to :famous_pirate + + validates_presence_of :name, on: :conference +end -- cgit v1.2.3 From 1ea61cb9bc95bf3857012850ffb475836e5d88e8 Mon Sep 17 00:00:00 2001 From: Lauro Caetano Date: Sat, 8 Feb 2014 18:46:32 -0200 Subject: Add test case for autosave HasMany with accepts_nested_attributes. It should not save the parent record when the nested attributes are invalid. Test case to cover #8194. --- .../test/cases/autosave_association_test.rb | 29 ++++++++++++++++++++++ activerecord/test/models/electron.rb | 2 ++ activerecord/test/models/molecule.rb | 2 ++ 3 files changed, 33 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 7a0c335627..c55dd685a1 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -17,6 +17,8 @@ require 'models/tag' require 'models/tagging' require 'models/treasure' require 'models/eye' +require 'models/electron' +require 'models/molecule' class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase def test_should_not_add_the_same_callbacks_multiple_times_for_has_one @@ -343,6 +345,33 @@ class TestDefaultAutosaveAssociationOnABelongsToAssociation < ActiveRecord::Test end end +class TestDefaultAutosaveAssociationOnAHasManyAssociationWithAcceptsNestedAttributes < ActiveRecord::TestCase + def test_invalid_adding_with_nested_attributes + molecule = Molecule.new + valid_electron = Electron.new(name: 'electron') + invalid_electron = Electron.new + + molecule.electrons = [valid_electron, invalid_electron] + molecule.save + + assert_not invalid_electron.valid? + assert valid_electron.valid? + assert_not molecule.persisted?, 'Molecule should not be persisted when its electrons are invalid' + end + + def test_valid_adding_with_nested_attributes + molecule = Molecule.new + valid_electron = Electron.new(name: 'electron') + + molecule.electrons = [valid_electron] + molecule.save + + assert valid_electron.valid? + assert molecule.persisted? + assert_equal 1, molecule.electrons.count + end +end + class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase fixtures :companies, :people diff --git a/activerecord/test/models/electron.rb b/activerecord/test/models/electron.rb index 35af9f679b..6fc270673f 100644 --- a/activerecord/test/models/electron.rb +++ b/activerecord/test/models/electron.rb @@ -1,3 +1,5 @@ class Electron < ActiveRecord::Base belongs_to :molecule + + validates_presence_of :name end diff --git a/activerecord/test/models/molecule.rb b/activerecord/test/models/molecule.rb index 69325b8d29..26870c8f88 100644 --- a/activerecord/test/models/molecule.rb +++ b/activerecord/test/models/molecule.rb @@ -1,4 +1,6 @@ class Molecule < ActiveRecord::Base belongs_to :liquid has_many :electrons + + accepts_nested_attributes_for :electrons end -- cgit v1.2.3 From 28a450d590a03f4b77993b50b24c0abdace460ee Mon Sep 17 00:00:00 2001 From: Mikko Johansson Date: Sun, 9 Feb 2014 02:52:32 +0200 Subject: Skips linked folder tests if symlink is invalid --- activerecord/test/cases/fixtures_test.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb index f3a4887a85..37c6af74da 100644 --- a/activerecord/test/cases/fixtures_test.rb +++ b/activerecord/test/cases/fixtures_test.rb @@ -628,7 +628,9 @@ class LoadAllFixturesTest < ActiveRecord::TestCase self.class.fixture_path = FIXTURES_ROOT + "/all" self.class.fixtures :all - assert_equal %w(admin/accounts admin/users developers people tasks), fixture_table_names.sort + if File.symlink? FIXTURES_ROOT + "/all/admin" + assert_equal %w(admin/accounts admin/users developers people tasks), fixture_table_names.sort + end ensure ActiveRecord::FixtureSet.reset_cache end @@ -639,7 +641,9 @@ class LoadAllFixturesWithPathnameTest < ActiveRecord::TestCase self.class.fixture_path = Pathname.new(FIXTURES_ROOT).join('all') self.class.fixtures :all - assert_equal %w(admin/accounts admin/users developers people tasks), fixture_table_names.sort + if File.symlink? FIXTURES_ROOT + "/all/admin" + assert_equal %w(admin/accounts admin/users developers people tasks), fixture_table_names.sort + end ensure ActiveRecord::FixtureSet.reset_cache end -- cgit v1.2.3 From 02a3c0e771b3e09173412f93d8699d4825a366d6 Mon Sep 17 00:00:00 2001 From: Kevin Casey Date: Sat, 8 Feb 2014 17:38:54 -0800 Subject: Reaper has access to threadsafe active? call --- activerecord/test/cases/connection_pool_test.rb | 2 +- activerecord/test/cases/reaper_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index 2da51ea015..1cf215017b 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -142,7 +142,7 @@ module ActiveRecord connections = @pool.connections.dup connections.each do |conn| - conn.extend(Module.new { def active?; false; end; }) + conn.extend(Module.new { def active_threadsafe?; false; end; }) end @pool.reap diff --git a/activerecord/test/cases/reaper_test.rb b/activerecord/test/cases/reaper_test.rb index e53a27d5dd..b62a41c08e 100644 --- a/activerecord/test/cases/reaper_test.rb +++ b/activerecord/test/cases/reaper_test.rb @@ -69,7 +69,7 @@ module ActiveRecord conn = pool.checkout count = pool.connections.length - conn.extend(Module.new { def active?; false; end; }) + conn.extend(Module.new { def active_threadsafe?; false; end; }) while count == pool.connections.length Thread.pass -- cgit v1.2.3 From ec43584431f61ad56f335033b650a906f44fbf40 Mon Sep 17 00:00:00 2001 From: Dmitry Polushkin Date: Sun, 9 Feb 2014 12:05:42 +0000 Subject: add activerecord test coverage for `sanitize_sql_array` check it is handles empty statement --- activerecord/test/cases/sanitize_test.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/sanitize_test.rb b/activerecord/test/cases/sanitize_test.rb index 766b2ff2ef..954eab8022 100644 --- a/activerecord/test/cases/sanitize_test.rb +++ b/activerecord/test/cases/sanitize_test.rb @@ -46,4 +46,9 @@ class SanitizeTest < ActiveRecord::TestCase 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) + end end -- cgit v1.2.3 From 4b11dcca74da2852249bc156e29af55bf11926ad Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Tue, 11 Feb 2014 13:58:04 +0100 Subject: test case to illustrate current PostgreSQL composite behavior. --- .../cases/adapters/postgresql/composite_test.rb | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 activerecord/test/cases/adapters/postgresql/composite_test.rb (limited to 'activerecord/test') diff --git a/activerecord/test/cases/adapters/postgresql/composite_test.rb b/activerecord/test/cases/adapters/postgresql/composite_test.rb new file mode 100644 index 0000000000..7202cce390 --- /dev/null +++ b/activerecord/test/cases/adapters/postgresql/composite_test.rb @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +require "cases/helper" +require 'active_record/base' +require 'active_record/connection_adapters/postgresql_adapter' + +class PostgresqlCompositeTest < ActiveRecord::TestCase + class PostgresqlComposite < ActiveRecord::Base + self.table_name = "postgresql_composites" + end + + def teardown + @connection.execute 'DROP TABLE IF EXISTS postgresql_composites' + @connection.execute 'DROP TYPE IF EXISTS full_address' + end + + def setup + @connection = ActiveRecord::Base.connection + @connection.transaction do + @connection.execute <<-SQL + CREATE TYPE full_address AS + ( + city VARCHAR(90), + street VARCHAR(90) + ); + SQL + @connection.create_table('postgresql_composites') do |t| + t.column :address, :full_address + end + end + end + + def test_composite_mapping + @connection.execute "INSERT INTO postgresql_composites VALUES (1, ROW('Paris', 'Champs-Élysées'));" + composite = PostgresqlComposite.first + assert_equal "(Paris,Champs-Élysées)", composite.address + + composite.address = "(Paris,Rue Basse)" + composite.save! + + assert_equal '(Paris,"Rue Basse")', composite.reload.address + end +end -- cgit v1.2.3 From 3b645fd3ed60c682b255bf31e7df08cfc6a37321 Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Thu, 19 Dec 2013 01:43:02 +1030 Subject: Terminate the backend ourselves on PG 9.2+ This should make it harder to accidentally break this test. --- .../cases/adapters/postgresql/connection_test.rb | 48 +++++++++++++--------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb index 90cca7d3e6..4715fa002d 100644 --- a/activerecord/test/cases/adapters/postgresql/connection_test.rb +++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb @@ -91,40 +91,50 @@ module ActiveRecord assert_operator plan.length, :>, 0 end - # Must have with_manual_interventions set to true for this - # test to run. + # Must have PostgreSQL >= 9.2, or with_manual_interventions set to + # true for this test to run. + # # When prompted, restart the PostgreSQL server with the # "-m fast" option or kill the individual connection assuming # you know the incantation to do that. # 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" - if ARTest.config['with_manual_interventions'] - def test_reconnection_after_actual_disconnection_with_verify - original_connection_pid = @connection.query('select pg_backend_pid()') + def test_reconnection_after_actual_disconnection_with_verify + original_connection_pid = @connection.query('select pg_backend_pid()') - # Sanity check. - assert @connection.active? + # Sanity check. + assert @connection.active? + if @connection.send(:postgresql_version) >= 90200 + 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 ' + 'server with the "-m fast" option) and then press enter.' $stdin.gets + else + # We're not capable of terminating the backend ourselves, and + # we're not allowed to seek assistance; bail out without + # actually testing anything. + return + end - @connection.verify! + @connection.verify! - assert @connection.active? + assert @connection.active? - # 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()') + # 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()') - assert_not_equal original_connection_pid, new_connection_pid, - "umm -- looks like you didn't break the connection, because we're still " + - "successfully querying with the same connection pid." + assert_not_equal original_connection_pid, new_connection_pid, + "umm -- looks like you didn't break the connection, because we're still " + + "successfully querying with the same connection pid." - # Repair all fixture connections so other tests won't break. - @fixture_connections.each do |c| - c.verify! - end + # Repair all fixture connections so other tests won't break. + @fixture_connections.each do |c| + c.verify! end end -- cgit v1.2.3 From ea3af7ee14217470b019225a03cccced1120f211 Mon Sep 17 00:00:00 2001 From: Yves Senn Date: Thu, 13 Feb 2014 16:45:56 +0100 Subject: tests are responsible to clean up afterwards. remove created state after test execution, not before the next test. This prevents the leak of the `ex` table outside of a single test. --- .../adapters/postgresql/postgresql_adapter_test.rb | 196 ++++++++++++--------- 1 file changed, 114 insertions(+), 82 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb index 131080913c..019406dd84 100644 --- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb +++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb @@ -6,21 +6,21 @@ module ActiveRecord class PostgreSQLAdapterTest < ActiveRecord::TestCase def setup @connection = ActiveRecord::Base.connection - @connection.exec_query('drop table if exists ex') - @connection.exec_query('create table ex(id serial primary key, number integer, data character varying(255))') end def test_bad_connection assert_raise ActiveRecord::NoDatabaseError do configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'should_not_exist-cinco-dog-db') connection = ActiveRecord::Base.postgresql_connection(configuration) - connection.exec_query('drop table if exists ex') + connection.exec_query('SELECT 1') end end def test_valid_column - column = @connection.columns('ex').find { |col| col.name == 'id' } - assert @connection.valid_type?(column.type) + with_example_table do + column = @connection.columns('ex').find { |col| col.name == 'id' } + assert @connection.valid_type?(column.type) + end end def test_invalid_column @@ -28,7 +28,9 @@ module ActiveRecord end def test_primary_key - assert_equal 'id', @connection.primary_key('ex') + with_example_table do + assert_equal 'id', @connection.primary_key('ex') + end end def test_primary_key_works_tables_containing_capital_letters @@ -36,15 +38,15 @@ module ActiveRecord end def test_non_standard_primary_key - @connection.exec_query('drop table if exists ex') - @connection.exec_query('create table ex(data character varying(255) primary key)') - 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 - @connection.exec_query('drop table if exists ex') - @connection.exec_query('create table ex(id integer)') - 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 @@ -54,32 +56,40 @@ module ActiveRecord end def test_insert_sql_with_proprietary_returning_clause - id = @connection.insert_sql("insert into ex (number) values(5150)", nil, "number") - assert_equal "5150", id + with_example_table do + id = @connection.insert_sql("insert into ex (number) values(5150)", nil, "number") + assert_equal "5150", id + end end def test_insert_sql_with_quoted_schema_and_table_name - id = @connection.insert_sql('insert into "public"."ex" (number) values(5150)') - expect = @connection.query('select max(id) from ex').first.first - assert_equal expect, id + with_example_table do + id = @connection.insert_sql('insert into "public"."ex" (number) values(5150)') + expect = @connection.query('select max(id) from ex').first.first + assert_equal expect, id + end end def test_insert_sql_with_no_space_after_table_name - id = @connection.insert_sql("insert into ex(number) values(5150)") - expect = @connection.query('select max(id) from ex').first.first - assert_equal expect, id + with_example_table do + id = @connection.insert_sql("insert into ex(number) values(5150)") + expect = @connection.query('select max(id) from ex').first.first + assert_equal expect, id + end end def test_multiline_insert_sql - id = @connection.insert_sql(<<-SQL) - insert into ex( - number) - values( - 5152 - ) - SQL - expect = @connection.query('select max(id) from ex').first.first - assert_equal expect, id + with_example_table do + id = @connection.insert_sql(<<-SQL) + insert into ex( + number) + values( + 5152 + ) + SQL + expect = @connection.query('select max(id) from ex').first.first + assert_equal expect, id + end end def test_insert_sql_with_returning_disabled @@ -135,29 +145,31 @@ module ActiveRecord end def test_pk_and_sequence_for - pk, seq = @connection.pk_and_sequence_for('ex') - assert_equal 'id', pk - assert_equal @connection.default_sequence_name('ex', 'id'), seq + 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 + end end def test_pk_and_sequence_for_with_non_standard_primary_key - @connection.exec_query('drop table if exists ex') - @connection.exec_query('create table ex(code serial primary key)') - pk, seq = @connection.pk_and_sequence_for('ex') - assert_equal 'code', pk - assert_equal @connection.default_sequence_name('ex', 'code'), seq + 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 + end end def test_pk_and_sequence_for_returns_nil_if_no_seq - @connection.exec_query('drop table if exists ex') - @connection.exec_query('create table ex(id integer primary key)') - 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 - @connection.exec_query('drop table if exists ex') - @connection.exec_query('create table ex(id integer)') - 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 @@ -165,23 +177,27 @@ module ActiveRecord end def test_exec_insert_number - insert(@connection, 'number' => 10) + with_example_table do + insert(@connection, 'number' => 10) - result = @connection.exec_query('SELECT number FROM ex WHERE number = 10') + result = @connection.exec_query('SELECT number FROM ex WHERE number = 10') - assert_equal 1, result.rows.length - assert_equal "10", result.rows.last.last + assert_equal 1, result.rows.length + assert_equal "10", result.rows.last.last + end end def test_exec_insert_string - str = 'いただきます!' - insert(@connection, 'number' => 10, 'data' => str) + with_example_table do + str = 'いただきます!' + insert(@connection, 'number' => 10, 'data' => str) - result = @connection.exec_query('SELECT number, data FROM ex WHERE number = 10') + result = @connection.exec_query('SELECT number, data FROM ex WHERE number = 10') - value = result.rows.last.last + value = result.rows.last.last - assert_equal str, value + assert_equal str, value + end end def test_table_alias_length @@ -191,44 +207,50 @@ module ActiveRecord end def test_exec_no_binds - 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') - @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") - 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 + with_example_table do + 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') + @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") + 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 + end end def test_exec_with_binds - string = @connection.quote('foo') - @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") - result = @connection.exec_query( - 'SELECT id, data FROM ex WHERE id = $1', nil, [[nil, 1]]) + with_example_table do + string = @connection.quote('foo') + @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") + result = @connection.exec_query( + 'SELECT id, data FROM ex WHERE id = $1', nil, [[nil, 1]]) - assert_equal 1, result.rows.length - assert_equal 2, result.columns.length + 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 - string = @connection.quote('foo') - @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") + with_example_table do + string = @connection.quote('foo') + @connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})") - column = @connection.columns('ex').find { |col| col.name == 'id' } - result = @connection.exec_query( - 'SELECT id, data FROM ex WHERE id = $1', nil, [[column, '1-fuu']]) + column = @connection.columns('ex').find { |col| col.name == 'id' } + result = @connection.exec_query( + 'SELECT id, data FROM ex WHERE id = $1', nil, [[column, '1-fuu']]) - assert_equal 1, result.rows.length - assert_equal 2, result.columns.length + 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_substitute_at @@ -240,9 +262,11 @@ module ActiveRecord end def test_partial_index - @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 + 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' } + assert_equal "(number > 100)", index.where + end end def test_columns_for_distinct_zero_orders @@ -300,6 +324,14 @@ module ActiveRecord ctx.exec_insert(sql, 'SQL', binds) end + def with_example_table(definition = nil) + definition ||= 'id serial primary key, number integer, data character varying(255)' + @connection.exec_query("create table ex(#{definition})") + yield + ensure + @connection.exec_query('drop table if exists ex') + end + def connection_without_insert_returning ActiveRecord::Base.postgresql_connection(ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false)) end -- cgit v1.2.3 From e1d4673102f7c4e58964a6de864402ae9a615688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20D=C4=85browski?= Date: Wed, 12 Feb 2014 22:23:16 +0100 Subject: Drop the correct index after reverting a migration Previously when reverting a migration which added a named index it would instead drop a corresponding index with matching columns but without a name. --- .../test/cases/invertible_migration_test.rb | 28 ++++++++++++++++++++++ .../test/cases/migration/command_recorder_test.rb | 6 ++--- 2 files changed, 31 insertions(+), 3 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/invertible_migration_test.rb b/activerecord/test/cases/invertible_migration_test.rb index 428145d00b..debacf815c 100644 --- a/activerecord/test/cases/invertible_migration_test.rb +++ b/activerecord/test/cases/invertible_migration_test.rb @@ -106,6 +106,22 @@ module ActiveRecord end end + class RevertNamedIndexMigration1 < SilentMigration + def change + create_table("horses") do |t| + t.column :content, :string + t.column :remind_at, :datetime + end + add_index :horses, :content + end + end + + class RevertNamedIndexMigration2 < SilentMigration + def change + add_index :horses, :content, name: "horses_index_named" + end + end + def teardown %w[horses new_horses].each do |table| if ActiveRecord::Base.connection.table_exists?(table) @@ -255,5 +271,17 @@ module ActiveRecord ActiveRecord::Base.table_name_prefix = ActiveRecord::Base.table_name_suffix = '' end + def test_migrate_revert_add_index_with_name + RevertNamedIndexMigration1.new.migrate(:up) + RevertNamedIndexMigration2.new.migrate(:up) + RevertNamedIndexMigration2.new.migrate(:down) + + connection = ActiveRecord::Base.connection + assert connection.index_exists?(:horses, :content), + "index on content should exist" + assert !connection.index_exists?(:horses, :content, name: "horses_index_named"), + "horses_index_named index should not exist" + end + end end diff --git a/activerecord/test/cases/migration/command_recorder_test.rb b/activerecord/test/cases/migration/command_recorder_test.rb index 35b656ee43..a925cf4c05 100644 --- a/activerecord/test/cases/migration/command_recorder_test.rb +++ b/activerecord/test/cases/migration/command_recorder_test.rb @@ -174,13 +174,13 @@ module ActiveRecord end def test_invert_add_index - remove = @recorder.inverse_of :add_index, [:table, [:one, :two], options: true] - assert_equal [:remove_index, [:table, {column: [:one, :two], options: true}]], remove + remove = @recorder.inverse_of :add_index, [:table, [:one, :two]] + 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, {column: [:one, :two], name: "new_index"}]], remove + assert_equal [:remove_index, [:table, {name: "new_index"}]], remove end def test_invert_add_index_with_no_options -- cgit v1.2.3 From 680f7d906e6fba521f6a9343d5d5b8c1376bbe76 Mon Sep 17 00:00:00 2001 From: Rajarshi Das Date: Fri, 14 Feb 2014 16:36:45 +0530 Subject: remove unused fixtures from sqlite3 test cases --- activerecord/test/cases/adapters/sqlite3/copy_table_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb b/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb index e78cb88562..b478db749d 100644 --- a/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/copy_table_test.rb @@ -1,7 +1,7 @@ require "cases/helper" class CopyTableTest < ActiveRecord::TestCase - fixtures :customers, :companies, :comments, :binaries + fixtures :customers def setup @connection = ActiveRecord::Base.connection -- cgit v1.2.3 From 8e6ef92fd9ede38aa435afeaef6370ff65191a0b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 14 Feb 2014 14:20:07 -0800 Subject: pass the association and connection to the scope method --- activerecord/test/cases/associations/association_scope_test.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/associations/association_scope_test.rb b/activerecord/test/cases/associations/association_scope_test.rb index d38648202e..f9793277e5 100644 --- a/activerecord/test/cases/associations/association_scope_test.rb +++ b/activerecord/test/cases/associations/association_scope_test.rb @@ -6,8 +6,10 @@ module ActiveRecord module Associations class AssociationScopeTest < ActiveRecord::TestCase test 'does not duplicate conditions' do - association_scope = AssociationScope.new(Author.new.association(:welcome_posts)) - wheres = association_scope.scope.where_values.map(&:right) + association_scope = AssociationScope.new + scope = association_scope.scope(Author.new.association(:welcome_posts), + Author.connection) + wheres = scope.where_values.map(&:right) assert_equal wheres.uniq, wheres end end -- cgit v1.2.3 From 213b2fbf40f6a1ce8381749bd5ba734f20bd4b21 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 14 Feb 2014 14:23:04 -0800 Subject: make a singleton for AssociationScope AssociationScope no longer maintains state, so we're safe to keep a singleton and save on GC time --- activerecord/test/cases/associations/association_scope_test.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'activerecord/test') diff --git a/activerecord/test/cases/associations/association_scope_test.rb b/activerecord/test/cases/associations/association_scope_test.rb index f9793277e5..c78b036f53 100644 --- a/activerecord/test/cases/associations/association_scope_test.rb +++ b/activerecord/test/cases/associations/association_scope_test.rb @@ -6,8 +6,7 @@ module ActiveRecord module Associations class AssociationScopeTest < ActiveRecord::TestCase test 'does not duplicate conditions' do - association_scope = AssociationScope.new - scope = association_scope.scope(Author.new.association(:welcome_posts), + scope = AssociationScope.scope(Author.new.association(:welcome_posts), Author.connection) wheres = scope.where_values.map(&:right) assert_equal wheres.uniq, wheres -- cgit v1.2.3