summaryrefslogtreecommitdiff
path: root/test/ruby/test_numeric.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_numeric.rb')
-rw-r--r--test/ruby/test_numeric.rb243
1 files changed, 201 insertions, 42 deletions
diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb
index ad5e283152..35496ac875 100644
--- a/test/ruby/test_numeric.rb
+++ b/test/ruby/test_numeric.rb
@@ -4,8 +4,8 @@ require 'test/unit'
class TestNumeric < Test::Unit::TestCase
def test_coerce
a, b = 1.coerce(2)
- assert_equal(Fixnum, a.class)
- assert_equal(Fixnum, b.class)
+ assert_kind_of(Integer, a)
+ assert_kind_of(Integer, b)
a, b = 1.coerce(2.0)
assert_equal(Float, a.class)
@@ -18,13 +18,19 @@ class TestNumeric < Test::Unit::TestCase
assert_raise_with_message(TypeError, /can't be coerced into /) {1|:foo}
assert_raise_with_message(TypeError, /can't be coerced into /) {1^:foo}
- EnvUtil.with_default_external(Encoding::UTF_8) do
+ EnvUtil.with_default_internal(Encoding::UTF_8) do
assert_raise_with_message(TypeError, /:\u{3042}/) {1+:"\u{3042}"}
assert_raise_with_message(TypeError, /:\u{3042}/) {1&:"\u{3042}"}
assert_raise_with_message(TypeError, /:\u{3042}/) {1|:"\u{3042}"}
assert_raise_with_message(TypeError, /:\u{3042}/) {1^:"\u{3042}"}
+
+ assert_raise_with_message(TypeError, /:\u{3044}/) {1+"\u{3044}".to_sym}
+ assert_raise_with_message(TypeError, /:\u{3044}/) {1&"\u{3044}".to_sym}
+ assert_raise_with_message(TypeError, /:\u{3044}/) {1|"\u{3044}".to_sym}
+ assert_raise_with_message(TypeError, /:\u{3044}/) {1^"\u{3044}".to_sym}
end
- EnvUtil.with_default_external(Encoding::US_ASCII) do
+
+ EnvUtil.with_default_internal(Encoding::US_ASCII) do
assert_raise_with_message(TypeError, /:"\\u3042"/) {1+:"\u{3042}"}
assert_raise_with_message(TypeError, /:"\\u3042"/) {1&:"\u{3042}"}
assert_raise_with_message(TypeError, /:"\\u3042"/) {1|:"\u{3042}"}
@@ -32,7 +38,7 @@ class TestNumeric < Test::Unit::TestCase
end
bug10711 = '[ruby-core:67405] [Bug #10711]'
- exp = "1.2 can't be coerced into Fixnum"
+ exp = "1.2 can't be coerced into Integer"
assert_raise_with_message(TypeError, exp, bug10711) { 1 & 1.2 }
end
@@ -56,20 +62,17 @@ class TestNumeric < Test::Unit::TestCase
end.new
assert_equal(-1, -a)
- bug7688 = '[ruby-core:51389] [Bug #7688]'
a = Class.new(Numeric) do
- def coerce(x); raise StandardError; end
+ def coerce(x); raise StandardError, "my error"; end
end.new
- assert_raise_with_message(TypeError, /can't be coerced into /) { 1 + a }
- warn = /will no more rescue exceptions of #coerce.+ in the next release/m
- assert_warn(warn, bug7688) { assert_raise(ArgumentError) { 1 < a } }
+ assert_raise_with_message(StandardError, "my error") { 1 + a }
+ assert_raise_with_message(StandardError, "my error") { 1 < a }
a = Class.new(Numeric) do
def coerce(x); :bad_return_value; end
end.new
assert_raise_with_message(TypeError, "coerce must return [x, y]") { 1 + a }
- warn = /Bad return value for #coerce.+next release will raise an error/m
- assert_warn(warn, bug7688) { assert_raise(ArgumentError) { 1 < a } }
+ assert_raise_with_message(TypeError, "coerce must return [x, y]") { 1 < a }
end
def test_singleton_method
@@ -80,12 +83,18 @@ class TestNumeric < Test::Unit::TestCase
def test_dup
a = Numeric.new
- assert_raise(TypeError) { a.dup }
+ assert_same a, a.dup
+ end
+
+ def test_clone
+ a = Numeric.new
+ assert_same a, a.clone
+ assert_raise(ArgumentError) {a.clone(freeze: false)}
- c = Module.new do
- break eval("class C\u{3042} < Numeric; self; end")
+ c = EnvUtil.labeled_class("\u{1f4a9}", Numeric)
+ assert_raise_with_message(ArgumentError, /\u{1f4a9}/) do
+ c.new.clone(freeze: false)
end
- assert_raise_with_message(TypeError, /C\u3042/) {c.new.dup}
end
def test_quo
@@ -147,6 +156,18 @@ class TestNumeric < Test::Unit::TestCase
assert_predicate(a, :zero?)
end
+ def test_nonzero_p
+ a = Class.new(Numeric) do
+ def zero?; true; end
+ end.new
+ assert_nil(a.nonzero?)
+
+ a = Class.new(Numeric) do
+ def zero?; false; end
+ end.new
+ assert_equal(a, a.nonzero?)
+ end
+
def test_positive_p
a = Class.new(Numeric) do
def >(x); true; end
@@ -185,6 +206,14 @@ class TestNumeric < Test::Unit::TestCase
assert_nil(a <=> :foo)
end
+ def test_float_round_ndigits
+ bug14635 = "[ruby-core:86323]"
+ f = 0.5
+ 31.times do |i|
+ assert_equal(0.5, f.round(i+1), bug14635 + " (argument: #{i+1})")
+ end
+ end
+
def test_floor_ceil_round_truncate
a = Class.new(Numeric) do
def to_f; 1.5; end
@@ -214,8 +243,18 @@ class TestNumeric < Test::Unit::TestCase
assert_equal(-1, a.truncate)
end
+ def test_floor_ceil_ndigits
+ bug17183 = "[ruby-core:100090]"
+ f = 291.4
+ 31.times do |i|
+ assert_equal(291.4, f.floor(i+1), bug17183)
+ assert_equal(291.4, f.ceil(i+1), bug17183)
+ end
+ end
+
def assert_step(expected, (from, *args), inf: false)
- enum = from.step(*args)
+ kw = args.last.is_a?(Hash) ? args.pop : {}
+ enum = from.step(*args, **kw)
size = enum.size
xsize = expected.size
@@ -224,7 +263,7 @@ class TestNumeric < Test::Unit::TestCase
assert_send [size, :>, 0], "step size: +infinity"
a = []
- from.step(*args) { |x| a << x; break if a.size == xsize }
+ from.step(*args, **kw) { |x| a << x; break if a.size == xsize }
assert_equal expected, a, "step"
a = []
@@ -234,7 +273,7 @@ class TestNumeric < Test::Unit::TestCase
assert_equal expected.size, size, "step size"
a = []
- from.step(*args) { |x| a << x }
+ from.step(*args, **kw) { |x| a << x }
assert_equal expected, a, "step"
a = []
@@ -244,23 +283,25 @@ class TestNumeric < Test::Unit::TestCase
end
def test_step
- i, bignum = 32, 1 << 30
- bignum <<= (i <<= 1) - 32 until bignum.is_a?(Bignum)
+ bignum = RbConfig::LIMITS['FIXNUM_MAX'] + 1
assert_raise(ArgumentError) { 1.step(10, 1, 0) { } }
assert_raise(ArgumentError) { 1.step(10, 1, 0).size }
assert_raise(ArgumentError) { 1.step(10, 0) { } }
- assert_raise(ArgumentError) { 1.step(10, 0).size }
assert_raise(ArgumentError) { 1.step(10, "1") { } }
assert_raise(ArgumentError) { 1.step(10, "1").size }
assert_raise(TypeError) { 1.step(10, nil) { } }
- assert_raise(TypeError) { 1.step(10, nil).size }
- assert_nothing_raised { 1.step(by: 0, to: nil) }
- assert_nothing_raised { 1.step(by: 0, to: nil).size }
- assert_nothing_raised { 1.step(by: 0) }
- assert_nothing_raised { 1.step(by: 0).size }
+ assert_nothing_raised { 1.step(10, nil).size }
assert_nothing_raised { 1.step(by: nil) }
assert_nothing_raised { 1.step(by: nil).size }
+ assert_kind_of(Enumerator::ArithmeticSequence, 1.step(10))
+ assert_kind_of(Enumerator::ArithmeticSequence, 1.step(10, 2))
+ assert_kind_of(Enumerator::ArithmeticSequence, 1.step(10, by: 2))
+ assert_kind_of(Enumerator::ArithmeticSequence, 1.step(by: 2))
+ assert_kind_of(Enumerator::ArithmeticSequence, 1.step(by: 2, to: nil))
+ assert_kind_of(Enumerator::ArithmeticSequence, 1.step(by: 2, to: 10))
+ assert_kind_of(Enumerator::ArithmeticSequence, 1.step(by: -1))
+
bug9811 = '[ruby-dev:48177] [Bug #9811]'
assert_raise(ArgumentError, bug9811) { 1.step(10, foo: nil) {} }
assert_raise(ArgumentError, bug9811) { 1.step(10, foo: nil).size }
@@ -269,6 +310,30 @@ class TestNumeric < Test::Unit::TestCase
assert_raise(ArgumentError, bug9811) { 1.step(10, 1, by: 11) {} }
assert_raise(ArgumentError, bug9811) { 1.step(10, 1, by: 11).size }
+ feature15573 = "[ruby-core:91324] [Feature #15573]"
+ assert_raise(ArgumentError, feature15573) { 1.step(10, 0) }
+ assert_raise(ArgumentError, feature15573) { 1.step(10, by: 0) }
+ assert_raise(ArgumentError, feature15573) { 1.step(10, 0) { break } }
+ assert_raise(ArgumentError, feature15573) { 1.step(10, by: 0) { break } }
+ assert_raise(ArgumentError, feature15573) { 42.step(by: 0, to: -Float::INFINITY) }
+ assert_raise(ArgumentError, feature15573) { 42.step(by: 0, to: 42.5) }
+ assert_raise(ArgumentError, feature15573) { 4.2.step(by: 0.0) }
+ assert_raise(ArgumentError, feature15573) { 4.2.step(by: -0.0) }
+ assert_raise(ArgumentError, feature15573) { 42.step(by: 0.0, to: 44) }
+ assert_raise(ArgumentError, feature15573) { 42.step(by: 0.0, to: 0) }
+ assert_raise(ArgumentError, feature15573) { 42.step(by: -0.0, to: 44) }
+ assert_raise(ArgumentError, feature15573) { bignum.step(by: 0) }
+ assert_raise(ArgumentError, feature15573) { bignum.step(by: 0.0) }
+ assert_raise(ArgumentError, feature15573) { bignum.step(by: 0, to: bignum+1) }
+ assert_raise(ArgumentError, feature15573) { bignum.step(by: 0, to: 0) }
+
+ e = 1.step(10, {by: "1"})
+ assert_raise(TypeError) {e.next}
+ assert_raise(TypeError) {e.size}
+ e = 1.step(to: "10")
+ assert_raise(ArgumentError) {e.next}
+ assert_raise(ArgumentError) {e.size}
+
assert_equal(bignum*2+1, (-bignum).step(bignum, 1).size)
assert_equal(bignum*2, (-bignum).step(bignum-1, 1).size)
@@ -278,7 +343,6 @@ class TestNumeric < Test::Unit::TestCase
i <<= 1 until (bigflo - i).to_i < bignum
bigflo -= i >> 1
assert_equal(bigflo.to_i, (0.0).step(bigflo-1.0, 1.0).size)
- assert_operator((0.0).step(bignum.to_f, 1.0).size, :>=, bignum) # may loose precision
assert_step [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 10]
assert_step [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, to: 10]
@@ -295,8 +359,6 @@ class TestNumeric < Test::Unit::TestCase
assert_step [], [2, 1, 3]
assert_step [], [-2, -1, -3]
- assert_step [3, 3, 3, 3], [3, by: 0], inf: true
- assert_step [3, 3, 3, 3], [3, by: 0, to: 42], inf: true
assert_step [10], [10, 1, -bignum]
assert_step [], [1, 0, Float::INFINITY]
@@ -306,19 +368,20 @@ class TestNumeric < Test::Unit::TestCase
assert_step [10, 11, 12, 13], [10], inf: true
assert_step [10, 9, 8, 7], [10, by: -1], inf: true
assert_step [10, 9, 8, 7], [10, by: -1, to: nil], inf: true
+ end
- assert_step [42, 42, 42, 42], [42, by: 0, to: -Float::INFINITY], inf: true
- assert_step [42, 42, 42, 42], [42, by: 0, to: 42.5], inf: true
- assert_step [4.2, 4.2, 4.2, 4.2], [4.2, by: 0.0], inf: true
- assert_step [4.2, 4.2, 4.2, 4.2], [4.2, by: -0.0], inf: true
- assert_step [42.0, 42.0, 42.0, 42.0], [42, by: 0.0, to: 44], inf: true
- assert_step [42.0, 42.0, 42.0, 42.0], [42, by: 0.0, to: 0], inf: true
- assert_step [42.0, 42.0, 42.0, 42.0], [42, by: -0.0, to: 44], inf: true
-
- assert_step [bignum]*4, [bignum, by: 0], inf: true
- assert_step [bignum]*4, [bignum, by: 0.0], inf: true
- assert_step [bignum]*4, [bignum, by: 0, to: bignum+1], inf: true
- assert_step [bignum]*4, [bignum, by: 0, to: 0], inf: true
+ def test_step_bug15537
+ assert_step [10.0, 8.0, 6.0, 4.0, 2.0], [10.0, 1, -2]
+ assert_step [10.0, 8.0, 6.0, 4.0, 2.0], [10.0, to: 1, by: -2]
+ assert_step [10.0, 8.0, 6.0, 4.0, 2.0], [10.0, 1, -2]
+ assert_step [10.0, 8.0, 6.0, 4.0, 2.0], [10, to: 1.0, by: -2]
+ assert_step [10.0, 8.0, 6.0, 4.0, 2.0], [10, 1.0, -2]
+
+ assert_step [10.0, 9.0, 8.0, 7.0], [10, by: -1.0], inf: true
+ assert_step [10.0, 9.0, 8.0, 7.0], [10, by: -1.0, to: nil], inf: true
+ assert_step [10.0, 9.0, 8.0, 7.0], [10, nil, -1.0], inf: true
+ assert_step [10.0, 9.0, 8.0, 7.0], [10.0, by: -1], inf: true
+ assert_step [10.0, 9.0, 8.0, 7.0], [10.0, nil, -1], inf: true
end
def test_num2long
@@ -336,4 +399,100 @@ class TestNumeric < Test::Unit::TestCase
assert_not_operator(1, :eql?, 1.0)
assert_not_operator(1, :eql?, 2)
end
+
+ def test_coerced_remainder
+ assert_separately([], <<-'end;')
+ x = Class.new do
+ def coerce(a) [self, a]; end
+ def %(a) self; end
+ end.new
+ assert_raise(ArgumentError) {1.remainder(x)}
+ end;
+ end
+
+ def test_remainder_infinity
+ assert_equal(4, 4.remainder(Float::INFINITY))
+ assert_equal(4, 4.remainder(-Float::INFINITY))
+ assert_equal(-4, -4.remainder(Float::INFINITY))
+ assert_equal(-4, -4.remainder(-Float::INFINITY))
+
+ assert_equal(4.2, 4.2.remainder(Float::INFINITY))
+ assert_equal(4.2, 4.2.remainder(-Float::INFINITY))
+ assert_equal(-4.2, -4.2.remainder(Float::INFINITY))
+ assert_equal(-4.2, -4.2.remainder(-Float::INFINITY))
+ end
+
+ def test_comparison_comparable
+ bug12864 = '[ruby-core:77713] [Bug #12864]'
+
+ myinteger = Class.new do
+ include Comparable
+
+ def initialize(i)
+ @i = i.to_i
+ end
+ attr_reader :i
+
+ def <=>(other)
+ @i <=> (other.is_a?(self.class) ? other.i : other)
+ end
+ end
+
+ all_assertions(bug12864) do |a|
+ [5, 2**62, 2**61].each do |i|
+ a.for("%#x"%i) do
+ m = myinteger.new(i)
+ assert_equal(i, m)
+ assert_equal(m, i)
+ end
+ end
+ end
+ end
+
+ def test_pow
+ assert_equal(2**3, 2.pow(3))
+ assert_equal(2**-1, 2.pow(-1))
+ assert_equal(2**0.5, 2.pow(0.5))
+ assert_equal((-1)**0.5, -1.pow(0.5))
+ assert_equal(3**3 % 8, 3.pow(3, 8))
+ assert_equal(3**3 % -8, 3.pow(3,-8))
+ assert_equal(3**2 % -2, 3.pow(2,-2))
+ assert_equal((-3)**3 % 8, -3.pow(3,8))
+ assert_equal((-3)**3 % -8, -3.pow(3,-8))
+ assert_equal(5**2 % -8, 5.pow(2,-8))
+ assert_equal(4481650795473624846969600733813414725093,
+ 2120078484650058507891187874713297895455.
+ pow(5478118174010360425845660566650432540723,
+ 5263488859030795548286226023720904036518))
+
+ assert_equal(12, 12.pow(1, 10000000000), '[Bug #14259]')
+ assert_equal(12, 12.pow(1, 10000000001), '[Bug #14259]')
+ assert_equal(12, 12.pow(1, 10000000002), '[Bug #14259]')
+ assert_equal(17298641040, 12.pow(72387894339363242, 243682743764), '[Bug #14259]')
+
+ integers = [-2, -1, 0, 1, 2, 3, 6, 1234567890123456789]
+ integers.each do |i|
+ assert_equal(0, i.pow(0, 1), '[Bug #17257]')
+ assert_equal(1, i.pow(0, 2))
+ assert_equal(1, i.pow(0, 3))
+ assert_equal(1, i.pow(0, 6))
+ assert_equal(1, i.pow(0, 1234567890123456789))
+
+ assert_equal(0, i.pow(0, -1))
+ assert_equal(-1, i.pow(0, -2))
+ assert_equal(-2, i.pow(0, -3))
+ assert_equal(-5, i.pow(0, -6))
+ assert_equal(-1234567890123456788, i.pow(0, -1234567890123456789))
+ end
+
+ assert_equal(0, 0.pow(2, 1))
+ assert_equal(0, 0.pow(3, 1))
+ assert_equal(0, 2.pow(3, 1))
+ assert_equal(0, -2.pow(3, 1))
+
+ min, max = RbConfig::LIMITS.values_at("FIXNUM_MIN", "FIXNUM_MAX")
+ assert_equal(0, 0.pow(2, min))
+ assert_equal(0, Integer.sqrt(max+1).pow(2, min))
+ end
+
end