From 68926798a53bb98e56efe9a96e321a33cc0fa995 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Wed, 21 Dec 2016 15:33:37 -0800 Subject: Fix invalid string Decimal casting under ruby 2.4 In Ruby 2.4, BigDecimal(), as used by the Decimal cast, was changed so that it will raise ArgumentError when passed an invalid string, in order to be more consistent with Integer(), Float(), etc. The other numeric types use ex. to_i and to_f. Unfortunately, we can't simply change BigDecimal() to to_d. String#to_d raises errors like BigDecimal(), unlike all the other to_* methods (this should probably be filed as a ruby bug). Instead, this simulates the existing behaviour and the behaviour of the other to_* methods by finding a numeric string at the start of the passed in value, and parsing that using BigDecimal(). See also https://bugs.ruby-lang.org/issues/10286 https://github.com/ruby/bigdecimal/commit/3081a627cebdc1fc119425c7a9f009dbb6bec8e8 --- activemodel/test/cases/type/decimal_test.rb | 8 ++++++++ activemodel/test/cases/type/float_test.rb | 8 ++++++++ activemodel/test/cases/type/integer_test.rb | 1 + 3 files changed, 17 insertions(+) (limited to 'activemodel/test/cases/type') diff --git a/activemodel/test/cases/type/decimal_test.rb b/activemodel/test/cases/type/decimal_test.rb index 46a913258e..c3b43725cc 100644 --- a/activemodel/test/cases/type/decimal_test.rb +++ b/activemodel/test/cases/type/decimal_test.rb @@ -11,6 +11,14 @@ module ActiveModel assert_equal BigDecimal.new("1"), type.cast(:"1") end + def test_type_cast_decimal_from_invalid_string + type = Decimal.new + assert_nil type.cast("") + assert_equal BigDecimal.new("1"), type.cast("1ignore") + assert_equal BigDecimal.new("0"), type.cast("bad1") + assert_equal BigDecimal.new("0"), type.cast("bad") + end + def test_type_cast_decimal_from_float_with_large_precision type = Decimal.new(precision: ::Float::DIG + 2) assert_equal BigDecimal.new("123.0"), type.cast(123.0) diff --git a/activemodel/test/cases/type/float_test.rb b/activemodel/test/cases/type/float_test.rb index 2e34f57f7e..8026d63ad5 100644 --- a/activemodel/test/cases/type/float_test.rb +++ b/activemodel/test/cases/type/float_test.rb @@ -9,6 +9,14 @@ module ActiveModel assert_equal 1.0, type.cast("1") end + def test_type_cast_float_from_invalid_string + type = Type::Float.new + assert_nil type.cast("") + assert_equal 1.0, type.cast("1ignore") + assert_equal 0.0, type.cast("bad1") + assert_equal 0.0, type.cast("bad") + end + def test_changing_float type = Type::Float.new diff --git a/activemodel/test/cases/type/integer_test.rb b/activemodel/test/cases/type/integer_test.rb index 2b9b03f3cf..a91144036b 100644 --- a/activemodel/test/cases/type/integer_test.rb +++ b/activemodel/test/cases/type/integer_test.rb @@ -7,6 +7,7 @@ module ActiveModel class IntegerTest < ActiveModel::TestCase test "simple values" do type = Type::Integer.new + assert_nil type.cast("") assert_equal 1, type.cast(1) assert_equal 1, type.cast("1") assert_equal 1, type.cast("1ignore") -- cgit v1.2.3