aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r--activerecord/test/cases/adapters/postgresql/json_test.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/type_lookup_test.rb4
-rw-r--r--activerecord/test/cases/associations/association_scope_test.rb6
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb8
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb10
-rw-r--r--activerecord/test/cases/associations_test.rb4
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb6
-rw-r--r--activerecord/test/cases/attributes_test.rb2
-rw-r--r--activerecord/test/cases/core_test.rb11
-rw-r--r--activerecord/test/cases/counter_cache_test.rb18
-rw-r--r--activerecord/test/cases/inheritance_test.rb4
-rw-r--r--activerecord/test/cases/migration/references_foreign_key_test.rb4
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb2
-rw-r--r--activerecord/test/cases/primary_keys_test.rb2
-rw-r--r--activerecord/test/cases/relation/mutation_test.rb10
-rw-r--r--activerecord/test/cases/relation/where_chain_test.rb72
-rw-r--r--activerecord/test/cases/relation/where_clause_test.rb128
-rw-r--r--activerecord/test/cases/relation_test.rb18
-rw-r--r--activerecord/test/cases/relations_test.rb36
-rw-r--r--activerecord/test/cases/scoping/default_scoping_test.rb10
-rw-r--r--activerecord/test/cases/scoping/named_scoping_test.rb2
-rw-r--r--activerecord/test/cases/scoping/relation_scoping_test.rb2
-rw-r--r--activerecord/test/cases/type/integer_test.rb39
-rw-r--r--activerecord/test/cases/type/unsigned_integer_test.rb4
-rw-r--r--activerecord/test/cases/types_test.rb17
26 files changed, 317 insertions, 114 deletions
diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb
index 5f6cda1986..f5ae872483 100644
--- a/activerecord/test/cases/adapters/postgresql/json_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/json_test.rb
@@ -179,6 +179,14 @@ module PostgresqlJSONSharedTestCases
assert_equal({ 'one' => 'two', 'three' => 'four' }, json.payload)
assert_not json.changed?
end
+
+ def test_assigning_invalid_json
+ json = JsonDataType.new
+
+ json.payload = 'foo'
+
+ assert_nil json.payload
+ end
end
class PostgresqlJSONTest < ActiveRecord::TestCase
diff --git a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
index c88259d274..4506e874bc 100644
--- a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
@@ -18,8 +18,8 @@ class PostgresqlTypeLookupTest < ActiveRecord::TestCase
bigint_array = @connection.type_map.lookup(1016, -1, "bigint[]")
big_array = [123456789123456789]
- assert_raises(RangeError) { int_array.type_cast_from_user(big_array) }
- assert_equal big_array, bigint_array.type_cast_from_user(big_array)
+ assert_raises(RangeError) { int_array.type_cast_for_database(big_array) }
+ assert_equal "{123456789123456789}", bigint_array.type_cast_for_database(big_array)
end
test "range types correctly respect registration of subtypes" do
diff --git a/activerecord/test/cases/associations/association_scope_test.rb b/activerecord/test/cases/associations/association_scope_test.rb
index 3e0032ec73..dd26a85e44 100644
--- a/activerecord/test/cases/associations/association_scope_test.rb
+++ b/activerecord/test/cases/associations/association_scope_test.rb
@@ -8,9 +8,9 @@ module ActiveRecord
test 'does not duplicate conditions' do
scope = AssociationScope.scope(Author.new.association(:welcome_posts),
Author.connection)
- wheres = scope.where_values.map(&:right)
- binds = scope.bind_values.map(&:last)
- wheres = scope.where_values.map(&:right).reject { |node|
+ wheres = scope.where_clause.predicates.map(&:right)
+ binds = scope.where_clause.binds.map(&:last)
+ wheres.reject! { |node|
Arel::Nodes::BindParam === node
}
assert_equal wheres.uniq, wheres
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 17394cb6f7..a425b3ed88 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -122,14 +122,14 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
Firm.create("name" => "Apple")
Client.create("name" => "Citibank", :firm_name => "Apple")
citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key).first
- assert citibank_result.association_cache.key?(:firm_with_primary_key)
+ assert citibank_result.association(:firm_with_primary_key).loaded?
end
def test_eager_loading_with_primary_key_as_symbol
Firm.create("name" => "Apple")
Client.create("name" => "Citibank", :firm_name => "Apple")
citibank_result = Client.all.merge!(:where => {:name => "Citibank"}, :includes => :firm_with_primary_key_symbols).first
- assert citibank_result.association_cache.key?(:firm_with_primary_key_symbols)
+ assert citibank_result.association(:firm_with_primary_key_symbols).loaded?
end
def test_creating_the_belonging_object
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 3bd7506bb5..5ef84562ad 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -316,16 +316,16 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
# would be convenient), because this would cause that scope to be applied to any callbacks etc.
def test_build_and_create_should_not_happen_within_scope
car = cars(:honda)
- scoped_count = car.foo_bulbs.where_values.count
+ scoped_count = car.foo_bulbs.where_clause.predicates.count
bulb = car.foo_bulbs.build
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
+ assert_not_equal scoped_count, bulb.scope_after_initialize.where_clause.predicates.count
bulb = car.foo_bulbs.create
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
+ assert_not_equal scoped_count, bulb.scope_after_initialize.where_clause.predicates.count
bulb = car.foo_bulbs.create!
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
+ assert_not_equal scoped_count, bulb.scope_after_initialize.where_clause.predicates.count
end
def test_no_sql_should_be_fired_if_association_already_loaded
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index 9b6757e256..c02509db46 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -237,16 +237,16 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_build_and_create_should_not_happen_within_scope
pirate = pirates(:blackbeard)
- scoped_count = pirate.association(:foo_bulb).scope.where_values.count
+ scoped_count = pirate.association(:foo_bulb).scope.where_clause.predicates.count
bulb = pirate.build_foo_bulb
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
+ assert_not_equal scoped_count, bulb.scope_after_initialize.where_clause.predicates.count
bulb = pirate.create_foo_bulb
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
+ assert_not_equal scoped_count, bulb.scope_after_initialize.where_clause.predicates.count
bulb = pirate.create_foo_bulb!
- assert_not_equal scoped_count, bulb.scope_after_initialize.where_values.count
+ assert_not_equal scoped_count, bulb.scope_after_initialize.where_clause.predicates.count
end
def test_create_association
@@ -276,7 +276,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_create_with_inexistent_foreign_key_failing
firm = Firm.create(name: 'GlobalMegaCorp')
- assert_raises(ActiveRecord::UnknownAttributeError) do
+ assert_raises(ActiveModel::AttributeAssignment::UnknownAttributeError) do
firm.create_account_with_inexistent_foreign_key
end
end
diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb
index 72963fd56c..c88dc58950 100644
--- a/activerecord/test/cases/associations_test.rb
+++ b/activerecord/test/cases/associations_test.rb
@@ -141,7 +141,7 @@ class AssociationsTest < ActiveRecord::TestCase
def test_association_with_references
firm = companies(:first_firm)
- assert_equal ['foo'], firm.association_with_references.references_values
+ assert_includes firm.association_with_references.references_values, 'foo'
end
end
@@ -238,7 +238,7 @@ class AssociationProxyTest < ActiveRecord::TestCase
end
def test_scoped_allows_conditions
- assert developers(:david).projects.merge!(where: 'foo').where_values.include?('foo')
+ assert developers(:david).projects.merge!(where: 'foo').where_clause.predicates.include?('foo')
end
test "getting a scope from an association" do
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index ea2b94cbf4..243c90e945 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -758,12 +758,12 @@ class AttributeMethodsTest < ActiveRecord::TestCase
def test_bulk_update_respects_access_control
privatize("title=(value)")
- assert_raise(ActiveRecord::UnknownAttributeError) { @target.new(:title => "Rants about pants") }
- assert_raise(ActiveRecord::UnknownAttributeError) { @target.new.attributes = { :title => "Ants in pants" } }
+ assert_raise(ActiveModel::AttributeAssignment::UnknownAttributeError) { @target.new(:title => "Rants about pants") }
+ assert_raise(ActiveModel::AttributeAssignment::UnknownAttributeError) { @target.new.attributes = { :title => "Ants in pants" } }
end
def test_bulk_update_raise_unknown_attribute_error
- error = assert_raises(ActiveRecord::UnknownAttributeError) {
+ error = assert_raises(ActiveModel::AttributeAssignment::UnknownAttributeError) {
Topic.new(hello: "world")
}
assert_instance_of Topic, error.record
diff --git a/activerecord/test/cases/attributes_test.rb b/activerecord/test/cases/attributes_test.rb
index dbe1eb48db..4ddf6e7ba0 100644
--- a/activerecord/test/cases/attributes_test.rb
+++ b/activerecord/test/cases/attributes_test.rb
@@ -58,7 +58,7 @@ module ActiveRecord
data = OverloadedType.new(non_existent_decimal: 1)
assert_equal BigDecimal.new(1), data.non_existent_decimal
- assert_raise ActiveRecord::UnknownAttributeError do
+ assert_raise ActiveModel::AttributeAssignment::UnknownAttributeError do
UnoverloadedType.new(non_existent_decimal: 1)
end
end
diff --git a/activerecord/test/cases/core_test.rb b/activerecord/test/cases/core_test.rb
index 715d92af99..3cb98832c5 100644
--- a/activerecord/test/cases/core_test.rb
+++ b/activerecord/test/cases/core_test.rb
@@ -98,4 +98,15 @@ class CoreTest < ActiveRecord::TestCase
assert actual.start_with?(expected.split('XXXXXX').first)
assert actual.end_with?(expected.split('XXXXXX').last)
end
+
+ def test_pretty_print_overridden_by_inspect
+ subtopic = Class.new(Topic) do
+ def inspect
+ "inspecting topic"
+ end
+ end
+ actual = ''
+ PP.pp(subtopic.new, StringIO.new(actual))
+ assert_equal "inspecting topic\n", actual
+ end
end
diff --git a/activerecord/test/cases/counter_cache_test.rb b/activerecord/test/cases/counter_cache_test.rb
index 07a182070b..1f5055b2a2 100644
--- a/activerecord/test/cases/counter_cache_test.rb
+++ b/activerecord/test/cases/counter_cache_test.rb
@@ -180,4 +180,22 @@ class CounterCacheTest < ActiveRecord::TestCase
SpecialTopic.reset_counters(special.id, :lightweight_special_replies)
end
end
+
+ test "counters are updated both in memory and in the database on create" do
+ car = Car.new(engines_count: 0)
+ car.engines = [Engine.new, Engine.new]
+ car.save!
+
+ assert_equal 2, car.engines_count
+ assert_equal 2, car.reload.engines_count
+ end
+
+ test "counter caches are updated in memory when the default value is nil" do
+ car = Car.new(engines_count: nil)
+ car.engines = [Engine.new, Engine.new]
+ car.save!
+
+ assert_equal 2, car.engines_count
+ assert_equal 2, car.reload.engines_count
+ end
end
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index fe6323ab02..6b18bfe84f 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -294,12 +294,12 @@ class InheritanceTest < ActiveRecord::TestCase
def test_eager_load_belongs_to_something_inherited
account = Account.all.merge!(:includes => :firm).find(1)
- assert account.association_cache.key?(:firm), "nil proves eager load failed"
+ assert account.association(:firm).loaded?, "association was not eager loaded"
end
def test_alt_eager_loading
cabbage = RedCabbage.all.merge!(:includes => :seller).find(4)
- assert cabbage.association_cache.key?(:seller), "nil proves eager load failed"
+ assert cabbage.association(:seller).loaded?, "association was not eager loaded"
end
def test_eager_load_belongs_to_primary_key_quoting
diff --git a/activerecord/test/cases/migration/references_foreign_key_test.rb b/activerecord/test/cases/migration/references_foreign_key_test.rb
index bba8897a0d..99de7db70c 100644
--- a/activerecord/test/cases/migration/references_foreign_key_test.rb
+++ b/activerecord/test/cases/migration/references_foreign_key_test.rb
@@ -10,8 +10,8 @@ module ActiveRecord
end
teardown do
- @connection.execute("drop table if exists testings")
- @connection.execute("drop table if exists testing_parents")
+ @connection.drop_table("testings") if @connection.table_exists? "testings"
+ @connection.drop_table("testing_parents") if @connection.table_exists? "testing_parents"
end
test "foreign keys can be created with the table" do
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index 5c7e8a65d2..8bc42b8890 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -672,7 +672,7 @@ module NestedAttributesOnACollectionAssociationTests
end
def test_should_not_assign_destroy_key_to_a_record
- assert_nothing_raised ActiveRecord::UnknownAttributeError do
+ assert_nothing_raised ActiveModel::AttributeAssignment::UnknownAttributeError do
@pirate.send(association_setter, { 'foo' => { '_destroy' => '0' }})
end
end
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 751eccc015..4b668f84dd 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -210,7 +210,7 @@ class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
end
teardown do
- @connection.execute("DROP TABLE IF EXISTS barcodes")
+ @connection.drop_table(:barcodes) if @connection.table_exists? :barcodes
end
def test_any_type_primary_key
diff --git a/activerecord/test/cases/relation/mutation_test.rb b/activerecord/test/cases/relation/mutation_test.rb
index 2443f10269..45ead08bd5 100644
--- a/activerecord/test/cases/relation/mutation_test.rb
+++ b/activerecord/test/cases/relation/mutation_test.rb
@@ -81,7 +81,7 @@ module ActiveRecord
assert_equal [], relation.extending_values
end
- (Relation::SINGLE_VALUE_METHODS - [:from, :lock, :reordering, :reverse_order, :create_with]).each do |method|
+ (Relation::SINGLE_VALUE_METHODS - [:lock, :reordering, :reverse_order, :create_with]).each do |method|
test "##{method}!" do
assert relation.public_send("#{method}!", :foo).equal?(relation)
assert_equal :foo, relation.public_send("#{method}_value")
@@ -90,7 +90,7 @@ module ActiveRecord
test '#from!' do
assert relation.from!('foo').equal?(relation)
- assert_equal ['foo', nil], relation.from_value
+ assert_equal 'foo', relation.from_clause.value
end
test '#lock!' do
@@ -136,12 +136,12 @@ module ActiveRecord
end
test 'test_merge!' do
- assert relation.merge!(where: :foo).equal?(relation)
- assert_equal [:foo], relation.where_values
+ assert relation.merge!(select: :foo).equal?(relation)
+ assert_equal [:foo], relation.select_values
end
test 'merge with a proc' do
- assert_equal [:foo], relation.merge(-> { where(:foo) }).where_values
+ assert_equal [:foo], relation.merge(-> { select(:foo) }).select_values
end
test 'none!' do
diff --git a/activerecord/test/cases/relation/where_chain_test.rb b/activerecord/test/cases/relation/where_chain_test.rb
index 0f9019bb1b..00c9a001c0 100644
--- a/activerecord/test/cases/relation/where_chain_test.rb
+++ b/activerecord/test/cases/relation/where_chain_test.rb
@@ -14,10 +14,10 @@ module ActiveRecord
def test_not_eq
relation = Post.where.not(title: 'hello')
- assert_equal 1, relation.where_values.length
+ assert_equal 1, relation.where_clause.predicates.length
- value = relation.where_values.first
- bind = relation.bind_values.first
+ value = relation.where_clause.predicates.first
+ bind = relation.where_clause.binds.first
assert_bound_ast value, Post.arel_table[@name], Arel::Nodes::NotEqual
assert_equal 'hello', bind.last
@@ -26,7 +26,7 @@ module ActiveRecord
def test_not_null
expected = Post.arel_table[@name].not_eq(nil)
relation = Post.where.not(title: nil)
- assert_equal([expected], relation.where_values)
+ assert_equal([expected], relation.where_clause.predicates)
end
def test_not_with_nil
@@ -38,25 +38,25 @@ module ActiveRecord
def test_not_in
expected = Post.arel_table[@name].not_in(%w[hello goodbye])
relation = Post.where.not(title: %w[hello goodbye])
- assert_equal([expected], relation.where_values)
+ assert_equal([expected], relation.where_clause.predicates)
end
def test_association_not_eq
expected = Comment.arel_table[@name].not_eq(Arel::Nodes::BindParam.new)
relation = Post.joins(:comments).where.not(comments: {title: 'hello'})
- assert_equal(expected.to_sql, relation.where_values.first.to_sql)
+ assert_equal(expected.to_sql, relation.where_clause.predicates.first.to_sql)
end
def test_not_eq_with_preceding_where
relation = Post.where(title: 'hello').where.not(title: 'world')
- value = relation.where_values.first
- bind = relation.bind_values.first
+ value = relation.where_clause.predicates.first
+ bind = relation.where_clause.binds.first
assert_bound_ast value, Post.arel_table[@name], Arel::Nodes::Equality
assert_equal 'hello', bind.last
- value = relation.where_values.last
- bind = relation.bind_values.last
+ value = relation.where_clause.predicates.last
+ bind = relation.where_clause.binds.last
assert_bound_ast value, Post.arel_table[@name], Arel::Nodes::NotEqual
assert_equal 'world', bind.last
end
@@ -64,13 +64,13 @@ module ActiveRecord
def test_not_eq_with_succeeding_where
relation = Post.where.not(title: 'hello').where(title: 'world')
- value = relation.where_values.first
- bind = relation.bind_values.first
+ value = relation.where_clause.predicates.first
+ bind = relation.where_clause.binds.first
assert_bound_ast value, Post.arel_table[@name], Arel::Nodes::NotEqual
assert_equal 'hello', bind.last
- value = relation.where_values.last
- bind = relation.bind_values.last
+ value = relation.where_clause.predicates.last
+ bind = relation.where_clause.binds.last
assert_bound_ast value, Post.arel_table[@name], Arel::Nodes::Equality
assert_equal 'world', bind.last
end
@@ -78,23 +78,23 @@ module ActiveRecord
def test_not_eq_with_string_parameter
expected = Arel::Nodes::Not.new("title = 'hello'")
relation = Post.where.not("title = 'hello'")
- assert_equal([expected], relation.where_values)
+ assert_equal([expected], relation.where_clause.predicates)
end
def test_not_eq_with_array_parameter
expected = Arel::Nodes::Not.new("title = 'hello'")
relation = Post.where.not(['title = ?', 'hello'])
- assert_equal([expected], relation.where_values)
+ assert_equal([expected], relation.where_clause.predicates)
end
def test_chaining_multiple
relation = Post.where.not(author_id: [1, 2]).where.not(title: 'ruby on rails')
expected = Post.arel_table['author_id'].not_in([1, 2])
- assert_equal(expected, relation.where_values[0])
+ assert_equal(expected, relation.where_clause.predicates[0])
- value = relation.where_values[1]
- bind = relation.bind_values.first
+ value = relation.where_clause.predicates[1]
+ bind = relation.where_clause.binds.first
assert_bound_ast value, Post.arel_table[@name], Arel::Nodes::NotEqual
assert_equal 'ruby on rails', bind.last
@@ -103,9 +103,9 @@ module ActiveRecord
def test_rewhere_with_one_condition
relation = Post.where(title: 'hello').where(title: 'world').rewhere(title: 'alone')
- assert_equal 1, relation.where_values.size
- value = relation.where_values.first
- bind = relation.bind_values.first
+ assert_equal 1, relation.where_clause.predicates.size
+ value = relation.where_clause.predicates.first
+ bind = relation.where_clause.binds.first
assert_bound_ast value, Post.arel_table[@name], Arel::Nodes::Equality
assert_equal 'alone', bind.last
end
@@ -113,15 +113,15 @@ module ActiveRecord
def test_rewhere_with_multiple_overwriting_conditions
relation = Post.where(title: 'hello').where(body: 'world').rewhere(title: 'alone', body: 'again')
- assert_equal 2, relation.where_values.size
+ assert_equal 2, relation.where_clause.predicates.size
- value = relation.where_values.first
- bind = relation.bind_values.first
+ value = relation.where_clause.predicates.first
+ bind = relation.where_clause.binds.first
assert_bound_ast value, Post.arel_table['title'], Arel::Nodes::Equality
assert_equal 'alone', bind.last
- value = relation.where_values[1]
- bind = relation.bind_values[1]
+ value = relation.where_clause.predicates[1]
+ bind = relation.where_clause.binds[1]
assert_bound_ast value, Post.arel_table['body'], Arel::Nodes::Equality
assert_equal 'again', bind.last
end
@@ -135,16 +135,16 @@ module ActiveRecord
def test_rewhere_with_one_overwriting_condition_and_one_unrelated
relation = Post.where(title: 'hello').where(body: 'world').rewhere(title: 'alone')
- assert_equal 2, relation.where_values.size
+ assert_equal 2, relation.where_clause.predicates.size
- value = relation.where_values.first
- bind = relation.bind_values.first
+ value = relation.where_clause.predicates.first
+ bind = relation.where_clause.binds.first
assert_bound_ast value, Post.arel_table['body'], Arel::Nodes::Equality
assert_equal 'world', bind.last
- value = relation.where_values.second
- bind = relation.bind_values.second
+ value = relation.where_clause.predicates.second
+ bind = relation.where_clause.binds.second
assert_bound_ast value, Post.arel_table['title'], Arel::Nodes::Equality
assert_equal 'alone', bind.last
@@ -153,28 +153,28 @@ module ActiveRecord
def test_rewhere_with_range
relation = Post.where(comments_count: 1..3).rewhere(comments_count: 3..5)
- assert_equal 1, relation.where_values.size
+ assert_equal 1, relation.where_clause.predicates.size
assert_equal Post.where(comments_count: 3..5), relation
end
def test_rewhere_with_infinite_upper_bound_range
relation = Post.where(comments_count: 1..Float::INFINITY).rewhere(comments_count: 3..5)
- assert_equal 1, relation.where_values.size
+ assert_equal 1, relation.where_clause.predicates.size
assert_equal Post.where(comments_count: 3..5), relation
end
def test_rewhere_with_infinite_lower_bound_range
relation = Post.where(comments_count: -Float::INFINITY..1).rewhere(comments_count: 3..5)
- assert_equal 1, relation.where_values.size
+ assert_equal 1, relation.where_clause.predicates.size
assert_equal Post.where(comments_count: 3..5), relation
end
def test_rewhere_with_infinite_range
relation = Post.where(comments_count: -Float::INFINITY..Float::INFINITY).rewhere(comments_count: 3..5)
- assert_equal 1, relation.where_values.size
+ assert_equal 1, relation.where_clause.predicates.size
assert_equal Post.where(comments_count: 3..5), relation
end
end
diff --git a/activerecord/test/cases/relation/where_clause_test.rb b/activerecord/test/cases/relation/where_clause_test.rb
new file mode 100644
index 0000000000..6864be2608
--- /dev/null
+++ b/activerecord/test/cases/relation/where_clause_test.rb
@@ -0,0 +1,128 @@
+require "cases/helper"
+
+class ActiveRecord::Relation
+ class WhereClauseTest < ActiveRecord::TestCase
+ test "+ combines two where clauses" do
+ first_clause = WhereClause.new([table["id"].eq(bind_param)], [["id", 1]])
+ second_clause = WhereClause.new([table["name"].eq(bind_param)], [["name", "Sean"]])
+ combined = WhereClause.new(
+ [table["id"].eq(bind_param), table["name"].eq(bind_param)],
+ [["id", 1], ["name", "Sean"]],
+ )
+
+ assert_equal combined, first_clause + second_clause
+ end
+
+ test "+ is associative, but not commutative" do
+ a = WhereClause.new(["a"], ["bind a"])
+ b = WhereClause.new(["b"], ["bind b"])
+ c = WhereClause.new(["c"], ["bind c"])
+
+ assert_equal a + (b + c), (a + b) + c
+ assert_not_equal a + b, b + a
+ end
+
+ test "an empty where clause is the identity value for +" do
+ clause = WhereClause.new([table["id"].eq(bind_param)], [["id", 1]])
+
+ assert_equal clause, clause + WhereClause.empty
+ end
+
+ test "merge combines two where clauses" do
+ a = WhereClause.new([table["id"].eq(1)], [])
+ b = WhereClause.new([table["name"].eq("Sean")], [])
+ expected = WhereClause.new([table["id"].eq(1), table["name"].eq("Sean")], [])
+
+ assert_equal expected, a.merge(b)
+ end
+
+ test "merge keeps the right side, when two equality clauses reference the same column" do
+ a = WhereClause.new([table["id"].eq(1), table["name"].eq("Sean")], [])
+ b = WhereClause.new([table["name"].eq("Jim")], [])
+ expected = WhereClause.new([table["id"].eq(1), table["name"].eq("Jim")], [])
+
+ assert_equal expected, a.merge(b)
+ end
+
+ test "merge removes bind parameters matching overlapping equality clauses" do
+ a = WhereClause.new(
+ [table["id"].eq(bind_param), table["name"].eq(bind_param)],
+ [[column("id"), 1], [column("name"), "Sean"]],
+ )
+ b = WhereClause.new(
+ [table["name"].eq(bind_param)],
+ [[column("name"), "Jim"]]
+ )
+ expected = WhereClause.new(
+ [table["id"].eq(bind_param), table["name"].eq(bind_param)],
+ [[column("id"), 1], [column("name"), "Jim"]],
+ )
+
+ assert_equal expected, a.merge(b)
+ end
+
+ test "merge allows for columns with the same name from different tables" do
+ skip "This is not possible as of 4.2, and the binds do not yet contain sufficient information for this to happen"
+ # We might be able to change the implementation to remove conflicts by index, rather than column name
+ end
+
+ test "a clause knows if it is empty" do
+ assert WhereClause.empty.empty?
+ assert_not WhereClause.new(["anything"], []).empty?
+ end
+
+ test "invert cannot handle nil" do
+ where_clause = WhereClause.new([nil], [])
+
+ assert_raises ArgumentError do
+ where_clause.invert
+ end
+ end
+
+ test "invert replaces each part of the predicate with its inverse" do
+ random_object = Object.new
+ original = WhereClause.new([
+ table["id"].in([1, 2, 3]),
+ table["id"].eq(1),
+ "sql literal",
+ random_object
+ ], [])
+ expected = WhereClause.new([
+ table["id"].not_in([1, 2, 3]),
+ table["id"].not_eq(1),
+ Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new("sql literal")),
+ Arel::Nodes::Not.new(random_object)
+ ], [])
+
+ assert_equal expected, original.invert
+ end
+
+ test "accept removes binary predicates referencing a given column" do
+ where_clause = WhereClause.new([
+ table["id"].in([1, 2, 3]),
+ table["name"].eq(bind_param),
+ table["age"].gteq(bind_param),
+ ], [
+ [column("name"), "Sean"],
+ [column("age"), 30],
+ ])
+ expected = WhereClause.new([table["age"].gteq(bind_param)], [[column("age"), 30]])
+
+ assert_equal expected, where_clause.except("id", "name")
+ end
+
+ private
+
+ def table
+ Arel::Table.new("table")
+ end
+
+ def bind_param
+ Arel::Nodes::BindParam.new
+ end
+
+ def column(name)
+ ActiveRecord::ConnectionAdapters::Column.new(name, nil, nil)
+ end
+ end
+end
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index f7cb471984..d75c5435c6 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -156,12 +156,12 @@ module ActiveRecord
relation = Relation.new(FakeKlass, :b, nil)
relation = relation.merge where: :lol, readonly: true
- assert_equal [:lol], relation.where_values
+ assert_equal [:lol], relation.where_clause.predicates
assert_equal true, relation.readonly_value
end
test 'merging an empty hash into a relation' do
- assert_equal [], Relation.new(FakeKlass, :b, nil).merge({}).where_values
+ assert_equal Relation::WhereClause.empty, Relation.new(FakeKlass, :b, nil).merge({}).where_clause
end
test 'merging a hash with unknown keys raises' do
@@ -173,18 +173,12 @@ module ActiveRecord
values = relation.values
values[:where] = nil
- assert_not_nil relation.where_values
+ assert_not_nil relation.where_clause
end
test 'relations can be created with a values hash' do
- relation = Relation.new(FakeKlass, :b, nil, where: [:foo])
- assert_equal [:foo], relation.where_values
- end
-
- test 'merging a single where value' do
- relation = Relation.new(FakeKlass, :b, nil)
- relation.merge!(where: :foo)
- assert_equal [:foo], relation.where_values
+ relation = Relation.new(FakeKlass, :b, nil, select: [:foo])
+ assert_equal [:foo], relation.select_values
end
test 'merging a hash interpolates conditions' do
@@ -197,7 +191,7 @@ module ActiveRecord
relation = Relation.new(klass, :b, nil)
relation.merge!(where: ['foo = ?', 'bar'])
- assert_equal ['foo = bar'], relation.where_values
+ assert_equal ['foo = bar'], relation.where_clause.predicates
end
def test_merging_readonly_false
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index 9631ea79be..ecb30af12b 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -39,15 +39,6 @@ class RelationTest < ActiveRecord::TestCase
assert_equal van, Minivan.where(:minivan_id => [van]).to_a.first
end
- def test_bind_values
- relation = Post.all
- assert_equal [], relation.bind_values
-
- relation2 = relation.bind 'foo'
- assert_equal %w{ foo }, relation2.bind_values
- assert_equal [], relation.bind_values
- end
-
def test_two_scopes_with_includes_should_not_drop_any_include
# heat habtm cache
car = Car.incl_engines.incl_tyres.first
@@ -857,6 +848,12 @@ class RelationTest < ActiveRecord::TestCase
assert ! fake.exists?(authors(:david).id)
end
+ def test_exists_uses_existing_scope
+ post = authors(:david).posts.first
+ authors = Author.includes(:posts).where(name: "David", posts: { id: post.id })
+ assert authors.exists?(authors(:david).id)
+ end
+
def test_last
authors = Author.all
assert_equal authors(:bob), authors.last
@@ -1462,10 +1459,27 @@ class RelationTest < ActiveRecord::TestCase
def test_doesnt_add_having_values_if_options_are_blank
scope = Post.having('')
- assert_equal [], scope.having_values
+ assert scope.having_clause.empty?
scope = Post.having([])
- assert_equal [], scope.having_values
+ assert scope.having_clause.empty?
+ end
+
+ def test_having_with_binds_for_both_where_and_having
+ post = Post.first
+ having_then_where = Post.having(id: post.id).where(title: post.title).group(:id)
+ where_then_having = Post.where(title: post.title).having(id: post.id).group(:id)
+
+ assert_equal [post], having_then_where
+ assert_equal [post], where_then_having
+ end
+
+ def test_multiple_where_and_having_clauses
+ post = Post.first
+ having_then_where = Post.having(id: post.id).where(title: post.title)
+ .having(id: post.id).where(title: post.title).group(:id)
+
+ assert_equal [post], having_then_where
end
def test_references_triggers_eager_loading
diff --git a/activerecord/test/cases/scoping/default_scoping_test.rb b/activerecord/test/cases/scoping/default_scoping_test.rb
index 0738df1b54..d0835ba3e5 100644
--- a/activerecord/test/cases/scoping/default_scoping_test.rb
+++ b/activerecord/test/cases/scoping/default_scoping_test.rb
@@ -284,8 +284,8 @@ class DefaultScopingTest < ActiveRecord::TestCase
def test_unscope_merging
merged = Developer.where(name: "Jamis").merge(Developer.unscope(:where))
- assert merged.where_values.empty?
- assert !merged.where(name: "Jon").where_values.empty?
+ assert merged.where_clause.empty?
+ assert !merged.where(name: "Jon").where_clause.empty?
end
def test_order_in_default_scope_should_not_prevail
@@ -426,19 +426,19 @@ class DefaultScopingTest < ActiveRecord::TestCase
test "additional conditions are ANDed with the default scope" do
scope = DeveloperCalledJamis.where(name: "David")
- assert_equal 2, scope.where_values.length
+ assert_equal 2, scope.where_clause.predicates.length
assert_equal [], scope.to_a
end
test "additional conditions in a scope are ANDed with the default scope" do
scope = DeveloperCalledJamis.david
- assert_equal 2, scope.where_values.length
+ assert_equal 2, scope.where_clause.predicates.length
assert_equal [], scope.to_a
end
test "a scope can remove the condition from the default scope" do
scope = DeveloperCalledJamis.david2
- assert_equal 1, scope.where_values.length
+ assert_equal 1, scope.where_clause.predicates.length
assert_equal Developer.where(name: "David").map(&:id), scope.map(&:id)
end
end
diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb
index 41f3449828..57c9ff6a8d 100644
--- a/activerecord/test/cases/scoping/named_scoping_test.rb
+++ b/activerecord/test/cases/scoping/named_scoping_test.rb
@@ -380,7 +380,7 @@ class NamedScopingTest < ActiveRecord::TestCase
end
def test_should_not_duplicates_where_values
- where_values = Topic.where("1=1").scope_with_lambda.where_values
+ where_values = Topic.where("1=1").scope_with_lambda.where_clause.predicates
assert_equal ["1=1"], where_values
end
diff --git a/activerecord/test/cases/scoping/relation_scoping_test.rb b/activerecord/test/cases/scoping/relation_scoping_test.rb
index d7bcbf6203..73760e628b 100644
--- a/activerecord/test/cases/scoping/relation_scoping_test.rb
+++ b/activerecord/test/cases/scoping/relation_scoping_test.rb
@@ -184,7 +184,7 @@ class RelationScopingTest < ActiveRecord::TestCase
rescue
end
- assert !Developer.all.where_values.include?("name = 'Jamis'")
+ assert !Developer.all.where_clause.predicates.include?("name = 'Jamis'")
end
def test_default_scope_filters_on_joins
diff --git a/activerecord/test/cases/type/integer_test.rb b/activerecord/test/cases/type/integer_test.rb
index ff956b7680..0c60f0690c 100644
--- a/activerecord/test/cases/type/integer_test.rb
+++ b/activerecord/test/cases/type/integer_test.rb
@@ -60,55 +60,68 @@ module ActiveRecord
test "values below int min value are out of range" do
assert_raises(::RangeError) do
- Integer.new.type_cast_from_user("-2147483649")
+ Integer.new.type_cast_for_database(-2147483649)
end
end
test "values above int max value are out of range" do
assert_raises(::RangeError) do
- Integer.new.type_cast_from_user("2147483648")
+ Integer.new.type_cast_for_database(2147483648)
end
end
test "very small numbers are out of range" do
assert_raises(::RangeError) do
- Integer.new.type_cast_from_user("-9999999999999999999999999999999")
+ Integer.new.type_cast_for_database(-9999999999999999999999999999999)
end
end
test "very large numbers are out of range" do
assert_raises(::RangeError) do
- Integer.new.type_cast_from_user("9999999999999999999999999999999")
+ Integer.new.type_cast_for_database(9999999999999999999999999999999)
end
end
test "normal numbers are in range" do
type = Integer.new
- assert_equal(0, type.type_cast_from_user("0"))
- assert_equal(-1, type.type_cast_from_user("-1"))
- assert_equal(1, type.type_cast_from_user("1"))
+ assert_equal(0, type.type_cast_for_database(0))
+ assert_equal(-1, type.type_cast_for_database(-1))
+ assert_equal(1, type.type_cast_for_database(1))
end
test "int max value is in range" do
- assert_equal(2147483647, Integer.new.type_cast_from_user("2147483647"))
+ assert_equal(2147483647, Integer.new.type_cast_for_database(2147483647))
end
test "int min value is in range" do
- assert_equal(-2147483648, Integer.new.type_cast_from_user("-2147483648"))
+ assert_equal(-2147483648, Integer.new.type_cast_for_database(-2147483648))
end
test "columns with a larger limit have larger ranges" do
type = Integer.new(limit: 8)
- assert_equal(9223372036854775807, type.type_cast_from_user("9223372036854775807"))
- assert_equal(-9223372036854775808, type.type_cast_from_user("-9223372036854775808"))
+ assert_equal(9223372036854775807, type.type_cast_for_database(9223372036854775807))
+ assert_equal(-9223372036854775808, type.type_cast_for_database(-9223372036854775808))
assert_raises(::RangeError) do
- type.type_cast_from_user("-9999999999999999999999999999999")
+ type.type_cast_for_database(-9999999999999999999999999999999)
end
assert_raises(::RangeError) do
- type.type_cast_from_user("9999999999999999999999999999999")
+ type.type_cast_for_database(9999999999999999999999999999999)
end
end
+
+ test "values which are out of range can be re-assigned" do
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = 'posts'
+ attribute :foo, Type::Integer.new
+ end
+ model = klass.new
+
+ model.foo = 2147483648
+ model.foo = 1
+
+ assert_equal 1, model.foo
+ end
end
end
end
diff --git a/activerecord/test/cases/type/unsigned_integer_test.rb b/activerecord/test/cases/type/unsigned_integer_test.rb
index b6f673109e..4b8e2fb518 100644
--- a/activerecord/test/cases/type/unsigned_integer_test.rb
+++ b/activerecord/test/cases/type/unsigned_integer_test.rb
@@ -4,12 +4,12 @@ module ActiveRecord
module Type
class UnsignedIntegerTest < ActiveRecord::TestCase
test "unsigned int max value is in range" do
- assert_equal(4294967295, UnsignedInteger.new.type_cast_from_user("4294967295"))
+ assert_equal(4294967295, UnsignedInteger.new.type_cast_for_database(4294967295))
end
test "minus value is out of range" do
assert_raises(::RangeError) do
- UnsignedInteger.new.type_cast_from_user("-1")
+ UnsignedInteger.new.type_cast_for_database(-1)
end
end
end
diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb
index 73e92addfe..d35d34ff2d 100644
--- a/activerecord/test/cases/types_test.rb
+++ b/activerecord/test/cases/types_test.rb
@@ -117,6 +117,23 @@ module ActiveRecord
assert_equal Encoding::ASCII_8BIT, type_cast.encoding
end
end
+
+ def test_attributes_which_are_invalid_for_database_can_still_be_reassigned
+ type_which_cannot_go_to_the_database = Type::Value.new
+ def type_which_cannot_go_to_the_database.type_cast_for_database(*)
+ raise
+ end
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = 'posts'
+ attribute :foo, type_which_cannot_go_to_the_database
+ end
+ model = klass.new
+
+ model.foo = "foo"
+ model.foo = "bar"
+
+ assert_equal "bar", model.foo
+ end
end
end
end