quoting_test.rb 6.9 KB
Newer Older
1
require "cases/helper"
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

module ActiveRecord
  module ConnectionAdapters
    class QuotingTest < ActiveRecord::TestCase
      def setup
        @quoter = Class.new { include Quoting }.new
      end

      def test_quoted_true
        assert_equal "'t'", @quoter.quoted_true
      end

      def test_quoted_false
        assert_equal "'f'", @quoter.quoted_false
      end

      def test_quote_column_name
19
        assert_equal "foo", @quoter.quote_column_name("foo")
20 21
      end

22
      def test_quote_table_name
23
        assert_equal "foo", @quoter.quote_table_name("foo")
24 25 26 27 28
      end

      def test_quote_table_name_calls_quote_column_name
        @quoter.extend(Module.new {
          def quote_column_name(string)
29
            "lol"
30 31
          end
        })
32
        assert_equal "lol", @quoter.quote_table_name("foo")
33 34
      end

35 36 37 38 39 40
      def test_quote_string
        assert_equal "''", @quoter.quote_string("'")
        assert_equal "\\\\", @quoter.quote_string("\\")
        assert_equal "hi''i", @quoter.quote_string("hi'i")
        assert_equal "hi\\\\i", @quoter.quote_string("hi\\i")
      end
41 42 43 44 45 46 47

      def test_quoted_date
        t = Date.today
        assert_equal t.to_s(:db), @quoter.quoted_date(t)
      end

      def test_quoted_time_utc
48
        with_timezone_config default: :utc do
49
          t = Time.now.change(usec: 0)
50 51
          assert_equal t.getutc.to_s(:db), @quoter.quoted_date(t)
        end
52 53 54
      end

      def test_quoted_time_local
55
        with_timezone_config default: :local do
56
          t = Time.now.change(usec: 0)
57 58
          assert_equal t.getlocal.to_s(:db), @quoter.quoted_date(t)
        end
59 60 61
      end

      def test_quoted_time_crazy
62
        with_timezone_config default: :asdfasdf do
63
          t = Time.now.change(usec: 0)
64 65
          assert_equal t.getlocal.to_s(:db), @quoter.quoted_date(t)
        end
66 67 68
      end

      def test_quoted_datetime_utc
69
        with_timezone_config default: :utc do
70
          t = Time.now.change(usec: 0).to_datetime
71 72
          assert_equal t.getutc.to_s(:db), @quoter.quoted_date(t)
        end
73 74 75 76 77
      end

      ###
      # DateTime doesn't define getlocal, so make sure it does nothing
      def test_quoted_datetime_local
78
        with_timezone_config default: :local do
79
          t = Time.now.change(usec: 0).to_datetime
80 81
          assert_equal t.to_s(:db), @quoter.quoted_date(t)
        end
82
      end
83 84

      def test_quote_with_quoted_id
85
        assert_deprecated { assert_equal 1, @quoter.quote(Struct.new(:quoted_id).new(1)) }
86 87 88
      end

      def test_quote_nil
89
        assert_equal "NULL", @quoter.quote(nil)
90 91 92
      end

      def test_quote_true
93
        assert_equal @quoter.quoted_true, @quoter.quote(true)
94 95 96
      end

      def test_quote_false
97
        assert_equal @quoter.quoted_false, @quoter.quote(false)
98
      end
99 100 101

      def test_quote_float
        float = 1.2
102
        assert_equal float.to_s, @quoter.quote(float)
103 104
      end

105 106
      def test_quote_integer
        integer = 1
107
        assert_equal integer.to_s, @quoter.quote(integer)
108 109 110 111
      end

      def test_quote_bignum
        bignum = 1 << 100
112
        assert_equal bignum.to_s, @quoter.quote(bignum)
113
      end
A
Aaron Patterson 已提交
114 115 116

      def test_quote_bigdecimal
        bigdec = BigDecimal.new((1 << 100).to_s)
117
        assert_equal bigdec.to_s("F"), @quoter.quote(bigdec)
A
Aaron Patterson 已提交
118
      end
119 120

      def test_dates_and_times
