aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/relation_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases/relation_test.rb')
-rw-r--r--activerecord/test/cases/relation_test.rb135
1 files changed, 63 insertions, 72 deletions
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index a403824f1a..4e75371147 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "cases/helper"
require "models/post"
require "models/comment"
@@ -8,49 +10,30 @@ module ActiveRecord
class RelationTest < ActiveRecord::TestCase
fixtures :posts, :comments, :authors, :author_addresses, :ratings
- FakeKlass = Struct.new(:table_name, :name) do
- extend ActiveRecord::Delegation::DelegateCache
-
- inherited self
-
- def self.connection
- Post.connection
- end
-
- def self.table_name
- "fake_table"
- end
-
- def self.sanitize_sql_for_order(sql)
- sql
- end
- end
-
def test_construction
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass, table: :b)
assert_equal FakeKlass, relation.klass
assert_equal :b, relation.table
assert !relation.loaded, "relation is not loaded"
end
def test_responds_to_model_and_returns_klass
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
assert_equal FakeKlass, relation.model
end
def test_initialize_single_values
- relation = Relation.new(FakeKlass, :b, nil)
- (Relation::SINGLE_VALUE_METHODS - [:create_with, :readonly]).each do |method|
+ relation = Relation.new(FakeKlass)
+ (Relation::SINGLE_VALUE_METHODS - [:create_with]).each do |method|
assert_nil relation.send("#{method}_value"), method.to_s
end
- assert_equal false, relation.readonly_value
value = relation.create_with_value
assert_equal({}, value)
assert_predicate value, :frozen?
end
def test_multi_value_initialize
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
Relation::MULTI_VALUE_METHODS.each do |method|
values = relation.send("#{method}_values")
assert_equal [], values, method.to_s
@@ -59,70 +42,64 @@ module ActiveRecord
end
def test_extensions
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
assert_equal [], relation.extensions
end
def test_empty_where_values_hash
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
assert_equal({}, relation.where_values_hash)
end
def test_has_values
- relation = Relation.new(Post, Post.arel_table, Post.predicate_builder)
- relation.where! relation.table[:id].eq(10)
- assert_equal({ id: 10 }, relation.where_values_hash)
+ relation = Relation.new(Post)
+ relation.where!(id: 10)
+ assert_equal({ "id" => 10 }, relation.where_values_hash)
end
def test_values_wrong_table
- relation = Relation.new(Post, Post.arel_table, Post.predicate_builder)
+ relation = Relation.new(Post)
relation.where! Comment.arel_table[:id].eq(10)
assert_equal({}, relation.where_values_hash)
end
def test_tree_is_not_traversed
- relation = Relation.new(Post, Post.arel_table, Post.predicate_builder)
+ relation = Relation.new(Post)
left = relation.table[:id].eq(10)
right = relation.table[:id].eq(10)
- combine = left.and right
+ combine = left.or(right)
relation.where! combine
assert_equal({}, relation.where_values_hash)
end
- def test_table_name_delegates_to_klass
- relation = Relation.new(FakeKlass.new("posts"), :b, Post.predicate_builder)
- assert_equal "posts", relation.table_name
- end
-
def test_scope_for_create
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
assert_equal({}, relation.scope_for_create)
end
def test_create_with_value
- relation = Relation.new(Post, Post.arel_table, Post.predicate_builder)
- hash = { hello: "world" }
- relation.create_with_value = hash
- assert_equal hash, relation.scope_for_create
- end
-
- def test_create_with_value_with_wheres
- relation = Relation.new(Post, Post.arel_table, Post.predicate_builder)
- relation.where! relation.table[:id].eq(10)
+ relation = Relation.new(Post)
relation.create_with_value = { hello: "world" }
- assert_equal({ hello: "world", id: 10 }, relation.scope_for_create)
+ assert_equal({ "hello" => "world" }, relation.scope_for_create)
end
- # FIXME: is this really wanted or expected behavior?
- def test_scope_for_create_is_cached
- relation = Relation.new(Post, Post.arel_table, Post.predicate_builder)
+ def test_create_with_value_with_wheres
+ relation = Relation.new(Post)
assert_equal({}, relation.scope_for_create)
- relation.where! relation.table[:id].eq(10)
- assert_equal({}, relation.scope_for_create)
+ relation.where!(id: 10)
+ assert_equal({ "id" => 10 }, relation.scope_for_create)
relation.create_with_value = { hello: "world" }
- assert_equal({}, relation.scope_for_create)
+ assert_equal({ "hello" => "world", "id" => 10 }, relation.scope_for_create)
+ end
+
+ def test_empty_scope
+ relation = Relation.new(Post)
+ assert_predicate relation, :empty_scope?
+
+ relation.merge!(relation)
+ assert_predicate relation, :empty_scope?
end
def test_bad_constants_raise_errors
@@ -132,31 +109,31 @@ module ActiveRecord
end
def test_empty_eager_loading?
- relation = Relation.new(FakeKlass, :b, nil)
- assert !relation.eager_loading?
+ relation = Relation.new(FakeKlass)
+ assert_not_predicate relation, :eager_loading?
end
def test_eager_load_values
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
relation.eager_load! :b
- assert relation.eager_loading?
+ assert_predicate relation, :eager_loading?
end
def test_references_values
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
assert_equal [], relation.references_values
relation = relation.references(:foo).references(:omg, :lol)
assert_equal ["foo", "omg", "lol"], relation.references_values
end
def test_references_values_dont_duplicate
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
relation = relation.references(:foo).references(:foo)
assert_equal ["foo"], relation.references_values
end
test "merging a hash into a relation" do
- relation = Relation.new(Post, Post.arel_table, Post.predicate_builder)
+ relation = Relation.new(Post)
relation = relation.merge where: { name: :lol }, readonly: true
assert_equal({ "name" => :lol }, relation.where_clause.to_h)
@@ -164,7 +141,7 @@ module ActiveRecord
end
test "merging an empty hash into a relation" do
- assert_equal Relation::WhereClause.empty, Relation.new(FakeKlass, :b, nil).merge({}).where_clause
+ assert_equal Relation::WhereClause.empty, Relation.new(FakeKlass).merge({}).where_clause
end
test "merging a hash with unknown keys raises" do
@@ -172,7 +149,7 @@ module ActiveRecord
end
test "merging nil or false raises" do
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
e = assert_raises(ArgumentError) do
relation = relation.merge nil
@@ -188,7 +165,7 @@ module ActiveRecord
end
test "#values returns a dup of the values" do
- relation = Relation.new(Post, Post.arel_table, Post.predicate_builder).where!(name: :foo)
+ relation = Relation.new(Post).where!(name: :foo)
values = relation.values
values[:where] = nil
@@ -196,7 +173,7 @@ module ActiveRecord
end
test "relations can be created with a values hash" do
- relation = Relation.new(FakeKlass, :b, nil, select: [:foo])
+ relation = Relation.new(FakeKlass, values: { select: [:foo] })
assert_equal [:foo], relation.select_values
end
@@ -208,13 +185,13 @@ module ActiveRecord
end
end
- relation = Relation.new(klass, :b, nil)
+ relation = Relation.new(klass)
relation.merge!(where: ["foo = ?", "bar"])
- assert_equal Relation::WhereClause.new(["foo = bar"], []), relation.where_clause
+ assert_equal Relation::WhereClause.new(["foo = bar"]), relation.where_clause
end
def test_merging_readonly_false
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
readonly_false_relation = relation.readonly(false)
# test merging in both directions
assert_equal false, relation.merge(readonly_false_relation).readonly_value
@@ -258,17 +235,17 @@ module ActiveRecord
def test_merge_raises_with_invalid_argument
assert_raises ArgumentError do
- relation = Relation.new(FakeKlass, :b, nil)
+ relation = Relation.new(FakeKlass)
relation.merge(true)
end
end
def test_respond_to_for_non_selected_element
post = Post.select(:title).first
- assert_equal false, post.respond_to?(:body), "post should not respond_to?(:body) since invoking it raises exception"
+ assert_not_respond_to post, :body, "post should not respond_to?(:body) since invoking it raises exception"
silence_warnings { post = Post.select("'title' as post_title").first }
- assert_equal false, post.respond_to?(:title), "post should not respond_to?(:body) since invoking it raises exception"
+ assert_not_respond_to post, :title, "post should not respond_to?(:body) since invoking it raises exception"
end
def test_select_quotes_when_using_from_clause
@@ -296,18 +273,32 @@ module ActiveRecord
assert_equal({ 2 => 1, 4 => 3, 5 => 1 }, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count)
end
+ def test_relation_merging_keeps_joining_order
+ authors = Author.where(id: 1)
+ posts = Post.joins(:author).merge(authors)
+ comments = Comment.joins(:post).merge(posts)
+ ratings = Rating.joins(:comment).merge(comments)
+
+ assert_equal 3, ratings.count
+ end
+
class EnsureRoundTripTypeCasting < ActiveRecord::Type::Value
def type
:string
end
+ def cast(value)
+ raise value unless value == "value from user"
+ "cast value"
+ end
+
def deserialize(value)
raise value unless value == "type cast for database"
"type cast from database"
end
def serialize(value)
- raise value unless value == "value from user"
+ raise value unless value == "cast value"
"type cast for database"
end
end