PageRenderTime 40ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/jruby-1.7.3/test/test_integer_overflows.rb

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Ruby | 668 lines | 570 code | 39 blank | 59 comment | 64 complexity | 7f654c1e4256121dee5ed9fa15a5b5d1 MD5 | raw file
  1. # Tests to (a) show issues/bugs, and (b) test patches for these, for jira.codehaus.org.
  2. # In the following: IntMin = -9223372036854775808, which is (-2)**(64 - 1).
  3. # #JRUBY-6612: some problems with JRuby seeming to not detect Java Long arithmetic overflows
  4. # # IntMin * -1 #=> 9223372036854775808;
  5. # # -1 * IntMin #=> -9223372036854775808;
  6. # In the second example JRuby was not detecting the integer overflow.
  7. # The first patch for this fixed the problem in jruby-1.7.0.preview1,
  8. # but created a much less serious problem:
  9. # # IntMin * 1 #=> -9223372036854775808 Fixnum;
  10. # # 1 * IntMin #=> -9223372036854775808 Bignum;
  11. # This problem is fixed in jruby-1.7.0.preview2.
  12. # #JRUBY-6777: RubyFixnum.java - two methods assert false, to detect some long integer overflows
  13. # # IntMin / -1: -9223372036854775808;
  14. # # IntMin.divmod(-1): [-9223372036854775808, 0];
  15. # Fixed in jruby-1.7.0.preview2.
  16. # #JRUBY-6778: Possible long integer overflow bug in Integer#succ in RubyInteger.java
  17. # # 9223372036854775807.succ #=> -9223372036854775808;
  18. # Fixed in jruby-1.7.0.preview2.
  19. # VVT.logfile = "path/smalltest-jruby-.txt"
  20. require 'test/unit'
  21. class VVT < Test::Unit::TestCase
  22. BIT_SIZES = [ 30, 31, 32, 33, 62, 63, 64, 65 ]
  23. def test_integer_overflows
  24. BIT_SIZES.each do |nbits|
  25. checks_for_integer_overflow(nbits)
  26. end
  27. end
  28. def test_integer_iteration_for_overflows
  29. BIT_SIZES.each do |nbits|
  30. checks_for_integer_iteration_overflows(nbits)
  31. end
  32. end
  33. def checks_for_integer_overflow(nbits)
  34. reset_subcounts()
  35. return unless nbits >= 6
  36. nbits_int_min = n_bits_integer_min(nbits)
  37. nbits_int_max = n_bits_integer_max(nbits)
  38. # (1) Test for whether integer addition and negation seems OK,
  39. # because we need these to be reliable for the remaining tests.
  40. check_integer_add_overflow(nbits_int_max, 1)
  41. check_integer_add_overflow(nbits_int_min, -1)
  42. check_integer_negate_overflow(nbits_int_max)
  43. check_integer_negate_overflow(nbits_int_min)
  44. return if sub_notOK?() # stop here if any of the above tests are failed
  45. # (2) Test for non-iteration integer overflows.
  46. # The problems for JRuby-1.6.7.2, JRuby-1.7.0.preview1
  47. # seem to be fixed by patches used in JRuby-1.7.0.preview2.
  48. # In the following: IntMin = -9223372036854775808, which is -(2**(64 - 1));
  49. # IntMax = 9223372036854775807, which is 2**(64 - 1) - 1.
  50. check_integer_succ(nbits_int_max - 1)
  51. #* next line:[JRUBY-6778]: integer overflow: JRuby-1.6.7.2, JRuby-1.7.0.preview1;
  52. # 9223372036854775807.succ #=> -9223372036854775808;
  53. # IntMax.succ #=> IntMin;
  54. check_integer_succ(nbits_int_max) # [JRUBY-6778]
  55. check_integer_succ(nbits_int_max + 1)
  56. check_integer_multiply_by_0_or_1_or_minus_1(nbits_int_min, 0) # OK
  57. check_integer_multiply_by_0_or_1_or_minus_1(0, nbits_int_min) # OK
  58. check_integer_multiply_by_0_or_1_or_minus_1(nbits_int_min, -1) # OK
  59. #* next line:[JRUBY-6612]: integer overflow: JRuby-1.6.7.2;
  60. # -1 * -9223372036854775808 #=> -9223372036854775808;
  61. # -1 * IntMin #=> IntMin;
  62. # patch for this corrected this bug but created new bug just below
  63. check_integer_multiply_by_0_or_1_or_minus_1(-1, nbits_int_min) # [JRUBY-6612]
  64. #* next line: incorrect class of result: JRuby-1.7.0.preview1;
  65. # patch for [JRUBY-6612] corrected that bug but created this new less serious bug:
  66. # 1 * -9223372036854775808 #=> -9223372036854775808 Bignum;
  67. # 1 * IntMin #=> -9223372036854775808 Bignum; should be Fixnum IntMin
  68. check_integer_multiply_by_0_or_1_or_minus_1( 1, nbits_int_min) # OK in preview2
  69. check_integer_multiply_by_0_or_1_or_minus_1(nbits_int_min, 1) # OK
  70. check_integer_divide_by_1_or_minus_1(nbits_int_min, 1)
  71. check_integer_divmod_by_1_or_minus_1(nbits_int_min, 1)
  72. #* next line:[JRUBY-6777]: integer overflow: JRuby-1.6.7.2, JRuby-1.7.0.preview1;
  73. # -9223372036854775808 / -1 #=> -9223372036854775808;
  74. # IntMin / -1 #=> IntMin;
  75. check_integer_divide_by_1_or_minus_1(nbits_int_min, -1) # [JRUBY-6777]
  76. #* next line:[JRUBY-6777]: integer overflow: JRuby-1.6.7.2, JRuby-1.7.0.preview1;
  77. # -9223372036854775808.divmod(-1) #=> [-9223372036854775808, 0];
  78. # IntMin.divmod(-1) #=> [IntMin, 0];
  79. check_integer_divmod_by_1_or_minus_1(nbits_int_min, -1) # [JRUBY-6777]
  80. end
  81. def check_integer_add_overflow(av, bv)
  82. reset_actual_expected_etc()
  83. return unless av.kind_of?(Integer) && bv.kind_of?(Integer)
  84. @expected = vv = vvs = vvv = nil
  85. if av == 0 && bv == 0 then @expected = 0
  86. elsif av == 0 then @expected = bv
  87. elsif bv == 0 then @expected = av
  88. elsif av == 1 then vv = vvs = 1; vvv = bv
  89. elsif av == -1 then vv = vvs = -1; vvv = bv
  90. elsif bv == 1 then vv = vvs = 1; vvv = av
  91. elsif bv == -1 then vv = vvs = -1; vvv = av
  92. elsif bv > 0 then vv = bv; vvs = 1; vvv = av
  93. elsif bv < 0 then vv = bv; vvs = -1; vvv = av
  94. else return
  95. end
  96. unless @expected then
  97. begin
  98. @expected = vv + vvv
  99. qok = (if vvs == 1 then @expected > vvv else @expected < vvv end)
  100. qok &&= (-vv + @expected) == vvv
  101. @expected = inzpect(@expected) + "_???" unless qok
  102. rescue
  103. @expected = "???_" + inzpect($!) + "_???"
  104. end
  105. end
  106. @text = "#{inzpect(av)} + #{inzpect(bv)}"
  107. begin
  108. @actual = av + bv
  109. rescue
  110. @exception = $!
  111. end
  112. process_test_result()
  113. end
  114. def check_integer_succ(nv)
  115. reset_actual_expected_etc()
  116. @text = "#{inzpect(nv)}.succ"
  117. begin
  118. @expected = 1 + nv
  119. qok = @expected > nv
  120. qok &&= (-1 + @expected) == nv
  121. @expected = inzpect(@expected) + "_???" unless qok
  122. rescue
  123. @expected = "???_" + inzpect($!) + "_???"
  124. end
  125. begin
  126. @actual = nv.succ
  127. rescue
  128. @exception = $!
  129. end
  130. process_test_result()
  131. end
  132. def check_integer_negate_overflow(nv)
  133. reset_actual_expected_etc()
  134. return unless nv.kind_of?(Integer)
  135. @text = "negate #{inzpect(nv)}"
  136. begin
  137. # This gets the expected value of negate by using subtract,
  138. # which may be a problem if "a subtract b" is implemented as "a plus negate b",
  139. # or if "negate n" is implemented as "0 subtract n".
  140. @expected = 0 - nv
  141. negexp = 0 - @expected
  142. qok = negexp == nv && negexp.class == nv.class &&
  143. if nv > 0 then @expected < 0 && @expected.class == nv.class
  144. elsif nv < 0 then @expected > 0 && (-1 + @expected).class == nv.class
  145. else @expected.zero? && nv.zero? &&
  146. @expected == nv && @expected.class == nv.class
  147. end
  148. @expected = inzpect(@expected) + "_???" unless qok
  149. rescue
  150. @expected = "???_" + inzpect($!) + "_???"
  151. end
  152. begin
  153. @actual = -nv
  154. rescue
  155. @exception = $!
  156. end
  157. process_test_result()
  158. end
  159. def check_integer_multiply_by_0_or_1_or_minus_1(av, bv)
  160. reset_actual_expected_etc()
  161. return unless av.kind_of?(Integer) && bv.kind_of?(Integer)
  162. @expected = if av == 0 || bv == 0 then 0
  163. elsif av == 1 then bv
  164. elsif bv == 1 then av
  165. elsif av == -1 then
  166. if bv < 0 then -(bv + 1) + 1 else -bv end
  167. elsif bv == -1 then
  168. if bv < 0 then -(av + 1) + 1 else -av end
  169. else nil
  170. end
  171. return unless @expected
  172. @text = "#{inzpect(av)} * #{inzpect(bv)}"
  173. begin
  174. @actual = av * bv
  175. rescue
  176. @exception = $!
  177. end
  178. process_test_result()
  179. end
  180. def check_integer_divide_by_1_or_minus_1(av, bv)
  181. return unless av.kind_of?(Integer) && bv.kind_of?(Integer)
  182. reset_actual_expected_etc()
  183. @expected = if bv == 1 then av
  184. elsif bv == -1 then -(av + 1) + 1
  185. else nil
  186. end
  187. return unless @expected
  188. @text = "#{inzpect(av)} / #{inzpect(bv)}"
  189. begin
  190. @actual = av / bv
  191. rescue
  192. @exception = $!
  193. end
  194. process_test_result()
  195. end
  196. def check_integer_divmod_by_1_or_minus_1(av, bv)
  197. return unless av.kind_of?(Integer) && bv.kind_of?(Integer)
  198. reset_actual_expected_etc()
  199. @expected = if bv == 1 then [av, 0]
  200. elsif bv == -1 then [-(av + 1) + 1, 0]
  201. else nil
  202. end
  203. return unless @expected
  204. @text = "#{inzpect(av)}.divmod(#{inzpect(bv)})"
  205. begin
  206. @actual = av.divmod(bv)
  207. rescue
  208. @exception = $!
  209. end
  210. process_test_result()
  211. end
  212. def checks_for_integer_iteration_overflows(nbits)
  213. # This mainly tests for incorrect detection of integer overflow in integer iterations.
  214. reset_subcounts()
  215. return unless nbits >= 6
  216. nbits_int_min = n_bits_integer_min(nbits)
  217. nbits_int_max = n_bits_integer_max(nbits)
  218. # (1) Test if integer iteration seems OK for some "likely" integer overflows.
  219. # The idea is to "assert false, quickly" if there are "likely" integer overflows.
  220. #* next lines seem OK in: JRuby-1.6.7.2, JRuby-1.7.0.preview1;
  221. # next line was in [JRUBY-6779] as an example of Range#each working as expected
  222. check_integer_range_each(nbits_int_max - 1...nbits_int_max) # [JRUBY-6779] OK in JRuby-1.6, etc
  223. check_range_step(nbits_int_max - 1...nbits_int_max, 1)
  224. check_range_step(nbits_int_max...nbits_int_max + 1, 1)
  225. #* next lines: integer overflow: JRuby-1.6.7.2, JRuby-1.7.0.preview1;
  226. # next three lines are OK in JRuby-1.7.0.preview2 because of [JRUBY-6778] #succ patch
  227. check_integer_range_each(nbits_int_max.. nbits_int_max + 1) # [JRUBY-6779] OK in preview2
  228. check_integer_range_each(nbits_int_max...nbits_int_max + 1) # [JRUBY-6779] OK in preview2
  229. check_integer_range_each(nbits_int_max...nbits_int_max + 1)
  230. # but the next two lines seem still notOK in JRuby-1.7.0.preview2
  231. check_integer_range_each(nbits_int_max ..nbits_int_max) # [JRUBY-6779]
  232. check_integer_range_each(nbits_int_max - 1..nbits_int_max) # [JRUBY-6779]
  233. check_integer_downto(nbits_int_min, nbits_int_min)
  234. check_integer_upto(nbits_int_max, nbits_int_max)
  235. check_numeric_step(nbits_int_max - 1, nbits_int_max - 1, 2) # [JRUBY-6790]
  236. check_numeric_step(nbits_int_max, nbits_int_max, 1) # [JRUBY-6790]
  237. check_numeric_step(nbits_int_min, nbits_int_min, -1)
  238. check_range_step(nbits_int_max..nbits_int_max, 1)
  239. check_range_step(nbits_int_max - 1..nbits_int_max, 2)
  240. check_range_step(nbits_int_max - 1..nbits_int_max - 1, 2)
  241. check_range_step(nbits_int_max - 1...nbits_int_max, 2)
  242. #* next lines test for plausible but incorrect detection of iteration integer overflow
  243. #* next lines: integer overflow: JRuby-1.6.7.2, JRuby-1.7.0.preview1;
  244. check_numeric_step(nbits_int_min + 1, nbits_int_max - 1, nbits_int_max - 2)
  245. check_numeric_step(nbits_int_max - 1, nbits_int_min + 1, nbits_int_min + 3)
  246. check_range_step(nbits_int_min + 1..nbits_int_max - 1, nbits_int_max - 2)
  247. check_range_step(nbits_int_min + 1...nbits_int_max, nbits_int_max - 2)
  248. return if sub_notOK?() # stop here if any of the above tests are failed
  249. # If there aren't any "likely" integer overflows then do many more tests,
  250. # hoping to detect any "unlikely" integer overflows.
  251. nn0 = nbits_int_max - 7
  252. nn2 = nbits_int_max + 7
  253. nn = nn0 - 1
  254. while (nn += 1) <= nn2 do
  255. nnn = nn0 - 1
  256. while (nnn += 1) <= nn2 do
  257. check_integer_downto(nn, nnn)
  258. check_integer_upto(nn, nnn)
  259. check_integer_range_each(nn..nnn)
  260. check_integer_range_each(nn...nnn)
  261. check_numeric_step(nn, nnn, 1)
  262. check_numeric_step(nn, nnn, 2)
  263. check_range_step(nn..nnn, 1)
  264. check_range_step(nn...nnn, 1)
  265. check_range_step(nn..nnn, 2)
  266. check_range_step(nn...nnn, 2)
  267. end
  268. end
  269. end
  270. # individual tests
  271. def check_integer_downto(fromv, tov)
  272. @text = inzpect(fromv) + ".downto(" + inzpect(tov) + ")"
  273. set_numeric_expected_iterations(fromv, tov, -1, false, false)
  274. @expected = fromv
  275. @iterations = []
  276. begin
  277. @actual = fromv.downto(tov) do |iv|
  278. @iterations << iv
  279. break if @iterations.size >= @max_num_iterations
  280. end
  281. rescue
  282. @exception = $!
  283. end
  284. process_test_result()
  285. end
  286. def check_integer_upto(fromv, tov)
  287. @text = inzpect(fromv) + ".upto(" + inzpect(tov) + ")"
  288. set_numeric_expected_iterations(fromv, tov, 1, false, false)
  289. @expected = fromv
  290. @iterations = []
  291. begin
  292. @actual = fromv.upto(tov) do |iv|
  293. @iterations << iv
  294. break if @iterations.size >= @max_num_iterations
  295. end
  296. rescue
  297. @exception = $!
  298. end
  299. process_test_result()
  300. end
  301. def check_integer_range_each(rangev)
  302. @text = "(" + inzpect(rangev) + ").each"
  303. set_numeric_expected_iterations(rangev.begin, rangev.end, 1, false, rangev.exclude_end?)
  304. @expected = rangev
  305. @iterations = []
  306. begin
  307. @actual = rangev.each do |iv|
  308. @iterations << iv
  309. break if @iterations.size >= @max_num_iterations
  310. end
  311. rescue
  312. @exception = $!
  313. end
  314. process_test_result()
  315. end
  316. def check_numeric_step(fromv, tov, stepv)
  317. @text = inzpect(fromv) + ".step(" + inzpect(tov) + ", " + inzpect(stepv) + ")"
  318. efromv = fromv; etov = tov; estepv = stepv
  319. if efromv.kind_of?(Float) || etov.kind_of?(Float) || estepv.kind_of?(Float) then
  320. efromv = efromv.to_f; etov = etov.to_f; estepv = estepv.to_f
  321. end
  322. set_numeric_expected_iterations(efromv, etov, estepv, false, false)
  323. @expected = fromv
  324. if @expected_exception then
  325. @expected_exception = ArgumentError.exception("step can't be 0")
  326. @expected_iterations = []
  327. @expected = nil
  328. end
  329. @iterations = []
  330. begin
  331. @actual = fromv.step(tov, stepv) do |iv|
  332. @iterations << iv
  333. break if @iterations.size >= @max_num_iterations
  334. end
  335. rescue
  336. @exception = $!
  337. end
  338. process_test_result()
  339. end
  340. def check_range_step(rangev, stepv)
  341. @text = "(" + inzpect(rangev) + ").step(" + inzpect(stepv) + ")"
  342. efromv = rangev.begin; etov = rangev.end; estepv = stepv
  343. if efromv.kind_of?(Float) || etov.kind_of?(Float) || estepv.kind_of?(Float) then
  344. efromv = efromv.to_f; etov = etov.to_f; estepv = estepv.to_f
  345. end
  346. set_numeric_expected_iterations(efromv, etov, estepv, false, rangev.exclude_end?)
  347. @expected = rangev
  348. if @expected_exception || stepv < 0 then
  349. @expected_exception = if stepv < 0 then
  350. ArgumentError.exception("step can't be negative")
  351. else
  352. ArgumentError.exception("step can't be 0")
  353. end
  354. @expected_iterations = []
  355. @expected = nil
  356. end
  357. @iterations = []
  358. begin
  359. @actual = rangev.step(stepv) do |iv|
  360. @iterations << iv
  361. break if @iterations.size >= @max_num_iterations
  362. end
  363. rescue
  364. @exception = $!
  365. end
  366. process_test_result()
  367. end
  368. #############################
  369. # Test support methods follow
  370. #############################
  371. def ruby_run_info_const(symv, altv = nil)
  372. if Module.const_defined?(symv) then
  373. Module.const_get(symv)
  374. else
  375. altv
  376. end
  377. end
  378. DEFAULT_RECUR_MAX_DEPTH = 3
  379. IS_JRUBY = !! RUBY_PLATFORM.to_s.downcase.index("java")
  380. def JRuby?()
  381. IS_JRUBY
  382. end
  383. Infinity = 1.0 / 0.0
  384. # Min and max values of N-bit signed integers are
  385. # used for tests that integer overflow detection is working.
  386. # 31-bit signed integers: MRI Ruby Fixnum;
  387. # 32-bit signed integers: Java int, C long, etc;
  388. # 63-bit signed integers: MRI Ruby Fixnum;
  389. # 64-bit signed integers: Java long, JRuby Ruby Fixnum;
  390. def n_bits_integer_min(nbits)
  391. return nil if nbits < 1
  392. # Calculate -(2**(nbits - 1)) using only addition
  393. # to avoid relying on powers (or multiply) being correctly implemented.
  394. # This may be slow but that should not matter for the types of tests that
  395. # this is intended for. (You can "cache" values if speed is a problem.)
  396. min_intv = -1 # starting min value, for a 1_bit signed integer
  397. nbitsi = 0
  398. while (nbitsi += 1) < nbits do
  399. prev_min_intv = min_intv
  400. unless (min_intv += min_intv) < prev_min_intv then
  401. raise "ERROR overflow calculating -(2**(nbits - 1)) for nbits=#{nbits}"
  402. end
  403. end
  404. return min_intv
  405. end
  406. #
  407. def n_bits_integer_max(nbits)
  408. (minv = n_bits_integer_min(nbits)) && -(minv + 1)
  409. end
  410. def Rational_loaded?()
  411. return defined?(Rational)
  412. end
  413. attr_accessor :exclude_tests_level, :normal_tests_level
  414. def setup()
  415. # initialize test result counts and test controls
  416. @numOK = @numNotOK = @numExceptions = 0
  417. reset_subcounts()
  418. reset_actual_expected_etc()
  419. @logfile = nil
  420. @exclude_tests_level = nil # controls excluding some tests
  421. @normal_tests_level = 8
  422. @recur_max_depth = DEFAULT_RECUR_MAX_DEPTH # max depth for #not_equal?
  423. # next instance variable allows you to limit the number of iterations in a test
  424. # in case the actual number of iterations is much larger than expected (or infinite)
  425. @max_num_iterations = nil
  426. # next instance variable is the allowed margin of the actual number of iterations
  427. # over the expected number of iterations
  428. @max_num_iterations_margin = 2
  429. end
  430. def reset_actual_expected_etc()
  431. @actual = @iterations = @exception = nil
  432. @expected = @expected_iterations = @expected_exception = nil
  433. @max_num_iterations = nil
  434. end
  435. def reset_subcounts()
  436. @sub_numOK = @sub_numNotOK = @sub_numExceptions = 0
  437. end
  438. def sub_notOK?()
  439. (@sub_numNotOK && @sub_numNotOK != 0) ||
  440. (@sub_numExceptions && @sub_numExceptions != 0)
  441. end
  442. def not_equal?(actualv, expectedv, recur_max_depthv = nil)
  443. return true if actualv.class != expectedv.class
  444. recur_max_depthv ||= @recur_max_depth || DEFAULT_RECUR_MAX_DEPTH
  445. recur_max_depthv -= 1
  446. case actualv
  447. when Exception then
  448. return actualv.to_s != expectedv.to_s # focus equality on the exception message
  449. when Array then
  450. if recur_max_depthv >= 0 then
  451. ii2 = if actualv.size < expectedv.size then actualv.size else expectedv.size end
  452. iii = vvv = nil
  453. ii = -1
  454. while (ii += 1) < ii2 do
  455. if (vvv = not_equal?(actualv[ii], expectedv[ii], recur_max_depthv)) then
  456. iii = ii
  457. break
  458. end
  459. end
  460. if iii || actualv.size != expectedv.size then
  461. vvv = [] unless vvv.kind_of?(Array)
  462. vvv << (iii || ii2)
  463. return vvv
  464. end
  465. end
  466. end
  467. return ! (actualv == expectedv) # use normal equality checking
  468. end
  469. def inzpect(valuev, recur_max_depthv = nil,
  470. first_diff_indexes = nil, first_diff_indexv = nil)
  471. # Similar to "inspect" but has different options for showing arrays.
  472. # And for Bignum values shows class as well as value: for example: -123456789_big;
  473. # the reason for this is that it is possible that a numeric value is correct
  474. # but that the expected value is Fixnum and the actual value is Bignum,
  475. # and we want the output to be clear about the type of value.
  476. recur_max_depthv ||= @recur_max_depth || DEFAULT_RECUR_MAX_DEPTH
  477. recur_max_depthv -= 1
  478. case valuev
  479. when Array then
  480. if recur_max_depthv >= 0 then
  481. if first_diff_indexes.kind_of?(Array) then
  482. first_diff_indexv ||= first_diff_indexes.size
  483. first_diff_indexv -= 1
  484. else
  485. first_diff_indexv = nil
  486. end
  487. resultv = "["
  488. if valuev.size > 0 then
  489. iidiff_indexv = if first_diff_indexes.kind_of?(Array) then
  490. first_diff_indexes[first_diff_indexv]
  491. else
  492. -1
  493. end
  494. iidiff_indexv = -1 if iidiff_indexv >= valuev.size
  495. ii = 0
  496. if ii == iidiff_indexv then
  497. iidiff_indexv = -1
  498. fdixs = first_diff_indexes
  499. fdixv = first_diff_indexv
  500. else
  501. fdixs = fdixv = nil
  502. end
  503. resultv << inzpect(valuev[ii], recur_max_depthv, fdixs, fdixv)
  504. if valuev.size > 1 then
  505. prev_ii = ii
  506. if prev_ii < iidiff_indexv then
  507. if prev_ii < (ii = iidiff_indexv - 1) then
  508. resultv << (if prev_ii + 1 == ii then ", " else ",...@#{ii}:" end) <<
  509. inzpect(valuev[ii], recur_max_depthv, nil, nil)
  510. prev_ii = ii
  511. end
  512. ii = iidiff_indexv
  513. iidiff_indexv = -1
  514. resultv << (if prev_ii + 1 == ii then ", " else ",...@#{ii}:" end) <<
  515. inzpect(valuev[ii], recur_max_depthv,
  516. first_diff_indexes, first_diff_indexv)
  517. prev_ii = ii
  518. end
  519. if prev_ii < (ii = valuev.size - 1) then
  520. resultv << (if prev_ii + 1 == ii then ", " else ",...@#{ii}:" end) <<
  521. inzpect(valuev[ii], recur_max_depthv, nil, nil)
  522. end
  523. end
  524. end
  525. resultv << "]"
  526. return resultv
  527. end
  528. when Range then
  529. # Note recursive calls in next line!!!
  530. return inzpect(valuev.begin) <<
  531. (if valuev.exclude_end? then "..." else ".." end) <<
  532. inzpect(valuev.end)
  533. when Exception then
  534. return valuev.class.name + ":" << valuev.to_s.inspect
  535. when Bignum then
  536. return valuev.inspect << "_big"
  537. when Fixnum, Float, NilClass, TrueClass, FalseClass then
  538. return valuev.inspect
  539. else
  540. unless Rational_loaded? && valuev.class == Rational then
  541. return valuev.class.name + ":v:" << valuev.inspect
  542. end
  543. end
  544. valuev.inspect
  545. end
  546. def process_test_result()
  547. # For readability in making tests, this method relies on instance variables being set.
  548. # It calls "process_test_result_private" which (mostly) does not use instance variables.
  549. process_test_result_private(@actual, @expected,
  550. @iterations, @expected_iterations,
  551. @exception, @expected_exception,
  552. @text)
  553. end
  554. def process_test_result_private(actual_resultv, expected_resultv,
  555. actual_iterationsv, expected_iterationsv,
  556. actual_exceptionv, expected_exceptionv,
  557. test_textv = nil)
  558. if expected_resultv.kind_of?(Exception) && expected_exceptionv.nil? then
  559. expected_exceptionv = expected_resultv
  560. expected_resultv = nil
  561. end
  562. msgv = test_textv << " #=>"
  563. msgv << " != " << inzpect(expected_resultv, nil, not_equal?(actual_iterationsv, expected_iterationsv), nil)
  564. assert_equal(actual_resultv, expected_resultv, msgv)
  565. msgv = test_textv << " #=>"
  566. msgv << " != " << inzpect(expected_iterationsv, nil, not_equal?(actual_resultv, expected_resultv), nil)
  567. assert_equal(actual_iterationsv, expected_iterationsv, msgv)
  568. msgv = test_textv << " #=>"
  569. msgv << " != " << inzpect(expected_exceptionv, nil, not_equal?(actual_exceptionv, expected_exceptionv), nil)
  570. assert_equal(actual_exceptionv, expected_exceptionv, msgv)
  571. end
  572. def set_numeric_expected_iterations(fromv, tov, stepv, exclude_fromv, exclude_tov)
  573. # set up expected numeric iterated values
  574. reset_actual_expected_etc()
  575. if stepv == 0 then
  576. @expected_exception = true
  577. return
  578. end
  579. @expected_iterations = [] # store expected iterated values in an array
  580. # next line sets the appropriate check for the end of the iteration
  581. symv = if stepv > 0 then
  582. if exclude_tov then :< else :<= end
  583. else
  584. if exclude_tov then :> else :>= end
  585. end
  586. itvalue = fromv
  587. num_steps = 0 # count the steps from fromv: needed for Float (etc) iterations
  588. if exclude_fromv then
  589. # Depending on the type of iteration, this might need to be changed
  590. # if stepv is a very small Float or BigDecimal, etc.
  591. itvalue += stepv
  592. num_steps += 1
  593. end
  594. while itvalue.__send__(symv, tov) do
  595. @expected_iterations << itvalue
  596. num_steps += 1 # needed for Float (etc) iterations
  597. if itvalue.kind_of?(Float) ||
  598. (defined?(BigDecimal) && itvalue.kind_of?(BigDecimal)) then
  599. itvalue = fromv + stepv * num_steps
  600. else
  601. itvalue += stepv
  602. end
  603. end
  604. # next line anticipates unexpected infinite or very large loops in tests of iterators
  605. @max_num_iterations = @expected_iterations.size + (@max_num_iterations_margin || 2)
  606. return
  607. end
  608. end