2017-07-09 13:41:28 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2011-06-06 14:17:44 -04:00
|
|
|
require "cases/helper"
|
2010-10-11 20:08:40 -04:00
|
|
|
|
|
|
|
module ActiveRecord
|
|
|
|
module ConnectionAdapters
|
|
|
|
class QuotingTest < ActiveRecord::TestCase
|
|
|
|
def setup
|
|
|
|
@quoter = Class.new { include Quoting }.new
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_quoted_true
|
2017-07-06 12:59:33 -04:00
|
|
|
assert_equal "TRUE", @quoter.quoted_true
|
2010-10-11 20:08:40 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_quoted_false
|
2017-07-06 12:59:33 -04:00
|
|
|
assert_equal "FALSE", @quoter.quoted_false
|
2010-10-11 20:08:40 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_quote_column_name
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal "foo", @quoter.quote_column_name("foo")
|
2010-10-11 20:08:40 -04:00
|
|
|
end
|
|
|
|
|
2010-10-11 20:40:36 -04:00
|
|
|
def test_quote_table_name
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal "foo", @quoter.quote_table_name("foo")
|
2010-10-11 20:40:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_quote_table_name_calls_quote_column_name
|
|
|
|
@quoter.extend(Module.new {
|
|
|
|
def quote_column_name(string)
|
2016-08-06 12:26:20 -04:00
|
|
|
"lol"
|
2010-10-11 20:40:36 -04:00
|
|
|
end
|
|
|
|
})
|
2016-08-06 12:26:20 -04:00
|
|
|
assert_equal "lol", @quoter.quote_table_name("foo")
|
2010-10-11 20:40:36 -04:00
|
|
|
end
|
|
|
|
|
2010-10-11 20:08:40 -04:00
|
|
|
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
|
2010-10-11 20:40:36 -04:00
|
|
|
|
|
|
|
def test_quoted_date
|
|
|
|
t = Date.today
|
|
|
|
assert_equal t.to_s(:db), @quoter.quoted_date(t)
|
|
|
|
end
|
|
|
|
|
2018-03-11 14:30:19 -04:00
|
|
|
def test_quoted_timestamp_utc
|
2013-10-24 15:26:23 -04:00
|
|
|
with_timezone_config default: :utc do
|
2015-02-10 13:52:01 -05:00
|
|
|
t = Time.now.change(usec: 0)
|
2013-07-28 23:37:55 -04:00
|
|
|
assert_equal t.getutc.to_s(:db), @quoter.quoted_date(t)
|
|
|
|
end
|
2010-10-11 20:40:36 -04:00
|
|
|
end
|
|
|
|
|
2018-03-11 14:30:19 -04:00
|
|
|
def test_quoted_timestamp_local
|
2013-10-24 15:26:23 -04:00
|
|
|
with_timezone_config default: :local do
|
2015-02-10 13:52:01 -05:00
|
|
|
t = Time.now.change(usec: 0)
|
2013-07-28 23:37:55 -04:00
|
|
|
assert_equal t.getlocal.to_s(:db), @quoter.quoted_date(t)
|
|
|
|
end
|
2010-10-11 20:40:36 -04:00
|
|
|
end
|
|
|
|
|
2018-03-11 14:30:19 -04:00
|
|
|
def test_quoted_timestamp_crazy
|
2013-10-24 15:26:23 -04:00
|
|
|
with_timezone_config default: :asdfasdf do
|
2015-02-10 13:52:01 -05:00
|
|
|
t = Time.now.change(usec: 0)
|
2013-07-28 23:37:55 -04:00
|
|
|
assert_equal t.getlocal.to_s(:db), @quoter.quoted_date(t)
|
|
|
|
end
|
2010-10-11 20:40:36 -04:00
|
|
|
end
|
|
|
|
|
2018-03-11 14:30:19 -04:00
|
|
|
def test_quoted_time_utc
|
|
|
|
with_timezone_config default: :utc do
|
|
|
|
t = Time.now.change(usec: 0)
|
|
|
|
|
2018-07-17 00:14:15 -04:00
|
|
|
expected = t.change(year: 2000, month: 1, day: 1)
|
|
|
|
expected = expected.getutc.to_s(:db).slice(11..-1)
|
2018-03-11 14:30:19 -04:00
|
|
|
|
|
|
|
assert_equal expected, @quoter.quoted_time(t)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_quoted_time_local
|
|
|
|
with_timezone_config default: :local do
|
|
|
|
t = Time.now.change(usec: 0)
|
|
|
|
|
|
|
|
expected = t.change(year: 2000, month: 1, day: 1)
|
|
|
|
expected = expected.getlocal.to_s(:db).sub("2000-01-01 ", "")
|
|
|
|
|
|
|
|
assert_equal expected, @quoter.quoted_time(t)
|
|
|
|
end
|
|
|
|
end
|
2018-07-17 00:14:15 -04:00
|
|
|
|
|
|
|
def test_quoted_time_dst_utc
|
2018-07-24 20:42:36 -04:00
|
|
|
with_env_tz "America/New_York" do
|
|
|
|
with_timezone_config default: :utc do
|
|
|
|
t = Time.new(2000, 7, 1, 0, 0, 0, "+04:30")
|
2018-07-17 00:14:15 -04:00
|
|
|
|
2018-07-24 20:42:36 -04:00
|
|
|
expected = t.change(year: 2000, month: 1, day: 1)
|
|
|
|
expected = expected.getutc.to_s(:db).slice(11..-1)
|
2018-07-17 00:14:15 -04:00
|
|
|
|
2018-07-24 20:42:36 -04:00
|
|
|
assert_equal expected, @quoter.quoted_time(t)
|
|
|
|
end
|
2018-07-17 00:14:15 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_quoted_time_dst_local
|
2018-07-24 20:42:36 -04:00
|
|
|
with_env_tz "America/New_York" do
|
|
|
|
with_timezone_config default: :local do
|
|
|
|
t = Time.new(2000, 7, 1, 0, 0, 0, "+04:30")
|
2018-07-17 00:14:15 -04:00
|
|
|
|
2018-07-24 20:42:36 -04:00
|
|
|
expected = t.change(year: 2000, month: 1, day: 1)
|
|
|
|
expected = expected.getlocal.to_s(:db).slice(11..-1)
|
2018-07-17 00:14:15 -04:00
|
|
|
|
2018-07-24 20:42:36 -04:00
|
|
|
assert_equal expected, @quoter.quoted_time(t)
|
|
|
|
end
|
2018-07-17 00:14:15 -04:00
|
|
|
end
|
|
|
|
end
|
2018-03-11 14:30:19 -04:00
|
|
|
|
|
|
|
def test_quoted_time_crazy
|
|
|
|
with_timezone_config default: :asdfasdf do
|
|
|
|
t = Time.now.change(usec: 0)
|
|
|
|
|
|
|
|
expected = t.change(year: 2000, month: 1, day: 1)
|
|
|
|
expected = expected.getlocal.to_s(:db).sub("2000-01-01 ", "")
|
|
|
|
|
|
|
|
assert_equal expected, @quoter.quoted_time(t)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-10-11 20:40:36 -04:00
|
|
|
def test_quoted_datetime_utc
|
2013-10-24 15:26:23 -04:00
|
|
|
with_timezone_config default: :utc do
|
2015-02-10 13:52:01 -05:00
|
|
|
t = Time.now.change(usec: 0).to_datetime
|
2013-07-28 23:37:55 -04:00
|
|
|
assert_equal t.getutc.to_s(:db), @quoter.quoted_date(t)
|
|
|
|
end
|
2010-10-11 20:40:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
###
|
|
|
|
# DateTime doesn't define getlocal, so make sure it does nothing
|
|
|
|
def test_quoted_datetime_local
|
2013-10-24 15:26:23 -04:00
|
|
|
with_timezone_config default: :local do
|
2015-02-10 13:52:01 -05:00
|
|
|
t = Time.now.change(usec: 0).to_datetime
|
2013-07-28 23:37:55 -04:00
|
|
|
assert_equal t.to_s(:db), @quoter.quoted_date(t)
|
|
|
|
end
|
2010-10-11 20:40:36 -04:00
|
|
|
end
|
2010-10-11 20:51:48 -04:00
|
|
|
|
|
|
|
def test_quote_nil
|
2016-12-29 02:20:50 -05:00
|
|
|
assert_equal "NULL", @quoter.quote(nil)
|
2010-10-11 20:51:48 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_quote_true
|
2016-12-29 02:20:50 -05:00
|
|
|
assert_equal @quoter.quoted_true, @quoter.quote(true)
|
2010-10-11 20:51:48 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_quote_false
|
2016-12-29 02:20:50 -05:00
|
|
|
assert_equal @quoter.quoted_false, @quoter.quote(false)
|
2010-10-11 20:51:48 -04:00
|
|
|
end
|
2010-10-11 20:57:47 -04:00
|
|
|
|
|
|
|
def test_quote_float
|
|
|
|
float = 1.2
|
2016-12-29 02:20:50 -05:00
|
|
|
assert_equal float.to_s, @quoter.quote(float)
|
2010-10-11 20:57:47 -04:00
|
|
|
end
|
|
|
|
|
2016-05-17 10:56:08 -04:00
|
|
|
def test_quote_integer
|
|
|
|
integer = 1
|
2016-12-29 02:20:50 -05:00
|
|
|
assert_equal integer.to_s, @quoter.quote(integer)
|
2010-10-11 20:57:47 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_quote_bignum
|
|
|
|
bignum = 1 << 100
|
2016-12-29 02:20:50 -05:00
|
|
|
assert_equal bignum.to_s, @quoter.quote(bignum)
|
2010-10-11 20:57:47 -04:00
|
|
|
end
|
2010-10-12 14:08:10 -04:00
|
|
|
|
|
|
|
def test_quote_bigdecimal
|
Suppress `warning: BigDecimal.new is deprecated` in activerecord
`BigDecimal.new` has been deprecated in BigDecimal 1.3.3
which will be a default for Ruby 2.5.
Refer https://github.com/ruby/bigdecimal/commit/533737338db915b00dc7168c3602e4b462b23503
```
$ cd rails/activerecord/
$ git grep -l BigDecimal.new | grep \.rb | xargs sed -i -e "s/BigDecimal.new/BigDecimal/g"
```
- Changes made only to Active Record. Will apply the same change to
other module once this commit is merged.
- The following deprecation has not been addressed because it has been
reported at `ActiveRecord::Result.new`. `ActiveRecord::Result.ancestors`
did not show `BigDecimal`.
* Not addressed
```ruby
/path/to/rails/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb:34:
warning: BigDecimal.new is deprecated
```
* database_statements.rb:34
```ruby
ActiveRecord::Result.new(result.fields, result.to_a) if result
```
* ActiveRecord::Result.ancestors
```ruby
[ActiveRecord::Result,
Enumerable,
ActiveSupport::ToJsonWithActiveSupportEncoder,
Object,
Metaclass::ObjectMethods,
Mocha::ObjectMethods,
PP::ObjectMixin,
ActiveSupport::Dependencies::Loadable,
ActiveSupport::Tryable,
JSON::Ext::Generator::GeneratorMethods::Object,
Kernel,
BasicObject]
```
This commit has been tested with these Ruby and BigDecimal versions
- ruby 2.5 and bigdecimal 1.3.3
```
$ ruby -v
ruby 2.5.0dev (2017-12-14 trunk 61217) [x86_64-linux]
$ gem list |grep bigdecimal
bigdecimal (default: 1.3.3, default: 1.3.2)
```
- ruby 2.4 and bigdecimal 1.3.0
```
$ ruby -v
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux-gnu]
$ gem list |grep bigdecimal
bigdecimal (default: 1.3.0)
```
- ruby 2.3 and bigdecimal 1.2.8
```
$ ruby -v
ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-linux]
$ gem list |grep -i bigdecimal
bigdecimal (1.2.8)
```
- ruby 2.2 and bigdecimal 1.2.6
```
$ ruby -v
ruby 2.2.8p477 (2017-09-14 revision 59906) [x86_64-linux]
$ gem list |grep bigdecimal
bigdecimal (1.2.6)
```
2017-12-13 14:46:46 -05:00
|
|
|
bigdec = BigDecimal((1 << 100).to_s)
|
2016-12-29 02:20:50 -05:00
|
|
|
assert_equal bigdec.to_s("F"), @quoter.quote(bigdec)
|
2010-10-12 14:08:10 -04:00
|
|
|
end
|
2010-10-12 14:21:35 -04:00
|
|
|
|
|
|
|
def test_dates_and_times
|
2016-08-06 12:26:20 -04:00
|
|
|
@quoter.extend(Module.new { def quoted_date(value) "lol" end })
|
2016-12-29 02:20:50 -05:00
|
|
|
assert_equal "'lol'", @quoter.quote(Date.today)
|
|
|
|
assert_equal "'lol'", @quoter.quote(Time.now)
|
|
|
|
assert_equal "'lol'", @quoter.quote(DateTime.now)
|
2010-10-12 14:21:35 -04:00
|
|
|
end
|
2010-10-12 14:25:20 -04:00
|
|
|
|
2016-09-10 19:21:37 -04:00
|
|
|
def test_quoting_classes
|
|
|
|
assert_equal "'Object'", @quoter.quote(Object)
|
|
|
|
end
|
|
|
|
|
2010-10-12 14:25:20 -04:00
|
|
|
def test_crazy_object
|
2015-01-14 15:55:29 -05:00
|
|
|
crazy = Object.new
|
|
|
|
e = assert_raises(TypeError) do
|
2016-12-29 02:20:50 -05:00
|
|
|
@quoter.quote(crazy)
|
2015-01-14 15:55:29 -05:00
|
|
|
end
|
|
|
|
assert_equal "can't quote Object", e.message
|
2010-10-12 14:25:20 -04:00
|
|
|
end
|
2010-10-12 14:29:28 -04:00
|
|
|
|
|
|
|
def test_quote_string_no_column
|
2016-09-11 03:14:44 -04:00
|
|
|
assert_equal "'lo\\\\l'", @quoter.quote('lo\l')
|
2010-10-12 14:29:28 -04:00
|
|
|
end
|
|
|
|
|
2010-10-12 14:38:07 -04:00
|
|
|
def test_quote_as_mb_chars_no_column
|
|
|
|
string = ActiveSupport::Multibyte::Chars.new('lo\l')
|
2016-09-11 03:14:44 -04:00
|
|
|
assert_equal "'lo\\\\l'", @quoter.quote(string)
|
2010-10-12 14:43:50 -04:00
|
|
|
end
|
2012-07-04 23:39:16 -04:00
|
|
|
|
|
|
|
def test_quote_duration
|
|
|
|
assert_equal "1800", @quoter.quote(30.minutes)
|
|
|
|
end
|
2010-10-11 20:08:40 -04:00
|
|
|
end
|
2016-06-15 17:14:12 -04:00
|
|
|
|
2017-02-14 13:17:01 -05:00
|
|
|
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
|
2017-07-18 13:04:47 -04:00
|
|
|
if current_adapter?(:Mysql2Adapter)
|
|
|
|
expected = date
|
|
|
|
else
|
|
|
|
expected = @conn.quoted_date(date)
|
|
|
|
end
|
2017-02-14 13:17:01 -05:00
|
|
|
assert_equal expected, @conn.type_cast(date)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_type_cast_time
|
|
|
|
time = Time.now
|
2017-07-18 13:04:47 -04:00
|
|
|
if current_adapter?(:Mysql2Adapter)
|
|
|
|
expected = time
|
|
|
|
else
|
|
|
|
expected = @conn.quoted_date(time)
|
|
|
|
end
|
2017-02-14 13:17:01 -05:00
|
|
|
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
|
|
|
|
end
|
|
|
|
|
2016-06-15 17:14:12 -04:00
|
|
|
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
|
2017-02-14 13:52:18 -05:00
|
|
|
|
|
|
|
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)
|
2017-07-18 13:04:47 -04:00
|
|
|
assert_equal @connection.type_cast(value.id), @connection.type_cast(value)
|
2017-02-14 13:52:18 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2010-10-11 20:08:40 -04:00
|
|
|
end
|
|
|
|
end
|