1require 'test/unit'
2
3class TestInteger < Test::Unit::TestCase
4  BDSIZE = 0x4000000000000000.coerce(0)[0].size
5  def self.bdsize(x)
6    ((x + 1) / 8 + BDSIZE) / BDSIZE * BDSIZE
7  end
8  def bdsize(x)
9    self.class.bdsize(x)
10  end
11
12  def test_aref
13    # assert_equal(1, (1 << 0x40000000)[0x40000000], "[ruby-dev:31271]")
14    # assert_equal(0, (-1 << 0x40000001)[0x40000000], "[ruby-dev:31271]")
15    big_zero = 0x40000000.coerce(0)[0]
16    assert_equal(0, (-0x40000002)[big_zero], "[ruby-dev:31271]")
17    assert_equal(1, 0x400000001[big_zero], "[ruby-dev:31271]")
18  end
19
20  def test_pow
21    assert_not_equal(0, begin
22                          0**-1
23                        rescue
24                          nil
25                        end, "[ruby-dev:32084] [ruby-dev:34547]")
26  end
27
28  def test_lshift
29    assert_equal(0, 1 << -0x40000000)
30    assert_equal(0, 1 << -0x40000001)
31    assert_equal(0, 1 << -0x80000000)
32    assert_equal(0, 1 << -0x80000001)
33    # assert_equal(bdsize(0x80000000), (1 << 0x80000000).size)
34  end
35
36  def test_rshift
37    # assert_equal(bdsize(0x40000001), (1 >> -0x40000001).size)
38    assert((1 >> 0x80000000).zero?)
39    assert((1 >> 0xffffffff).zero?)
40    assert((1 >> 0x100000000).zero?)
41    # assert_equal((1 << 0x40000000), (1 >> -0x40000000))
42    # assert_equal((1 << 0x40000001), (1 >> -0x40000001))
43  end
44
45  def test_Integer
46    assert_raise(ArgumentError) {Integer("0x-1")}
47    assert_raise(ArgumentError) {Integer("-0x-1")}
48    assert_raise(ArgumentError) {Integer("0x     123")}
49    assert_raise(ArgumentError) {Integer("0x      123")}
50    assert_raise(ArgumentError) {Integer("0x0x5")}
51    assert_raise(ArgumentError) {Integer("0x0x000000005")}
52    assert_nothing_raised(ArgumentError) {
53      assert_equal(1540841, "0x0x5".to_i(36))
54    }
55    assert_raise(ArgumentError) { Integer("--0") }
56    assert_raise(ArgumentError) { Integer("-+0") }
57    assert_raise(ArgumentError) { Integer("++1") }
58    assert_raise(ArgumentError) { Integer("") }
59    assert_raise(ArgumentError) { Integer("10  x") }
60    assert_raise(ArgumentError) { Integer("1__2") }
61    assert_raise(ArgumentError) { Integer("1z") }
62    assert_raise(ArgumentError) { Integer("46116860184273__87904") }
63    assert_raise(ArgumentError) { Integer("4611686018427387904_") }
64    assert_raise(ArgumentError) { Integer("4611686018427387904  :") }
65    assert_equal(0x4000000000000000, Integer("46_11_686_0184273_87904"))
66    assert_raise(ArgumentError) { Integer("\0") }
67    assert_nothing_raised(ArgumentError, "[ruby-core:13873]") {
68      assert_equal(0, Integer("0 "))
69    }
70    assert_nothing_raised(ArgumentError, "[ruby-core:14139]") {
71      assert_equal(0377, Integer("0_3_7_7"))
72    }
73    assert_raise(ArgumentError, "[ruby-core:14139]") {Integer("0__3_7_7")}
74    assert_equal(1234, Integer(1234))
75    assert_equal(1, Integer(1.234))
76
77    # base argument
78    assert_equal(1234, Integer("1234", 10))
79    assert_equal(668, Integer("1234", 8))
80    assert_equal(4660, Integer("1234", 16))
81    assert_equal(49360, Integer("1234", 36))
82    # decimal, not octal
83    assert_equal(1234, Integer("01234", 10))
84    assert_raise(ArgumentError) { Integer("0x123", 10) }
85    assert_raise(ArgumentError) { Integer(1234, 10) }
86    assert_raise(ArgumentError) { Integer(12.34, 10) }
87    assert_raise(ArgumentError) { Integer(Object.new, 1) }
88
89    assert_raise(ArgumentError) { Integer(1, 1, 1) }
90
91    assert_equal(2 ** 50, Integer(2.0 ** 50))
92    assert_raise(TypeError) { Integer(nil) }
93
94    bug6192 = '[ruby-core:43566]'
95    assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-16be"))}
96    assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-16le"))}
97    assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-32be"))}
98    assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-32le"))}
99    assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("iso-2022-jp"))}
100  end
101
102  def test_int_p
103    assert(!(1.0.integer?))
104    assert(1.integer?)
105  end
106
107  def test_odd_p_even_p
108    Fixnum.class_eval do
109      alias odd_bak odd?
110      alias even_bak even?
111      remove_method :odd?, :even?
112    end
113
114    assert(1.odd?)
115    assert(!(2.odd?))
116    assert(!(1.even?))
117    assert(2.even?)
118
119  ensure
120    Fixnum.class_eval do
121      alias odd? odd_bak
122      alias even? even_bak
123      remove_method :odd_bak, :even_bak
124    end
125  end
126
127  def test_succ
128    assert_equal(2, 1.send(:succ))
129
130    Fixnum.class_eval do
131      alias succ_bak succ
132      remove_method :succ
133    end
134
135    assert_equal(2, 1.succ)
136    assert_equal(4294967297, 4294967296.succ)
137
138  ensure
139    Fixnum.class_eval do
140      alias succ succ_bak
141      remove_method :succ_bak
142    end
143  end
144
145  def test_chr
146    assert_equal("a", "a".ord.chr)
147    assert_raise(RangeError) { (-1).chr }
148    assert_raise(RangeError) { 0x100.chr }
149  end
150
151  def test_upto
152    a = []
153    1.upto(3) {|x| a << x }
154    assert_equal([1, 2, 3], a)
155
156    a = []
157    1.upto(0) {|x| a << x }
158    assert_equal([], a)
159
160    y = 2**30 - 1
161    a = []
162    y.upto(y+2) {|x| a << x }
163    assert_equal([y, y+1, y+2], a)
164  end
165
166  def test_downto
167    a = []
168    -1.downto(-3) {|x| a << x }
169    assert_equal([-1, -2, -3], a)
170
171    a = []
172    1.downto(2) {|x| a << x }
173    assert_equal([], a)
174
175    y = -(2**30)
176    a = []
177    y.downto(y-2) {|x| a << x }
178    assert_equal([y, y-1, y-2], a)
179  end
180
181  def test_times
182    (2**32).times do |i|
183      break if i == 2
184    end
185  end
186
187  def test_round
188    assert_equal(11111, 11111.round)
189    assert_equal(Fixnum, 11111.round.class)
190    assert_equal(11111, 11111.round(0))
191    assert_equal(Fixnum, 11111.round(0).class)
192
193    assert_equal(11111.0, 11111.round(1))
194    assert_equal(Float, 11111.round(1).class)
195    assert_equal(11111.0, 11111.round(2))
196    assert_equal(Float, 11111.round(2).class)
197
198    assert_equal(11110, 11111.round(-1))
199    assert_equal(Fixnum, 11111.round(-1).class)
200    assert_equal(11100, 11111.round(-2))
201    assert_equal(Fixnum, 11111.round(-2).class)
202
203    assert_equal(1111_1111_1111_1111_1111_1111_1111_1110, 1111_1111_1111_1111_1111_1111_1111_1111.round(-1))
204    assert_equal(Bignum, 1111_1111_1111_1111_1111_1111_1111_1111.round(-1).class)
205    assert_equal(-1111_1111_1111_1111_1111_1111_1111_1110, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1))
206    assert_equal(Bignum, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1).class)
207  end
208
209  def test_bitwise_and_with_integer_mimic_object
210    def (obj = Object.new).to_int
211      10
212    end
213    assert_raise(TypeError, '[ruby-core:39491]') { 3 & obj }
214
215    def obj.coerce(other)
216      [other, 10]
217    end
218    assert_equal(3 & 10, 3 & obj)
219  end
220
221  def test_bitwise_or_with_integer_mimic_object
222    def (obj = Object.new).to_int
223      10
224    end
225    assert_raise(TypeError, '[ruby-core:39491]') { 3 | obj }
226
227    def obj.coerce(other)
228      [other, 10]
229    end
230    assert_equal(3 | 10, 3 | obj)
231  end
232
233  def test_bitwise_xor_with_integer_mimic_object
234    def (obj = Object.new).to_int
235      10
236    end
237    assert_raise(TypeError, '[ruby-core:39491]') { 3 ^ obj }
238
239    def obj.coerce(other)
240      [other, 10]
241    end
242    assert_equal(3 ^ 10, 3 ^ obj)
243  end
244end
245