121
        @quoter.extend(Module.new { def quoted_date(value) "lol" end })
122 123 124
        assert_equal "'lol'", @quoter.quote(Date.today)
        assert_equal "'lol'", @quoter.quote(Time.now)
        assert_equal "'lol'", @quoter.quote(DateTime.now)
125
      end
A
Aaron Patterson 已提交
126

127 128 129 130
      def test_quoting_classes
        assert_equal "'Object'", @quoter.quote(Object)
      end

A
Aaron Patterson 已提交
131
      def test_crazy_object
132 133
        crazy = Object.new
        e = assert_raises(TypeError) do
134
          @quoter.quote(crazy)
135 136
        end
        assert_equal "can't quote Object", e.message
A
Aaron Patterson 已提交
137
      end
138 139

      def test_quote_string_no_column
140
        assert_equal "'lo\\\\l'", @quoter.quote('lo\l')
141 142
      end

143 144
      def test_quote_as_mb_chars_no_column
        string = ActiveSupport::Multibyte::Chars.new('lo\l')
145
        assert_equal "'lo\\\\l'", @quoter.quote(string)
146
      end
147 148 149 150

      def test_quote_duration
        assert_equal "1800", @quoter.quote(30.minutes)
      end
151
    end
152

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
    class TypeCastingTest < ActiveRecord::TestCase
      def setup
        @conn = ActiveRecord::Base.connection
      end

      def test_type_cast_symbol
        assert_equal "foo", @conn.type_cast(:foo)
      end

      def test_type_cast_date
        date = Date.today
        expected = @conn.quoted_date(date)
        assert_equal expected, @conn.type_cast(date)
      end

      def test_type_cast_time
        time = Time.now
        expected = @conn.quoted_date(time)
        assert_equal expected, @conn.type_cast(time)
      end

      def test_type_cast_numeric
        assert_equal 10, @conn.type_cast(10)
        assert_equal 2.2, @conn.type_cast(2.2)
      end

      def test_type_cast_nil
        assert_nil @conn.type_cast(nil)
      end

      def test_type_cast_unknown_should_raise_error
        obj = Class.new.new
        assert_raise(TypeError) { @conn.type_cast(obj) }
      end

      def test_type_cast_object_which_responds_to_quoted_id
        quoted_id_obj = Class.new {
          def quoted_id
            "'zomg'"
          end

          def id
            10
          end
        }.new
        assert_equal 10, @conn.type_cast(quoted_id_obj)

        quoted_id_obj = Class.new {
          def quoted_id
            "'zomg'"
          end
        }.new
        assert_raise(TypeError) { @conn.type_cast(quoted_id_obj) }
      end
    end

209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
    class QuoteBooleanTest < ActiveRecord::TestCase
      def setup
        @connection = ActiveRecord::Base.connection
      end

      def test_quote_returns_frozen_string
        assert_predicate @connection.quote(true), :frozen?
        assert_predicate @connection.quote(false), :frozen?
      end

      def test_type_cast_returns_frozen_value
        assert_predicate @connection.type_cast(true), :frozen?
        assert_predicate @connection.type_cast(false), :frozen?
      end
    end
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250

    if subsecond_precision_supported?
      class QuoteARBaseTest < ActiveRecord::TestCase
        class DatetimePrimaryKey < ActiveRecord::Base
        end

        def setup
          @time = ::Time.utc(2017, 2, 14, 12, 34, 56, 789999)
          @connection = ActiveRecord::Base.connection
          @connection.create_table :datetime_primary_keys, id: :datetime, precision: 3, force: true
        end

        def teardown
          @connection.drop_table :datetime_primary_keys, if_exists: true
        end

        def test_quote_ar_object
          value = DatetimePrimaryKey.new(id: @time)
          assert_equal "'2017-02-14 12:34:56.789000'",  @connection.quote(value)
        end

        def test_type_cast_ar_object
          value = DatetimePrimaryKey.new(id: @time)
          assert_equal "2017-02-14 12:34:56.789000",  @connection.type_cast(value)
        end
      end
    end
251 252
  end
end