diff options
-rw-r--r-- | activemodel/lib/active_model/type/helpers/time_value.rb | 10 | ||||
-rw-r--r-- | activemodel/test/cases/type/decimal_test.rb (renamed from activerecord/test/cases/type/decimal_test.rb) | 5 | ||||
-rw-r--r-- | activemodel/test/cases/type/integer_test.rb | 108 | ||||
-rw-r--r-- | activemodel/test/cases/type/string_test.rb | 20 | ||||
-rw-r--r-- | activemodel/test/cases/type/unsigned_integer_test.rb (renamed from activerecord/test/cases/type/unsigned_integer_test.rb) | 5 | ||||
-rw-r--r-- | activemodel/test/cases/types_test.rb | 121 | ||||
-rw-r--r-- | activerecord/test/cases/type/integer_test.rb | 100 | ||||
-rw-r--r-- | activerecord/test/cases/type/string_test.rb | 14 | ||||
-rw-r--r-- | activerecord/test/cases/types_test.rb | 105 |
9 files changed, 263 insertions, 225 deletions
diff --git a/activemodel/lib/active_model/type/helpers/time_value.rb b/activemodel/lib/active_model/type/helpers/time_value.rb index c55bb1e136..0a0e58654b 100644 --- a/activemodel/lib/active_model/type/helpers/time_value.rb +++ b/activemodel/lib/active_model/type/helpers/time_value.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/time/zones" + module ActiveModel module Type module Helpers @@ -21,11 +23,15 @@ module ActiveModel end def is_utc? - ::Time.zone_default =~ 'UTC' + ::Time.zone_default.nil? || ::Time.zone_default =~ 'UTC' end def default_timezone - ::Time.zone_default + if is_utc? + :utc + else + :local + end end def type_cast_for_schema(value) diff --git a/activerecord/test/cases/type/decimal_test.rb b/activemodel/test/cases/type/decimal_test.rb index 01ee36b892..353dbf84ad 100644 --- a/activerecord/test/cases/type/decimal_test.rb +++ b/activemodel/test/cases/type/decimal_test.rb @@ -1,8 +1,9 @@ require "cases/helper" +require "active_model/type" -module ActiveRecord +module ActiveModel module Type - class DecimalTest < ActiveRecord::TestCase + class DecimalTest < ActiveModel::TestCase def test_type_cast_decimal type = Decimal.new assert_equal BigDecimal.new("0"), type.cast(BigDecimal.new("0")) diff --git a/activemodel/test/cases/type/integer_test.rb b/activemodel/test/cases/type/integer_test.rb new file mode 100644 index 0000000000..dac922db42 --- /dev/null +++ b/activemodel/test/cases/type/integer_test.rb @@ -0,0 +1,108 @@ +require "cases/helper" +require "active_model/type" + +module ActiveModel + module Type + class IntegerTest < ActiveModel::TestCase + test "simple values" do + type = Type::Integer.new + assert_equal 1, type.cast(1) + assert_equal 1, type.cast('1') + assert_equal 1, type.cast('1ignore') + assert_equal 0, type.cast('bad1') + assert_equal 0, type.cast('bad') + assert_equal 1, type.cast(1.7) + assert_equal 0, type.cast(false) + assert_equal 1, type.cast(true) + assert_nil type.cast(nil) + end + + test "random objects cast to nil" do + type = Type::Integer.new + assert_nil type.cast([1,2]) + assert_nil type.cast({1 => 2}) + assert_nil type.cast(1..2) + end + + test "casting objects without to_i" do + type = Type::Integer.new + assert_nil type.cast(::Object.new) + end + + test "casting nan and infinity" do + type = Type::Integer.new + assert_nil type.cast(::Float::NAN) + assert_nil type.cast(1.0/0.0) + end + + test "casting booleans for database" do + type = Type::Integer.new + assert_equal 1, type.serialize(true) + assert_equal 0, type.serialize(false) + end + + test "changed?" do + type = Type::Integer.new + + assert type.changed?(5, 5, '5wibble') + assert_not type.changed?(5, 5, '5') + assert_not type.changed?(5, 5, '5.0') + assert_not type.changed?(-5, -5, '-5') + assert_not type.changed?(-5, -5, '-5.0') + assert_not type.changed?(nil, nil, nil) + end + + test "values below int min value are out of range" do + assert_raises(::RangeError) do + Integer.new.serialize(-2147483649) + end + end + + test "values above int max value are out of range" do + assert_raises(::RangeError) do + Integer.new.serialize(2147483648) + end + end + + test "very small numbers are out of range" do + assert_raises(::RangeError) do + Integer.new.serialize(-9999999999999999999999999999999) + end + end + + test "very large numbers are out of range" do + assert_raises(::RangeError) do + Integer.new.serialize(9999999999999999999999999999999) + end + end + + test "normal numbers are in range" do + type = Integer.new + assert_equal(0, type.serialize(0)) + assert_equal(-1, type.serialize(-1)) + assert_equal(1, type.serialize(1)) + end + + test "int max value is in range" do + assert_equal(2147483647, Integer.new.serialize(2147483647)) + end + + test "int min value is in range" do + assert_equal(-2147483648, Integer.new.serialize(-2147483648)) + end + + test "columns with a larger limit have larger ranges" do + type = Integer.new(limit: 8) + + assert_equal(9223372036854775807, type.serialize(9223372036854775807)) + assert_equal(-9223372036854775808, type.serialize(-9223372036854775808)) + assert_raises(::RangeError) do + type.serialize(-9999999999999999999999999999999) + end + assert_raises(::RangeError) do + type.serialize(9999999999999999999999999999999) + end + end + end + end +end diff --git a/activemodel/test/cases/type/string_test.rb b/activemodel/test/cases/type/string_test.rb new file mode 100644 index 0000000000..8ec771ea42 --- /dev/null +++ b/activemodel/test/cases/type/string_test.rb @@ -0,0 +1,20 @@ +require "cases/helper" +require "active_model/type" + +module ActiveModel + class StringTypeTest < ActiveModel::TestCase + test "type casting" do + type = Type::String.new + assert_equal "t", type.cast(true) + assert_equal "f", type.cast(false) + assert_equal "123", type.cast(123) + end + + test "values are duped coming out" do + s = "foo" + type = Type::String.new + assert_not_same s, type.cast(s) + assert_not_same s, type.deserialize(s) + end + end +end diff --git a/activerecord/test/cases/type/unsigned_integer_test.rb b/activemodel/test/cases/type/unsigned_integer_test.rb index f2c910eade..16301b3ac0 100644 --- a/activerecord/test/cases/type/unsigned_integer_test.rb +++ b/activemodel/test/cases/type/unsigned_integer_test.rb @@ -1,8 +1,9 @@ require "cases/helper" +require "active_model/type" -module ActiveRecord +module ActiveModel module Type - class UnsignedIntegerTest < ActiveRecord::TestCase + class UnsignedIntegerTest < ActiveModel::TestCase test "unsigned int max value is in range" do assert_equal(4294967295, UnsignedInteger.new.serialize(4294967295)) end diff --git a/activemodel/test/cases/types_test.rb b/activemodel/test/cases/types_test.rb new file mode 100644 index 0000000000..0bb971fa39 --- /dev/null +++ b/activemodel/test/cases/types_test.rb @@ -0,0 +1,121 @@ +require "cases/helper" +require "active_model/type" + +module ActiveModel + class TypesTest < ActiveModel::TestCase + def test_type_cast_boolean + type = Type::Boolean.new + assert type.cast('').nil? + assert type.cast(nil).nil? + + assert type.cast(true) + assert type.cast(1) + assert type.cast('1') + assert type.cast('t') + assert type.cast('T') + assert type.cast('true') + assert type.cast('TRUE') + assert type.cast('on') + assert type.cast('ON') + assert type.cast(' ') + assert type.cast("\u3000\r\n") + assert type.cast("\u0000") + assert type.cast('SOMETHING RANDOM') + + # explicitly check for false vs nil + assert_equal false, type.cast(false) + assert_equal false, type.cast(0) + assert_equal false, type.cast('0') + assert_equal false, type.cast('f') + assert_equal false, type.cast('F') + assert_equal false, type.cast('false') + assert_equal false, type.cast('FALSE') + assert_equal false, type.cast('off') + assert_equal false, type.cast('OFF') + end + + def test_type_cast_float + type = Type::Float.new + assert_equal 1.0, type.cast("1") + end + + def test_changing_float + type = Type::Float.new + + assert type.changed?(5.0, 5.0, '5wibble') + assert_not type.changed?(5.0, 5.0, '5') + assert_not type.changed?(5.0, 5.0, '5.0') + assert_not type.changed?(nil, nil, nil) + end + + def test_type_cast_binary + type = Type::Binary.new + assert_equal nil, type.cast(nil) + assert_equal "1", type.cast("1") + assert_equal 1, type.cast(1) + end + + def test_type_cast_time + type = Type::Time.new + assert_equal nil, type.cast(nil) + assert_equal nil, type.cast('') + assert_equal nil, type.cast('ABC') + + time_string = Time.now.utc.strftime("%T") + assert_equal time_string, type.cast(time_string).strftime("%T") + end + + def test_type_cast_datetime_and_timestamp + type = Type::DateTime.new + assert_equal nil, type.cast(nil) + assert_equal nil, type.cast('') + assert_equal nil, type.cast(' ') + assert_equal nil, type.cast('ABC') + + datetime_string = Time.now.utc.strftime("%FT%T") + assert_equal datetime_string, type.cast(datetime_string).strftime("%FT%T") + end + + def test_type_cast_date + type = Type::Date.new + assert_equal nil, type.cast(nil) + assert_equal nil, type.cast('') + assert_equal nil, type.cast(' ') + assert_equal nil, type.cast('ABC') + + date_string = Time.now.utc.strftime("%F") + assert_equal date_string, type.cast(date_string).strftime("%F") + end + + def test_type_cast_duration_to_integer + type = Type::Integer.new + assert_equal 1800, type.cast(30.minutes) + assert_equal 7200, type.cast(2.hours) + end + + def test_string_to_time_with_timezone + ["UTC", "US/Eastern"].each do |zone| + with_timezone_config default: zone do + type = Type::DateTime.new + assert_equal Time.utc(2013, 9, 4, 0, 0, 0), type.cast("Wed, 04 Sep 2013 03:00:00 EAT") + end + end + end + + def test_type_equality + assert_equal Type::Value.new, Type::Value.new + assert_not_equal Type::Value.new, Type::Integer.new + assert_not_equal Type::Value.new(precision: 1), Type::Value.new(precision: 2) + end + + private + + def with_timezone_config(default:) + old_zone_default = ::Time.zone_default + ::Time.zone_default = ::Time.find_zone(default) + yield + ensure + ::Time.zone_default = old_zone_default + end + end +end diff --git a/activerecord/test/cases/type/integer_test.rb b/activerecord/test/cases/type/integer_test.rb index 0dcdbd0667..c0932d5357 100644 --- a/activerecord/test/cases/type/integer_test.rb +++ b/activerecord/test/cases/type/integer_test.rb @@ -4,112 +4,12 @@ require "models/company" module ActiveRecord module Type class IntegerTest < ActiveRecord::TestCase - test "simple values" do - type = Type::Integer.new - assert_equal 1, type.cast(1) - assert_equal 1, type.cast('1') - assert_equal 1, type.cast('1ignore') - assert_equal 0, type.cast('bad1') - assert_equal 0, type.cast('bad') - assert_equal 1, type.cast(1.7) - assert_equal 0, type.cast(false) - assert_equal 1, type.cast(true) - assert_nil type.cast(nil) - end - - test "random objects cast to nil" do - type = Type::Integer.new - assert_nil type.cast([1,2]) - assert_nil type.cast({1 => 2}) - assert_nil type.cast(1..2) - end - test "casting ActiveRecord models" do type = Type::Integer.new firm = Firm.create(:name => 'Apple') assert_nil type.cast(firm) end - test "casting objects without to_i" do - type = Type::Integer.new - assert_nil type.cast(::Object.new) - end - - test "casting nan and infinity" do - type = Type::Integer.new - assert_nil type.cast(::Float::NAN) - assert_nil type.cast(1.0/0.0) - end - - test "casting booleans for database" do - type = Type::Integer.new - assert_equal 1, type.serialize(true) - assert_equal 0, type.serialize(false) - end - - test "changed?" do - type = Type::Integer.new - - assert type.changed?(5, 5, '5wibble') - assert_not type.changed?(5, 5, '5') - assert_not type.changed?(5, 5, '5.0') - assert_not type.changed?(-5, -5, '-5') - assert_not type.changed?(-5, -5, '-5.0') - assert_not type.changed?(nil, nil, nil) - end - - test "values below int min value are out of range" do - assert_raises(::RangeError) do - Integer.new.serialize(-2147483649) - end - end - - test "values above int max value are out of range" do - assert_raises(::RangeError) do - Integer.new.serialize(2147483648) - end - end - - test "very small numbers are out of range" do - assert_raises(::RangeError) do - Integer.new.serialize(-9999999999999999999999999999999) - end - end - - test "very large numbers are out of range" do - assert_raises(::RangeError) do - Integer.new.serialize(9999999999999999999999999999999) - end - end - - test "normal numbers are in range" do - type = Integer.new - assert_equal(0, type.serialize(0)) - assert_equal(-1, type.serialize(-1)) - assert_equal(1, type.serialize(1)) - end - - test "int max value is in range" do - assert_equal(2147483647, Integer.new.serialize(2147483647)) - end - - test "int min value is in range" do - assert_equal(-2147483648, Integer.new.serialize(-2147483648)) - end - - test "columns with a larger limit have larger ranges" do - type = Integer.new(limit: 8) - - assert_equal(9223372036854775807, type.serialize(9223372036854775807)) - assert_equal(-9223372036854775808, type.serialize(-9223372036854775808)) - assert_raises(::RangeError) do - type.serialize(-9999999999999999999999999999999) - end - assert_raises(::RangeError) do - type.serialize(9999999999999999999999999999999) - end - end - test "values which are out of range can be re-assigned" do klass = Class.new(ActiveRecord::Base) do self.table_name = 'posts' diff --git a/activerecord/test/cases/type/string_test.rb b/activerecord/test/cases/type/string_test.rb index 56e9bf434d..6fe6d46711 100644 --- a/activerecord/test/cases/type/string_test.rb +++ b/activerecord/test/cases/type/string_test.rb @@ -2,20 +2,6 @@ require 'cases/helper' module ActiveRecord class StringTypeTest < ActiveRecord::TestCase - test "type casting" do - type = Type::String.new - assert_equal "t", type.cast(true) - assert_equal "f", type.cast(false) - assert_equal "123", type.cast(123) - end - - test "values are duped coming out" do - s = "foo" - type = Type::String.new - assert_not_same s, type.cast(s) - assert_not_same s, type.deserialize(s) - end - test "string mutations are detected" do klass = Class.new(Base) klass.table_name = 'authors' diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb index 9b1859c2ce..81fcf04a27 100644 --- a/activerecord/test/cases/types_test.rb +++ b/activerecord/test/cases/types_test.rb @@ -3,111 +3,6 @@ require "cases/helper" module ActiveRecord module ConnectionAdapters class TypesTest < ActiveRecord::TestCase - def test_type_cast_boolean - type = Type::Boolean.new - assert type.cast('').nil? - assert type.cast(nil).nil? - - assert type.cast(true) - assert type.cast(1) - assert type.cast('1') - assert type.cast('t') - assert type.cast('T') - assert type.cast('true') - assert type.cast('TRUE') - assert type.cast('on') - assert type.cast('ON') - assert type.cast(' ') - assert type.cast("\u3000\r\n") - assert type.cast("\u0000") - assert type.cast('SOMETHING RANDOM') - - # explicitly check for false vs nil - assert_equal false, type.cast(false) - assert_equal false, type.cast(0) - assert_equal false, type.cast('0') - assert_equal false, type.cast('f') - assert_equal false, type.cast('F') - assert_equal false, type.cast('false') - assert_equal false, type.cast('FALSE') - assert_equal false, type.cast('off') - assert_equal false, type.cast('OFF') - end - - def test_type_cast_float - type = Type::Float.new - assert_equal 1.0, type.cast("1") - end - - def test_changing_float - type = Type::Float.new - - assert type.changed?(5.0, 5.0, '5wibble') - assert_not type.changed?(5.0, 5.0, '5') - assert_not type.changed?(5.0, 5.0, '5.0') - assert_not type.changed?(nil, nil, nil) - end - - def test_type_cast_binary - type = Type::Binary.new - assert_equal nil, type.cast(nil) - assert_equal "1", type.cast("1") - assert_equal 1, type.cast(1) - end - - def test_type_cast_time - type = Type::Time.new - assert_equal nil, type.cast(nil) - assert_equal nil, type.cast('') - assert_equal nil, type.cast('ABC') - - time_string = Time.now.utc.strftime("%T") - assert_equal time_string, type.cast(time_string).strftime("%T") - end - - def test_type_cast_datetime_and_timestamp - type = Type::DateTime.new - assert_equal nil, type.cast(nil) - assert_equal nil, type.cast('') - assert_equal nil, type.cast(' ') - assert_equal nil, type.cast('ABC') - - datetime_string = Time.now.utc.strftime("%FT%T") - assert_equal datetime_string, type.cast(datetime_string).strftime("%FT%T") - end - - def test_type_cast_date - type = Type::Date.new - assert_equal nil, type.cast(nil) - assert_equal nil, type.cast('') - assert_equal nil, type.cast(' ') - assert_equal nil, type.cast('ABC') - - date_string = Time.now.utc.strftime("%F") - assert_equal date_string, type.cast(date_string).strftime("%F") - end - - def test_type_cast_duration_to_integer - type = Type::Integer.new - assert_equal 1800, type.cast(30.minutes) - assert_equal 7200, type.cast(2.hours) - end - - def test_string_to_time_with_timezone - [:utc, :local].each do |zone| - with_timezone_config default: zone do - type = Type::DateTime.new - assert_equal Time.utc(2013, 9, 4, 0, 0, 0), type.cast("Wed, 04 Sep 2013 03:00:00 EAT") - end - end - end - - def test_type_equality - assert_equal Type::Value.new, Type::Value.new - assert_not_equal Type::Value.new, Type::Integer.new - assert_not_equal Type::Value.new(precision: 1), Type::Value.new(precision: 2) - end - def test_attributes_which_are_invalid_for_database_can_still_be_reassigned type_which_cannot_go_to_the_database = Type::Value.new def type_which_cannot_go_to_the_database.serialize(*) |