aboutsummaryrefslogblamecommitdiffstats
path: root/activerecord/test/cases/relation/mutation_test.rb
blob: 4fafa668fb167dc6122b17cc5c94bc5ae0e80656 (plain) (tree)
1
2
3
4
5
6
7
8
9
                      







                                                      






                                                 



                                


                
                                                                        

       
                                                                                                  





                                                                        
                     



                                                         
                                                         






                                                    
                                                                                



















































                                                                                                                 








                                                           











                                                               
                         













                                                                          
                       




                                                                
                                             





                                                                
require 'cases/helper'
require 'models/post'

module ActiveRecord
  class RelationMutationTest < ActiveSupport::TestCase
    class FakeKlass < Struct.new(:table_name, :name)
      extend ActiveRecord::Delegation::DelegateCache
      inherited self

      def connection
        Post.connection
      end

      def relation_delegate_class(klass)
        self.class.relation_delegate_class(klass)
      end

      def attribute_alias?(name)
        false
      end
    end

    def relation
      @relation ||= Relation.new FakeKlass.new('posts'), Post.arel_table
    end

    (Relation::MULTI_VALUE_METHODS - [:references, :extending, :order, :unscope]).each do |method|
      test "##{method}!" do
        assert relation.public_send("#{method}!", :foo).equal?(relation)
        assert_equal [:foo], relation.public_send("#{method}_values")
      end
    end

    test '#order!' do
      assert relation.order!('name ASC').equal?(relation)
      assert_equal ['name ASC'], relation.order_values
    end

    test '#order! with symbol prepends the table name' do
      assert relation.order!(:name).equal?(relation)
      node = relation.order_values.first
      assert node.ascending?
      assert_equal :name, node.expr.name
      assert_equal "posts", node.expr.relation.name
    end

    test '#order! on non-string does not attempt regexp match for references' do
      obj = Object.new
      obj.expects(:=~).never
      assert relation.order!(obj)
      assert_equal [obj], relation.order_values
    end

    test '#references!' do
      assert relation.references!(:foo).equal?(relation)
      assert relation.references_values.include?('foo')
    end

    test 'extending!' do
      mod, mod2 = Module.new, Module.new

      assert relation.extending!(mod).equal?(relation)
      assert_equal [mod], relation.extending_values
      assert relation.is_a?(mod)

      relation.extending!(mod2)
      assert_equal [mod, mod2], relation.extending_values
    end

    test 'extending! with empty args' do
      relation.extending!
      assert_equal [], relation.extending_values
    end

    (Relation::SINGLE_VALUE_METHODS - [:from, :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")
      end
    end

    test '#from!' do
      assert relation.from!('foo').equal?(relation)
      assert_equal ['foo', nil], relation.from_value
    end

    test '#lock!' do
      assert relation.lock!('foo').equal?(relation)
      assert_equal 'foo', relation.lock_value
    end

    test '#reorder!' do
      relation = self.relation.order('foo')

      assert relation.reorder!('bar').equal?(relation)
      assert_equal ['bar'], relation.order_values
      assert relation.reordering_value
    end

    test '#reorder! with symbol prepends the table name' do
      assert relation.reorder!(:name).equal?(relation)
      node = relation.order_values.first

      assert node.ascending?
      assert_equal :name, node.expr.name
      assert_equal "posts", node.expr.relation.name
    end

    test 'reverse_order!' do
      assert relation.reverse_order!.equal?(relation)
      assert relation.reverse_order_value
      relation.reverse_order!
      assert !relation.reverse_order_value
    end

    test 'create_with!' do
      assert relation.create_with!(foo: 'bar').equal?(relation)
      assert_equal({foo: 'bar'}, relation.create_with_value)
    end

    test 'test_merge!' do
      assert relation.merge!(where: :foo).equal?(relation)
      assert_equal [:foo], relation.where_values
    end

    test 'merge with a proc' do
      assert_equal [:foo], relation.merge(-> { where(:foo) }).where_values
    end

    test 'none!' do
      assert relation.none!.equal?(relation)
      assert_equal [NullRelation], relation.extending_values
      assert relation.is_a?(NullRelation)
    end

    test 'distinct!' do
      relation.distinct! :foo
      assert_equal :foo, relation.distinct_value
      assert_equal :foo, relation.uniq_value # deprecated access
    end

    test 'uniq! was replaced by distinct!' do
      relation.uniq! :foo
      assert_equal :foo, relation.distinct_value
      assert_equal :foo, relation.uniq_value # deprecated access
    end
  end
end