aboutsummaryrefslogtreecommitdiffstats
path: root/spec/active_relation/unit/predicates/binary_spec.rb
blob: b63472a836396c1f18207627f42cb543fcff077a (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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
require File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper')

module ActiveRelation
  describe Binary do
    before do
      @relation = Table.new(:users)
      @attribute1 = @relation[:id]
      @attribute2 = @relation[:name]
      @value = "1-asdf".bind(@relation)
      class ConcreteBinary < Binary
        def predicate_sql
          "<=>"
        end
      end
    end

    describe '#to_sql' do
      describe 'when relating two attributes' do
        it 'manufactures sql with a binary operation' do
          ConcreteBinary.new(@attribute1, @attribute2).to_sql.should be_like("
            `users`.`id` <=> `users`.`name`
          ")
        end
      end
      
      describe 'when relating an attribute and a value' do
        describe 'when relating to an integer attribute' do
          it 'formats values as integers' do
            ConcreteBinary.new(@attribute1, @value).to_sql.should be_like("
              `users`.`id` <=> 1
            ")
          end
        end
        
        describe 'when relating to a string attribute' do
          it 'formats values as strings' do
            ConcreteBinary.new(@attribute2, @value).to_sql.should be_like("
              `users`.`name` <=> '1-asdf'
            ")
          end
        end
      end
      
      describe 'when relating two values' do
        before do
          @another_value = 2.bind(@relation)
        end
        
        it 'quotes values appropriate to their type' do
          ConcreteBinary.new(string = @value, integer = @another_value).to_sql.should be_like("
            '1-asdf' <=> 2
          ")        
        end
      end
      
      describe 'when relating to an array' do
        describe 'when the array\'s elements are the same type as the attribute' do
          before do
            @array = [1, 2, 3]
          end
          
          it 'manufactures sql with a comma separated list' do
            ConcreteBinary.new(@attribute1, @array.bind(@relation)).to_sql.should be_like("
              `users`.`id` <=> (1, 2, 3)
            ")        
          end
        end
        
        describe 'when the array\'s elements are not same type as the attribute' do
          before do
            @array = ['1-asdf', 2, 3]
          end
          
          it 'formats values in the array as the type of the attribute' do
            ConcreteBinary.new(@attribute1, @array.bind(@relation)).to_sql.should be_like("
              `users`.`id` <=> (1, 2, 3)
            ")
          end
        end
      end
      
      describe 'when relating to a relation' do
        it 'manufactures sql with a subselect' do
          ConcreteBinary.new(@attribute1, @relation).to_sql.should be_like("
            `users`.`id` <=> (SELECT `users`.`id`, `users`.`name` FROM `users`)
          ")        
        end
      end
    end
    
    describe '==' do
      it "obtains if attribute1 and attribute2 are identical" do
        Binary.new(@attribute1, @attribute2).should == Binary.new(@attribute1, @attribute2)
        Binary.new(@attribute1, @attribute2).should_not == Binary.new(@attribute1, @attribute1)
      end
    
      it "obtains if the concrete type of the Predicates::Binarys are identical" do
        Binary.new(@attribute1, @attribute2).should == Binary.new(@attribute1, @attribute2)
        Binary.new(@attribute1, @attribute2).should_not == ConcreteBinary.new(@attribute1, @attribute2)
      end
    end
  
    describe '#qualify' do
      it "descends" do
        ConcreteBinary.new(@attribute1, @attribute2).qualify \
          .should == ConcreteBinary.new(@attribute1, @attribute2).descend(&:qualify)
      end
    end
    
    describe '#descend' do
      it "distributes a block over the predicates and attributes" do
        ConcreteBinary.new(@attribute1, @attribute2).descend(&:qualify). \
          should == ConcreteBinary.new(@attribute1.qualify, @attribute2.qualify)
      end
    end
    
    describe '#bind' do
      before do
        @another_relation = Table.new(:photos)
      end
      
      it "descends" do
        ConcreteBinary.new(@attribute1, @attribute2).bind(@another_relation). \
          should == ConcreteBinary.new(@attribute1.bind(@another_relation), @attribute2.bind(@another_relation))
      end
    end
  end
end