aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/relation/where_clause_test.rb
blob: b498739e845660f73a7b41e19404936e731af8cc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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

    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