summaryrefslogtreecommitdiff
path: root/trunk/test/ruby
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-25 15:02:05 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-25 15:02:05 +0000
commit0dc342de848a642ecce8db697b8fecd83a63e117 (patch)
tree2b7ed4724aff1f86073e4740134bda9c4aac1a39 /trunk/test/ruby
parentef70cf7138ab8034b5b806f466e4b484b24f0f88 (diff)
added tag v1_9_0_4
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_0_4@18845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'trunk/test/ruby')
-rw-r--r--trunk/test/ruby/allpairs.rb103
-rw-r--r--trunk/test/ruby/beginmainend.rb80
-rw-r--r--trunk/test/ruby/enc/test_big5.rb28
-rw-r--r--trunk/test/ruby/enc/test_cp949.rb28
-rw-r--r--trunk/test/ruby/enc/test_euc_jp.rb20
-rw-r--r--trunk/test/ruby/enc/test_euc_kr.rb28
-rw-r--r--trunk/test/ruby/enc/test_euc_tw.rb28
-rw-r--r--trunk/test/ruby/enc/test_gb18030.rb125
-rw-r--r--trunk/test/ruby/enc/test_gbk.rb28
-rw-r--r--trunk/test/ruby/enc/test_iso_8859.rb163
-rw-r--r--trunk/test/ruby/enc/test_koi8.rb22
-rw-r--r--trunk/test/ruby/enc/test_shift_jis.rb27
-rw-r--r--trunk/test/ruby/enc/test_utf16.rb358
-rw-r--r--trunk/test/ruby/enc/test_utf32.rb93
-rw-r--r--trunk/test/ruby/enc/test_windows_1251.rb16
-rw-r--r--trunk/test/ruby/endblockwarn_rb12
-rw-r--r--trunk/test/ruby/envutil.rb176
-rw-r--r--trunk/test/ruby/lbtest.rb48
-rw-r--r--trunk/test/ruby/marshaltestlib.rb499
-rw-r--r--trunk/test/ruby/sentence.rb668
-rw-r--r--trunk/test/ruby/test_alias.rb64
-rw-r--r--trunk/test/ruby/test_argf.rb701
-rw-r--r--trunk/test/ruby/test_array.rb1603
-rw-r--r--trunk/test/ruby/test_assignment.rb687
-rw-r--r--trunk/test/ruby/test_basicinstructions.rb628
-rw-r--r--trunk/test/ruby/test_beginendblock.rb101
-rw-r--r--trunk/test/ruby/test_bignum.rb390
-rw-r--r--trunk/test/ruby/test_call.rb19
-rw-r--r--trunk/test/ruby/test_case.rb49
-rw-r--r--trunk/test/ruby/test_class.rb147
-rw-r--r--trunk/test/ruby/test_clone.rb28
-rw-r--r--trunk/test/ruby/test_comparable.rb66
-rw-r--r--trunk/test/ruby/test_complex.rb1147
-rw-r--r--trunk/test/ruby/test_condition.rb16
-rw-r--r--trunk/test/ruby/test_const.rb48
-rw-r--r--trunk/test/ruby/test_continuation.rb81
-rw-r--r--trunk/test/ruby/test_defined.rb81
-rw-r--r--trunk/test/ruby/test_dir.rb170
-rw-r--r--trunk/test/ruby/test_econv.rb524
-rw-r--r--trunk/test/ruby/test_encoding.rb54
-rw-r--r--trunk/test/ruby/test_enum.rb259
-rw-r--r--trunk/test/ruby/test_enumerator.rb125
-rw-r--r--trunk/test/ruby/test_env.rb350
-rw-r--r--trunk/test/ruby/test_eval.rb394
-rw-r--r--trunk/test/ruby/test_exception.rb226
-rw-r--r--trunk/test/ruby/test_fiber.rb164
-rw-r--r--trunk/test/ruby/test_file.rb122
-rw-r--r--trunk/test/ruby/test_file_exhaustive.rb726
-rw-r--r--trunk/test/ruby/test_fixnum.rb241
-rw-r--r--trunk/test/ruby/test_float.rb433
-rw-r--r--trunk/test/ruby/test_fnmatch.rb104
-rw-r--r--trunk/test/ruby/test_gc.rb54
-rw-r--r--trunk/test/ruby/test_hash.rb851
-rw-r--r--trunk/test/ruby/test_ifunless.rb14
-rw-r--r--trunk/test/ruby/test_integer.rb193
-rw-r--r--trunk/test/ruby/test_integer_comb.rb620
-rw-r--r--trunk/test/ruby/test_io.rb1276
-rw-r--r--trunk/test/ruby/test_io_m17n.rb1334
-rw-r--r--trunk/test/ruby/test_iterator.rb497
-rw-r--r--trunk/test/ruby/test_lambda.rb68
-rw-r--r--trunk/test/ruby/test_literal.rb241
-rw-r--r--trunk/test/ruby/test_m17n.rb1290
-rw-r--r--trunk/test/ruby/test_m17n_comb.rb1623
-rw-r--r--trunk/test/ruby/test_marshal.rb194
-rw-r--r--trunk/test/ruby/test_math.rb239
-rw-r--r--trunk/test/ruby/test_method.rb224
-rw-r--r--trunk/test/ruby/test_mixed_unicode_escapes.rb25
-rw-r--r--trunk/test/ruby/test_module.rb720
-rw-r--r--trunk/test/ruby/test_numeric.rb217
-rw-r--r--trunk/test/ruby/test_object.rb401
-rw-r--r--trunk/test/ruby/test_objectspace.rb67
-rw-r--r--trunk/test/ruby/test_optimization.rb140
-rw-r--r--trunk/test/ruby/test_pack.rb448
-rw-r--r--trunk/test/ruby/test_parse.rb826
-rw-r--r--trunk/test/ruby/test_path.rb224
-rw-r--r--trunk/test/ruby/test_pipe.rb16
-rw-r--r--trunk/test/ruby/test_prec.rb21
-rw-r--r--trunk/test/ruby/test_primitive.rb397
-rw-r--r--trunk/test/ruby/test_proc.rb312
-rw-r--r--trunk/test/ruby/test_process.rb1007
-rw-r--r--trunk/test/ruby/test_rand.rb167
-rw-r--r--trunk/test/ruby/test_range.rb270
-rw-r--r--trunk/test/ruby/test_rational.rb1074
-rw-r--r--trunk/test/ruby/test_rational2.rb1360
-rw-r--r--trunk/test/ruby/test_readpartial.rb70
-rw-r--r--trunk/test/ruby/test_regexp.rb758
-rw-r--r--trunk/test/ruby/test_require.rb194
-rw-r--r--trunk/test/ruby/test_rubyoptions.rb283
-rw-r--r--trunk/test/ruby/test_settracefunc.rb184
-rw-r--r--trunk/test/ruby/test_signal.rb166
-rw-r--r--trunk/test/ruby/test_sleep.rb10
-rw-r--r--trunk/test/ruby/test_sprintf.rb273
-rw-r--r--trunk/test/ruby/test_sprintf_comb.rb548
-rw-r--r--trunk/test/ruby/test_string.rb1717
-rw-r--r--trunk/test/ruby/test_stringchar.rb166
-rw-r--r--trunk/test/ruby/test_struct.rb215
-rw-r--r--trunk/test/ruby/test_super.rb134
-rw-r--r--trunk/test/ruby/test_symbol.rb135
-rw-r--r--trunk/test/ruby/test_system.rb76
-rw-r--r--trunk/test/ruby/test_thread.rb507
-rw-r--r--trunk/test/ruby/test_time.rb394
-rw-r--r--trunk/test/ruby/test_trace.rb49
-rw-r--r--trunk/test/ruby/test_transcode.rb398
-rw-r--r--trunk/test/ruby/test_unicode_escape.rb267
-rw-r--r--trunk/test/ruby/test_variable.rb83
-rw-r--r--trunk/test/ruby/test_whileuntil.rb82
-rw-r--r--trunk/test/ruby/test_yield.rb355
-rw-r--r--trunk/test/ruby/ut_eof.rb128
108 files changed, 35900 insertions, 0 deletions
diff --git a/trunk/test/ruby/allpairs.rb b/trunk/test/ruby/allpairs.rb
new file mode 100644
index 0000000000..393d0c3288
--- /dev/null
+++ b/trunk/test/ruby/allpairs.rb
@@ -0,0 +1,103 @@
+module AllPairs
+ module_function
+
+ def make_prime(v)
+ return 2 if v < 2
+ ary = [true] * (v*2)
+ 2.upto(Math.sqrt(ary.length).ceil) {|i|
+ return i if ary[i] && v <= i
+ (i*2).step(ary.length, i) {|j|
+ ary[j] = false
+ }
+ }
+ v.upto(ary.length-1) {|i|
+ return i if ary[i]
+ }
+ raise "[bug] prime not found greater than #{v}"
+ end
+
+ def make_basic_block(prime)
+ prime.times {|i|
+ prime.times {|j|
+ row = [i]
+ 0.upto(prime-1) {|m|
+ row << (i*m + j) % prime
+ }
+ yield row
+ }
+ }
+ end
+
+ def combine_block(tbl1, tbl2)
+ result = []
+ tbl2.each {|row|
+ result << row * tbl1.first.length
+ }
+ tbl1.each_with_index {|row, k|
+ next if k == 0
+ result << row.map {|i| [i] * tbl2.first.length }.flatten
+ }
+ result
+ end
+
+ def make_large_block(v, prime)
+ if prime <= v+1
+ make_basic_block(v) {|row|
+ yield row
+ }
+ else
+ tbl = []
+ make_basic_block(v) {|row|
+ tbl << row
+ }
+ tbls = [tbl]
+ while tbl.first.length ** 2 < prime
+ tbl = combine_block(tbl, tbl)
+ tbls << tbl
+ end
+ tbl1 = tbls.find {|t| prime <= t.first.length * tbl.first.length }
+ tbl = combine_block(tbl, tbl1)
+ tbl.each {|row|
+ yield row
+ }
+ end
+ end
+
+ def each_index(*vs)
+ n = vs.length
+ max_v = vs.max
+ prime = make_prime(max_v)
+ h = {}
+ make_large_block(max_v, n) {|row|
+ row = vs.zip(row).map {|v, i| i % v }
+ next if h[row]
+ h[row] = true
+ yield row
+ }
+ end
+
+ # generate all pairs test.
+ def each(*args)
+ args.map! {|a| a.to_a }
+ each_index(*args.map {|a| a.length}) {|is|
+ yield is.zip(args).map {|i, a| a[i] }
+ }
+ end
+
+ # generate all combination in cartesian product. (not all-pairs test)
+ def exhaustive_each(*args)
+ args = args.map {|a| a.to_a }
+ i = 0
+ while true
+ n = i
+ as = []
+ args.reverse_each {|a|
+ n, m = n.divmod(a.length)
+ as.unshift a[m]
+ }
+ break if 0 < n
+ yield as
+ i += 1
+ end
+ end
+end
diff --git a/trunk/test/ruby/beginmainend.rb b/trunk/test/ruby/beginmainend.rb
new file mode 100644
index 0000000000..6cdfb15ea6
--- /dev/null
+++ b/trunk/test/ruby/beginmainend.rb
@@ -0,0 +1,80 @@
+errout = ARGV.shift
+
+BEGIN {
+ puts "b1"
+ local_begin1 = "local_begin1"
+ $global_begin1 = "global_begin1"
+ ConstBegin1 = "ConstBegin1"
+}
+
+BEGIN {
+ puts "b2"
+
+ BEGIN {
+ puts "b2-1"
+ }
+}
+
+# for scope check
+#raise if defined?(local_begin1)
+raise unless defined?($global_begin1)
+raise unless defined?(::ConstBegin1)
+local_for_end2 = "e2"
+$global_for_end1 = "e1"
+
+puts "main"
+
+END {
+ puts local_for_end2 # e2
+}
+
+eval <<EOE
+ BEGIN {
+ puts "b3"
+
+ BEGIN {
+ puts "b3-1"
+ }
+ }
+
+ BEGIN {
+ puts "b4"
+ }
+
+ END {
+ puts "e3"
+ }
+
+ END {
+ puts "e4"
+
+ END {
+ puts "e4-1"
+
+ END {
+ puts "e4-1-1"
+ }
+ }
+
+ END {
+ puts "e4-2"
+ }
+ }
+EOE
+
+END {
+ exit
+ puts "should not be dumped"
+
+ END {
+ puts "not reached"
+ }
+}
+
+END {
+ puts $global_for_end1 # e1
+
+ END {
+ puts "e1-1"
+ }
+}
diff --git a/trunk/test/ruby/enc/test_big5.rb b/trunk/test/ruby/enc/test_big5.rb
new file mode 100644
index 0000000000..e8fe0270a8
--- /dev/null
+++ b/trunk/test/ruby/enc/test_big5.rb
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestBig5 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("big5")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("big5"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
diff --git a/trunk/test/ruby/enc/test_cp949.rb b/trunk/test/ruby/enc/test_cp949.rb
new file mode 100644
index 0000000000..e675c7b80c
--- /dev/null
+++ b/trunk/test/ruby/enc/test_cp949.rb
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestCP949 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("cp949")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("cp949"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
diff --git a/trunk/test/ruby/enc/test_euc_jp.rb b/trunk/test/ruby/enc/test_euc_jp.rb
new file mode 100644
index 0000000000..82abe2116d
--- /dev/null
+++ b/trunk/test/ruby/enc/test_euc_jp.rb
@@ -0,0 +1,20 @@
+# vim: set fileencoding=euc-jp
+
+require "test/unit"
+
+class TestEUC_JP < Test::Unit::TestCase
+ def test_mbc_case_fold
+ assert_match(/()(a)\1\2/i, "aA")
+ assert_no_match(/()(a)\1\2/i, "aA")
+ end
+
+ def test_property
+ assert_match(/{0}\p{Hiragana}{4}/, "Ҥ餬")
+ assert_no_match(/{0}\p{Hiragana}{4}/, "")
+ assert_no_match(/{0}\p{Hiragana}{4}/, "")
+ assert_no_match(/{0}\p{Katakana}{4}/, "Ҥ餬")
+ assert_match(/{0}\p{Katakana}{4}/, "")
+ assert_no_match(/{0}\p{Katakana}{4}/, "")
+ assert_raise(RegexpError) { Regexp.new('{0}\p{foobarbaz}') }
+ end
+end
diff --git a/trunk/test/ruby/enc/test_euc_kr.rb b/trunk/test/ruby/enc/test_euc_kr.rb
new file mode 100644
index 0000000000..087bc795f7
--- /dev/null
+++ b/trunk/test/ruby/enc/test_euc_kr.rb
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestEucKr < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("euc-kr")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("euc-kr"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
diff --git a/trunk/test/ruby/enc/test_euc_tw.rb b/trunk/test/ruby/enc/test_euc_tw.rb
new file mode 100644
index 0000000000..f36d86b088
--- /dev/null
+++ b/trunk/test/ruby/enc/test_euc_tw.rb
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestEucTw < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("euc-tw")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\xa1\xa1").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0xa1a1, s("\xa1\xa1").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\xa1\xa1"), 0xa1a1.chr("euc-tw"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\xa1\xa1)\\1"), "i")
+ assert_match(r, s("\xa1\xa1\xa1\xa1"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\xa1\xa1"), s("\xa1\xa1\xa1\xa1").chop)
+ end
+end
diff --git a/trunk/test/ruby/enc/test_gb18030.rb b/trunk/test/ruby/enc/test_gb18030.rb
new file mode 100644
index 0000000000..a33a9eb28e
--- /dev/null
+++ b/trunk/test/ruby/enc/test_gb18030.rb
@@ -0,0 +1,125 @@
+require "test/unit"
+
+class TestGB18030 < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("gb18030")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\x81\x40").size)
+ assert_equal(1, s("\x81\x30\x81\x30").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0x8140, s("\x81\x40").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\x81\x40"), 0x8140.chr("gb18030"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\x81\x40)\\1"), "i")
+ assert_match(r, s("\x81\x40\x81\x40"))
+ end
+
+ def scheck(c, i)
+ assert_equal(s(c.reverse.take(c.size - i).join), s(c.reverse.join).chop)
+ end
+
+ def fcheck(c)
+ assert_raise(ArgumentError) { s(c.reverse.join).chop }
+ end
+
+ def test_left_adjust_char_head
+ # C1: 00-2f, 3a-3f, 7f, ff
+ # C2: 40-7e, 80
+ # C4: 30-39
+ # CM: 81-fe
+ c1 = "\x2f"
+ c2 = "\x40"
+ c4 = "\x30"
+ cm = "\x81"
+
+ # S_START-c1
+ # S_START-c2-S_one_C2-0
+ # S_START-c2-S_one_C2-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-cm-S_even_CM_one_CX-c1
+ # S_START-c2-S_one_C2-cm-S_odd_CM_one_CX-cm-S_even_CM_one_CX-cm-S_odd_CM_one_CX(rec)
+ # S_START-c4-S_one_C4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-c4-S_one_C4_odd_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-cm-S_even_CM_odd_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-c4-S_one_C4_even_CMC4-cm-S_odd_CMC4-cm-S_odd_CM_odd_CMC4-cm-S_even_CM_odd_CMC4-cm-S_odd_CM_odd_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-cm-S_even_CM_even_CMC4-c1
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-c4-S_one_C4_odd_CMC4-cm-S_even_CMC4-cm-S_odd_CM_even_CMC4-cm-S_even_CM_even_CMC4-cm-S_odd_CM_even_CMC4(rec)
+ # S_START-c4-S_one_C4-cm-S_one_CMC4-cm-S_even_CM_one_CX(rec)
+ # S_START-cm-S_one_CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-c4-S_odd_C4CM(rec)
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-cm-S_odd_CM_even_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-c4-S_even_C4CM-cm-S_one_CM_even_C4CM-cm-S_even_CM_even_C4CM-cm-S_odd_CM_even_C4CM-cm-S_even_CM_even_C4CM(rec)
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-cm-S_odd_CM_odd_C4CM-c1
+ # S_START-cm-S_one_CM-c4-S_odd_C4CM-cm-S_one_CM_odd_C4CM-cm-S_even_CM_odd_C4CM-cm-S_odd_CM_odd_C4CM-cm-S_even_CM_odd_C4CM(rec)
+ # S_START-cm-S_one_CM-cm-S_odd_CM_one_CX(rec)
+
+ scheck([c1], 1)
+ scheck([c2], 1)
+ scheck([c2, c1], 1)
+ scheck([c2, cm, c1], 2)
+ scheck([c2, cm, cm, c1], 1)
+ scheck([c2, cm, cm, cm], 2)
+ scheck([c4], 1)
+ scheck([c4, c1], 1)
+ scheck([c4, cm], 2)
+ fcheck([c4, cm, c1])
+ fcheck([c4, cm, c4, c1])
+ scheck([c4, cm, c4, cm], 4)
+ scheck([c4, cm, c4, cm, c1], 4)
+ scheck([c4, cm, c4, cm, c4], 4)
+ scheck([c4, cm, c4, cm, c4, c1], 4)
+ fcheck([c4, cm, c4, cm, c4, cm])
+ fcheck([c4, cm, c4, cm, c4, cm, c1])
+ fcheck([c4, cm, c4, cm, c4, cm, c4])
+ scheck([c4, cm, c4, cm, c4, cm, cm, c1], 4)
+ fcheck([c4, cm, c4, cm, c4, cm, cm, cm])
+ fcheck([c4, cm, c4, cm, c4, cm, cm, cm, c1])
+ scheck([c4, cm, c4, cm, c4, cm, cm, cm, cm], 4)
+ fcheck([c4, cm, c4, cm, cm, c1])
+ scheck([c4, cm, c4, cm, cm, cm], 4)
+ scheck([c4, cm, c4, cm, cm, cm, c1], 4)
+ fcheck([c4, cm, c4, cm, cm, cm, cm])
+ scheck([c4, cm, cm], 1)
+ scheck([cm], 1)
+ fcheck([cm, c1])
+ fcheck([cm, c4, c1])
+ scheck([cm, c4, cm], 3)
+ fcheck([cm, c4, cm, c1])
+ fcheck([cm, c4, cm, c4])
+ fcheck([cm, c4, cm, c4, c1])
+ fcheck([cm, c4, cm, c4, cm])
+ fcheck([cm, c4, cm, c4, cm, c1])
+ fcheck([cm, c4, cm, c4, cm, c4])
+ fcheck([cm, c4, cm, c4, cm, cm, c1])
+ fcheck([cm, c4, cm, c4, cm, cm, cm])
+ fcheck([cm, c4, cm, c4, cm, cm, cm, c1])
+ fcheck([cm, c4, cm, c4, cm, cm, cm, cm])
+ fcheck([cm, c4, cm, cm, c1])
+ fcheck([cm, c4, cm, cm, cm])
+ fcheck([cm, c4, cm, cm, cm, c1])
+ fcheck([cm, c4, cm, cm, cm, cm])
+ scheck([cm, cm], 2)
+ end
+end
diff --git a/trunk/test/ruby/enc/test_gbk.rb b/trunk/test/ruby/enc/test_gbk.rb
new file mode 100644
index 0000000000..d6dc5d6d1b
--- /dev/null
+++ b/trunk/test/ruby/enc/test_gbk.rb
@@ -0,0 +1,28 @@
+require "test/unit"
+
+class TestGBK < Test::Unit::TestCase
+ def s(s)
+ s.force_encoding("gbk")
+ end
+
+ def test_mbc_enc_len
+ assert_equal(1, s("\x81\x40").size)
+ end
+
+ def test_mbc_to_code
+ assert_equal(0x8140, s("\x81\x40").ord)
+ end
+
+ def test_code_to_mbc
+ assert_equal(s("\x81\x40"), 0x8140.chr("gbk"))
+ end
+
+ def test_mbc_case_fold
+ r = Regexp.new(s("(\x81\x40)\\1"), "i")
+ assert_match(r, s("\x81\x40\x81\x40"))
+ end
+
+ def test_left_adjust_char_head
+ assert_equal(s("\x81\x40"), s("\x81\x40\x81\x40").chop)
+ end
+end
diff --git a/trunk/test/ruby/enc/test_iso_8859.rb b/trunk/test/ruby/enc/test_iso_8859.rb
new file mode 100644
index 0000000000..64cc7cd76d
--- /dev/null
+++ b/trunk/test/ruby/enc/test_iso_8859.rb
@@ -0,0 +1,163 @@
+require 'test/unit'
+
+class TestISO8859 < Test::Unit::TestCase
+ ASSERTS = %q(
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ # assert_match(/^(\xdf)\1$/i, "\xdfss") # this must be bug...
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ ((0xc0..0xde).to_a - [0xd7]).each do |c|
+ c1 = c.chr("ENCODING")
+ c2 = (c + 0x20).chr("ENCODING")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ assert_match(/^\xff$/i, "\xff")
+ )
+
+ def test_iso_8859_1
+ eval("# encoding: iso8859-1\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-1"))
+ end
+
+ def test_iso_8859_2
+ eval("# encoding: iso8859-2\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-2"))
+ end
+
+ def test_iso_8859_3
+ eval(%q(# encoding: iso8859-3
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ [0xa1, 0xa6, *(0xa9..0xac), 0xaf].each do |c|
+ c1 = c.chr("iso8859-3")
+ c2 = (c + 0x10).chr("iso8859-3")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ([*(0xc0..0xde)] - [0xc3, 0xd0, 0xd7]).each do |c|
+ c1 = c.chr("iso8859-3")
+ c2 = (c + 0x20).chr("iso8859-3")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_4
+ eval("# encoding: iso8859-4\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-4"))
+ end
+
+ def test_iso_8859_5
+ eval(%q(# encoding: iso8859-5
+ (0xb0..0xcf).each do |c|
+ c1 = c.chr("iso8859-5")
+ c2 = (c + 0x20).chr("iso8859-5")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ((0xa1..0xaf).to_a - [0xad]).each do |c|
+ c1 = c.chr("iso8859-5")
+ c2 = (c + 0x50).chr("iso8859-5")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_6
+ eval(%q(# encoding: iso8859-6
+ [0xa4, 0xac, 0xbb, 0xbf, *(0xc1..0xda), *(0xe0..0xf2)].each do |c|
+ c1 = c.chr("iso8859-6")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_7
+ eval(%q(# encoding: iso8859-7
+ ((0xa0..0xfe).to_a - [0xae, 0xd2]).each do |c|
+ c1 = c.chr("iso8859-7")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ((0xc1..0xd9).to_a - [0xd2]).each do |c|
+ c1 = c.chr("iso8859-7")
+ c2 = (c + 0x20).chr("iso8859-7")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_8
+ eval(%q(# encoding: iso8859-8
+ [0xa0, *(0xa2..0xbe), *(0xdf..0xfa), 0xfc, 0xfd].each do |c|
+ c1 = c.chr("iso8859-8")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_9
+ eval(%q(# encoding: iso8859-9
+ assert_match(/^(\xdf)\1$/i, "\xdf\xdf")
+ assert_match(/^(\xdf)\1$/i, "ssss")
+ assert_match(/^[\xdfz]+$/i, "sszzsszz")
+ assert_match(/^SS$/i, "\xdf")
+ assert_match(/^Ss$/i, "\xdf")
+ ([*(0xc0..0xdc)] - [0xd7]).each do |c|
+ c1 = c.chr("iso8859-9")
+ c2 = (c + 0x20).chr("iso8859-9")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ ))
+ end
+
+ def test_iso_8859_10
+ eval("# encoding: iso8859-10\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-10"))
+ end
+
+ def test_iso_8859_11
+ eval(%q(# encoding: iso8859-11
+ [*(0xa0..0xda), *(0xdf..0xfb)].each do |c|
+ c1 = c.chr("iso8859-11")
+ assert_match(/^(#{ c1 })\1$/i, c1 * 2)
+ end
+ ))
+ end
+
+ def test_iso_8859_13
+ eval("# encoding: iso8859-13\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-13"))
+ end
+
+ def test_iso_8859_14
+ eval("# encoding: iso8859-14\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-14"))
+ end
+
+ def test_iso_8859_15
+ eval("# encoding: iso8859-15\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-15"))
+ end
+
+ def test_iso_8859_16
+ eval("# encoding: iso8859-16\n" + ASSERTS.gsub(/ENCODING/m, "iso8859-16"))
+ end
+end
+
diff --git a/trunk/test/ruby/enc/test_koi8.rb b/trunk/test/ruby/enc/test_koi8.rb
new file mode 100644
index 0000000000..ce2d8925ea
--- /dev/null
+++ b/trunk/test/ruby/enc/test_koi8.rb
@@ -0,0 +1,22 @@
+require "test/unit"
+
+class TestKOI8 < Test::Unit::TestCase
+ ASSERTS = %q(
+ (0xc0..0xdf).each do |c|
+ c1 = c.chr("ENCODING")
+ c2 = (c + 0x20).chr("ENCODING")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ )
+
+ def test_koi8_r
+ eval("# encoding: koi8-r\n" + ASSERTS.gsub("ENCODING", "koi8-r"))
+ end
+
+ def test_koi8_u
+ eval("# encoding: koi8-u\n" + ASSERTS.gsub("ENCODING", "koi8-u"))
+ end
+end
diff --git a/trunk/test/ruby/enc/test_shift_jis.rb b/trunk/test/ruby/enc/test_shift_jis.rb
new file mode 100644
index 0000000000..f81cb7801c
--- /dev/null
+++ b/trunk/test/ruby/enc/test_shift_jis.rb
@@ -0,0 +1,27 @@
+# vim: set fileencoding=shift_jis
+
+require "test/unit"
+
+class TestShiftJIS < Test::Unit::TestCase
+ def test_mbc_case_fold
+ assert_match(/()(a)\1\2/i, "aA")
+ assert_no_match(/()(a)\1\2/i, "a`A")
+ end
+
+ def test_property
+ assert_match(/{0}\p{Hiragana}{4}/, "Ђ炪")
+ assert_no_match(/{0}\p{Hiragana}{4}/, "J^Ji")
+ assert_no_match(/{0}\p{Hiragana}{4}/, "")
+ assert_no_match(/{0}\p{Katakana}{4}/, "Ђ炪")
+ assert_match(/{0}\p{Katakana}{4}/, "J^Ji")
+ assert_no_match(/{0}\p{Katakana}{4}/, "")
+ assert_raise(RegexpError) { Regexp.new('{0}\p{foobarbaz}') }
+ end
+
+ def test_code_to_mbclen
+ s = ""
+ s << 0x82a9
+ assert_equal("", s)
+ assert_raise(ArgumentError) { s << 0x82 }
+ end
+end
diff --git a/trunk/test/ruby/enc/test_utf16.rb b/trunk/test/ruby/enc/test_utf16.rb
new file mode 100644
index 0000000000..a7c735f436
--- /dev/null
+++ b/trunk/test/ruby/enc/test_utf16.rb
@@ -0,0 +1,358 @@
+require 'test/unit'
+
+class TestUTF16 < Test::Unit::TestCase
+ def encdump(str)
+ d = str.dump
+ if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
+ d
+ else
+ "#{d}.force_encoding(#{str.encoding.name.dump})"
+ end
+ end
+
+ def enccall(recv, meth, *args)
+ desc = ''
+ if String === recv
+ desc << encdump(recv)
+ else
+ desc << recv.inspect
+ end
+ desc << '.' << meth.to_s
+ if !args.empty?
+ desc << '('
+ args.each_with_index {|a, i|
+ desc << ',' if 0 < i
+ if String === a
+ desc << encdump(a)
+ else
+ desc << a.inspect
+ end
+ }
+ desc << ')'
+ end
+ result = nil
+ assert_nothing_raised(desc) {
+ result = recv.send(meth, *args)
+ }
+ result
+ end
+
+ def assert_str_equal(expected, actual, message=nil)
+ full_message = build_message(message, <<EOT)
+#{encdump expected} expected but not equal to
+#{encdump actual}.
+EOT
+ assert_block(full_message) { expected == actual }
+ end
+
+ # tests start
+
+ def test_utf16be_valid_encoding
+ [
+ "\x00\x00",
+ "\xd7\xff",
+ "\xd8\x00\xdc\x00",
+ "\xdb\xff\xdf\xff",
+ "\xe0\x00",
+ "\xff\xff",
+ ].each {|s|
+ s.force_encoding("utf-16be")
+ assert_equal(true, s.valid_encoding?, "#{encdump s}.valid_encoding?")
+ }
+ [
+ "\x00",
+ "\xd7",
+ "\xd8\x00",
+ "\xd8\x00\xd8\x00",
+ "\xdc\x00",
+ "\xdc\x00\xd8\x00",
+ "\xdc\x00\xdc\x00",
+ "\xe0",
+ "\xff",
+ ].each {|s|
+ s.force_encoding("utf-16be")
+ assert_equal(false, s.valid_encoding?, "#{encdump s}.valid_encoding?")
+ }
+ end
+
+ def test_utf16le_valid_encoding
+ [
+ "\x00\x00",
+ "\xff\xd7",
+ "\x00\xd8\x00\xdc",
+ "\xff\xdb\xff\xdf",
+ "\x00\xe0",
+ "\xff\xff",
+ ].each {|s|
+ s.force_encoding("utf-16le")
+ assert_equal(true, s.valid_encoding?, "#{encdump s}.valid_encoding?")
+ }
+ [
+ "\x00",
+ "\xd7",
+ "\x00\xd8",
+ "\x00\xd8\x00\xd8",
+ "\x00\xdc",
+ "\x00\xdc\x00\xd8",
+ "\x00\xdc\x00\xdc",
+ "\xe0",
+ "\xff",
+ ].each {|s|
+ s.force_encoding("utf-16le")
+ assert_equal(false, s.valid_encoding?, "#{encdump s}.valid_encoding?")
+ }
+ end
+
+ def test_strftime
+ s = "aa".force_encoding("utf-16be")
+ assert_raise(ArgumentError, "Time.now.strftime(#{encdump s})") { Time.now.strftime(s) }
+ end
+
+ def test_intern
+ s = "aaaa".force_encoding("utf-16be")
+ assert_equal(s.encoding, s.intern.to_s.encoding, "#{encdump s}.intern.to_s.encoding")
+ end
+
+ def test_sym_eq
+ s = "aa".force_encoding("utf-16le")
+ assert(s.intern != :aa, "#{encdump s}.intern != :aa")
+ end
+
+ def test_compatible
+ s1 = "aa".force_encoding("utf-16be")
+ s2 = "z".force_encoding("us-ascii")
+ assert_nil(Encoding.compatible?(s1, s2), "Encoding.compatible?(#{encdump s1}, #{encdump s2})")
+ end
+
+ def test_casecmp
+ s1 = "aa".force_encoding("utf-16be")
+ s2 = "AA"
+ assert_not_equal(0, s1.casecmp(s2), "#{encdump s1}.casecmp(#{encdump s2})")
+ end
+
+ def test_end_with
+ s1 = "ab".force_encoding("utf-16be")
+ s2 = "b".force_encoding("utf-16be")
+ assert_equal(false, s1.end_with?(s2), "#{encdump s1}.end_with?(#{encdump s2})")
+ end
+
+ def test_hex
+ assert_raise(EncodingCompatibilityError) {
+ "ff".encode("utf-16le").hex
+ }
+ assert_raise(EncodingCompatibilityError) {
+ "ff".encode("utf-16be").hex
+ }
+ end
+
+ def test_oct
+ assert_raise(EncodingCompatibilityError) {
+ "77".encode("utf-16le").oct
+ }
+ assert_raise(EncodingCompatibilityError) {
+ "77".encode("utf-16be").oct
+ }
+ end
+
+ def test_count
+ s1 = "aa".force_encoding("utf-16be")
+ s2 = "aa"
+ assert_raise(EncodingCompatibilityError, "#{encdump s1}.count(#{encdump s2})") {
+ s1.count(s2)
+ }
+ end
+
+ def test_plus
+ s1 = "a".force_encoding("us-ascii")
+ s2 = "aa".force_encoding("utf-16be")
+ assert_raise(EncodingCompatibilityError, "#{encdump s1} + #{encdump s2}") {
+ s1 + s2
+ }
+ end
+
+ def test_encoding_find
+ assert_raise(ArgumentError) {
+ Encoding.find("utf-8".force_encoding("utf-16be"))
+ }
+ end
+
+ def test_interpolation
+ s = "aa".force_encoding("utf-16be")
+ assert_raise(EncodingCompatibilityError, "\"a\#{#{encdump s}}\"") {
+ "a#{s}"
+ }
+ end
+
+ def test_slice!
+ enccall("aa".force_encoding("UTF-16BE"), :slice!, -1)
+ end
+
+ def test_plus_empty1
+ s1 = ""
+ s2 = "aa".force_encoding("utf-16be")
+ assert_nothing_raised("#{encdump s1} << #{encdump s2}") {
+ s1 + s2
+ }
+ end
+
+ def test_plus_empty2
+ s1 = "aa"
+ s2 = "".force_encoding("utf-16be")
+ assert_nothing_raised("#{encdump s1} << #{encdump s2}") {
+ s1 + s2
+ }
+ end
+
+ def test_plus_nonempty
+ s1 = "aa"
+ s2 = "bb".force_encoding("utf-16be")
+ assert_raise(EncodingCompatibilityError, "#{encdump s1} << #{encdump s2}") {
+ s1 + s2
+ }
+ end
+
+ def test_concat_empty1
+ s1 = ""
+ s2 = "aa".force_encoding("utf-16be")
+ assert_nothing_raised("#{encdump s1} << #{encdump s2}") {
+ s1 << s2
+ }
+ end
+
+ def test_concat_empty2
+ s1 = "aa"
+ s2 = "".force_encoding("utf-16be")
+ assert_nothing_raised("#{encdump s1} << #{encdump s2}") {
+ s1 << s2
+ }
+ end
+
+ def test_concat_nonempty
+ s1 = "aa"
+ s2 = "bb".force_encoding("utf-16be")
+ assert_raise(EncodingCompatibilityError, "#{encdump s1} << #{encdump s2}") {
+ s1 << s2
+ }
+ end
+
+ def test_chomp
+ s = "\1\n".force_encoding("utf-16be")
+ assert_equal(s, s.chomp, "#{encdump s}.chomp")
+ s = "\0\n".force_encoding("utf-16be")
+ assert_equal("", s.chomp, "#{encdump s}.chomp")
+ s = "\0\r\0\n".force_encoding("utf-16be")
+ assert_equal("", s.chomp, "#{encdump s}.chomp")
+ end
+
+ def test_succ
+ s = "\xff\xff".force_encoding("utf-16be")
+ assert(s.succ.valid_encoding?, "#{encdump s}.succ.valid_encoding?")
+
+ s = "\xdb\xff\xdf\xff".force_encoding("utf-16be")
+ assert(s.succ.valid_encoding?, "#{encdump s}.succ.valid_encoding?")
+ end
+
+ def test_regexp_union
+ enccall(Regexp, :union, "aa".force_encoding("utf-16be"), "bb".force_encoding("utf-16be"))
+ end
+
+ def test_empty_regexp
+ s = "".force_encoding("utf-16be")
+ assert_equal(Encoding.find("utf-16be"), Regexp.new(s).encoding,
+ "Regexp.new(#{encdump s}).encoding")
+ end
+
+ def test_regexp_match
+ assert_raise(ArgumentError) { Regexp.new("aa".force_encoding("utf-16be")) =~ "aa" }
+ end
+
+ def test_gsub
+ s = "abcd".force_encoding("utf-16be")
+ assert_nothing_raised {
+ s.gsub(Regexp.new(".".encode("utf-16be")), "xy")
+ }
+ s = "ab\0\ncd".force_encoding("utf-16be")
+ assert_raise(EncodingCompatibilityError) {
+ s.gsub(Regexp.new(".".encode("utf-16be")), "xy")
+ }
+ end
+
+ def test_split_awk
+ s = " ab cd ".encode("utf-16be")
+ r = s.split(" ".encode("utf-16be"))
+ assert_equal(2, r.length)
+ assert_str_equal("ab".encode("utf-16be"), r[0])
+ assert_str_equal("cd".encode("utf-16be"), r[1])
+ end
+
+ def test_count2
+ e = "abc".count("^b")
+ assert_equal(e, "abc".encode("utf-16be").count("^b".encode("utf-16be")))
+ assert_equal(e, "abc".encode("utf-16le").count("^b".encode("utf-16le")))
+ end
+
+ def test_header
+ assert_raise(ArgumentError) { eval("# encoding:utf-16le\nfoo") }
+ assert_raise(ArgumentError) { eval("# encoding:utf-16be\nfoo") }
+ end
+
+
+ def test_is_mbc_newline
+ sl = "f\0o\0o\0\n\0b\0a\0r\0\n\0b\0a\0z\0\n\0".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\0\n\0b\0a\0r\0\n\0b\0a\0z\0\n".force_encoding("utf-16be")
+ al = sl.lines.to_a
+ ab = sb.lines.to_a
+ assert_equal("f\0o\0o\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("b\0a\0r\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("b\0a\0z\0\n\0".force_encoding("utf-16le"), al.shift)
+ assert_equal("\0f\0o\0o\0\n".force_encoding("utf-16be"), ab.shift)
+ assert_equal("\0b\0a\0r\0\n".force_encoding("utf-16be"), ab.shift)
+ assert_equal("\0b\0a\0z\0\n".force_encoding("utf-16be"), ab.shift)
+
+ sl = "f\0o\0o\0\n\0".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\0\n".force_encoding("utf-16be")
+ sl2 = "f\0o\0o\0".force_encoding("utf-16le")
+ sb2 = "\0f\0o\0o".force_encoding("utf-16be")
+ assert_equal(sl2, sl.chomp)
+ assert_equal(sl2, sl.chomp.chomp)
+ assert_equal(sb2, sb.chomp)
+ assert_equal(sb2, sb.chomp.chomp)
+
+ sl = "f\0o\0o\0\n".force_encoding("utf-16le")
+ sb = "\0f\0o\0o\n".force_encoding("utf-16be")
+ assert_equal(sl, sl.chomp)
+ assert_equal(sb, sb.chomp)
+ end
+
+ def test_code_to_mbc
+ assert_equal("a\0".force_encoding("utf-16le"), "a".ord.chr("utf-16le"))
+ assert_equal("\0a".force_encoding("utf-16be"), "a".ord.chr("utf-16be"))
+ end
+
+ def utf8_to_utf16(s, e)
+ s.chars.map {|c| c.ord.chr(e) }.join
+ end
+
+ def test_mbc_case_fold
+ rl = Regexp.new(utf8_to_utf16("^(\u3042)(a)\\1\\2$", "utf-16le"), "i")
+ rb = Regexp.new(utf8_to_utf16("^(\u3042)(a)\\1\\2$", "utf-16be"), "i")
+ assert_equal(Encoding.find("utf-16le"), rl.encoding)
+ assert_equal(Encoding.find("utf-16be"), rb.encoding)
+ assert_match(rl, utf8_to_utf16("\u3042a\u3042a", "utf-16le"))
+ assert_match(rb, utf8_to_utf16("\u3042a\u3042a", "utf-16be"))
+ end
+
+ def test_surrogate_pair
+ sl = "\x42\xd8\xb7\xdf".force_encoding("utf-16le")
+ sb = "\xd8\x42\xdf\xb7".force_encoding("utf-16be")
+
+ assert_equal(1, sl.size)
+ assert_equal(1, sb.size)
+ assert_equal(0x20bb7, sl.ord)
+ assert_equal(0x20bb7, sb.ord)
+ assert_equal(sl, 0x20bb7.chr("utf-16le"))
+ assert_equal(sb, 0x20bb7.chr("utf-16be"))
+ assert_equal("", sl.chop)
+ assert_equal("", sb.chop)
+ end
+end
diff --git a/trunk/test/ruby/enc/test_utf32.rb b/trunk/test/ruby/enc/test_utf32.rb
new file mode 100644
index 0000000000..3d4a458512
--- /dev/null
+++ b/trunk/test/ruby/enc/test_utf32.rb
@@ -0,0 +1,93 @@
+require 'test/unit'
+
+class TestUTF32 < Test::Unit::TestCase
+ def encdump(str)
+ d = str.dump
+ if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
+ d
+ else
+ "#{d}.force_encoding(#{str.encoding.name.dump})"
+ end
+ end
+
+ def assert_str_equal(expected, actual, message=nil)
+ full_message = build_message(message, <<EOT)
+#{encdump expected} expected but not equal to
+#{encdump actual}.
+EOT
+ assert_block(full_message) { expected == actual }
+ end
+
+ def test_substr
+ assert_str_equal(
+ "abcdefgh".force_encoding("utf-32le"),
+ "abcdefgh".force_encoding("utf-32le")[0,3])
+ assert_str_equal(
+ "abcdefgh".force_encoding("utf-32be"),
+ "abcdefgh".force_encoding("utf-32be")[0,3])
+ end
+
+ def test_mbc_len
+ al = "abcdefghijkl".force_encoding("utf-32le").each_char.to_a
+ ab = "abcdefghijkl".force_encoding("utf-32be").each_char.to_a
+ assert_equal("abcd".force_encoding("utf-32le"), al.shift)
+ assert_equal("efgh".force_encoding("utf-32le"), al.shift)
+ assert_equal("ijkl".force_encoding("utf-32le"), al.shift)
+ assert_equal("abcd".force_encoding("utf-32be"), ab.shift)
+ assert_equal("efgh".force_encoding("utf-32be"), ab.shift)
+ assert_equal("ijkl".force_encoding("utf-32be"), ab.shift)
+ end
+
+ def ascii_to_utf16le(s)
+ s.unpack("C*").map {|x| [x,0,0,0] }.flatten.pack("C*").force_encoding("utf-32le")
+ end
+
+ def ascii_to_utf16be(s)
+ s.unpack("C*").map {|x| [0,0,0,x] }.flatten.pack("C*").force_encoding("utf-32be")
+ end
+
+ def test_mbc_newline
+ al = ascii_to_utf16le("foo\nbar\nbaz\n").lines.to_a
+ ab = ascii_to_utf16be("foo\nbar\nbaz\n").lines.to_a
+
+ assert_equal(ascii_to_utf16le("foo\n"), al.shift)
+ assert_equal(ascii_to_utf16le("bar\n"), al.shift)
+ assert_equal(ascii_to_utf16le("baz\n"), al.shift)
+ assert_equal(ascii_to_utf16be("foo\n"), ab.shift)
+ assert_equal(ascii_to_utf16be("bar\n"), ab.shift)
+ assert_equal(ascii_to_utf16be("baz\n"), ab.shift)
+
+ sl = "a\0".force_encoding("utf-32le")
+ sb = "a\0".force_encoding("utf-32be")
+ assert_equal(sl, sl.chomp)
+ assert_equal(sb, sb.chomp)
+ end
+
+ def test_mbc_to_code
+ sl = "a\0\0\0".force_encoding("utf-32le")
+ sb = "\0\0\0a".force_encoding("utf-32be")
+ assert_equal("a".ord, sl.ord)
+ assert_equal("a".ord, sb.ord)
+ end
+
+ def utf8_to_utf32(s, e)
+ s.chars.map {|c| c.ord.chr(e) }.join
+ end
+
+ def test_mbc_case_fold
+ rl = Regexp.new(utf8_to_utf32("^(\u3042)(a)\\1\\2$", "utf-32le"), "i")
+ rb = Regexp.new(utf8_to_utf32("^(\u3042)(a)\\1\\2$", "utf-32be"), "i")
+ assert_equal(Encoding.find("utf-32le"), rl.encoding)
+ assert_equal(Encoding.find("utf-32be"), rb.encoding)
+ assert_match(rl, utf8_to_utf32("\u3042a\u3042a", "utf-32le"))
+ assert_match(rb, utf8_to_utf32("\u3042a\u3042a", "utf-32be"))
+ end
+
+ def test_code_to_mbc
+ sl = "a\0\0\0".force_encoding("utf-32le")
+ sb = "\0\0\0a".force_encoding("utf-32be")
+ assert_equal(sl, "a".ord.chr("utf-32le"))
+ assert_equal(sb, "a".ord.chr("utf-32be"))
+ end
+end
+
diff --git a/trunk/test/ruby/enc/test_windows_1251.rb b/trunk/test/ruby/enc/test_windows_1251.rb
new file mode 100644
index 0000000000..6fbf3159a1
--- /dev/null
+++ b/trunk/test/ruby/enc/test_windows_1251.rb
@@ -0,0 +1,16 @@
+# encoding:windows-1251
+
+require "test/unit"
+
+class TestWindows1251 < Test::Unit::TestCase
+ def test_windows_1251
+ (0xc0..0xdf).each do |c|
+ c1 = c.chr("windows-1251")
+ c2 = (c + 0x20).chr("windows-1251")
+ assert_match(/^(#{ c1 })\1$/i, c2 + c1)
+ assert_match(/^(#{ c2 })\1$/i, c1 + c2)
+ assert_match(/^[#{ c1 }]+$/i, c2 + c1)
+ assert_match(/^[#{ c2 }]+$/i, c1 + c2)
+ end
+ end
+end
diff --git a/trunk/test/ruby/endblockwarn_rb b/trunk/test/ruby/endblockwarn_rb
new file mode 100644
index 0000000000..7b7f97f597
--- /dev/null
+++ b/trunk/test/ruby/endblockwarn_rb
@@ -0,0 +1,12 @@
+def end1
+ END {}
+end
+
+end1
+
+eval <<EOE
+ def end2
+ END {}
+ end
+EOE
+
diff --git a/trunk/test/ruby/envutil.rb b/trunk/test/ruby/envutil.rb
new file mode 100644
index 0000000000..4aba8a0bde
--- /dev/null
+++ b/trunk/test/ruby/envutil.rb
@@ -0,0 +1,176 @@
+require "open3"
+require "timeout"
+
+module EnvUtil
+ def rubybin
+ unless ENV["RUBYOPT"]
+
+ end
+ if ruby = ENV["RUBY"]
+ return ruby
+ end
+ ruby = "ruby"
+ rubyexe = ruby+".exe"
+ 3.times do
+ if File.exist? ruby and File.executable? ruby and !File.directory? ruby
+ return File.expand_path(ruby)
+ end
+ if File.exist? rubyexe and File.executable? rubyexe
+ return File.expand_path(rubyexe)
+ end
+ ruby = File.join("..", ruby)
+ end
+ begin
+ require "rbconfig"
+ File.join(
+ RbConfig::CONFIG["bindir"],
+ RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]
+ )
+ rescue LoadError
+ "ruby"
+ end
+ end
+ module_function :rubybin
+
+ LANG_ENVS = %w"LANG LC_ALL LC_CTYPE"
+ def rubyexec(*args)
+ ruby = EnvUtil.rubybin
+ c = "C"
+ env = {}
+ LANG_ENVS.each {|lc| env[lc], ENV[lc] = ENV[lc], c}
+ stdin = stdout = stderr = nil
+ Timeout.timeout(10) do
+ stdin, stdout, stderr = Open3.popen3(*([ruby] + args))
+ env.each_pair {|lc, v|
+ if v
+ ENV[lc] = v
+ else
+ ENV.delete(lc)
+ end
+ }
+ env = nil
+ yield(stdin, stdout, stderr)
+ end
+
+ ensure
+ env.each_pair {|lc, v|
+ if v
+ ENV[lc] = v
+ else
+ ENV.delete(lc)
+ end
+ } if env
+ stdin .close unless !stdin || stdin .closed?
+ stdout.close unless !stdout || stdout.closed?
+ stderr.close unless !stderr || stderr.closed?
+ end
+ module_function :rubyexec
+end
+
+module Test
+ module Unit
+ module Assertions
+ public
+ def assert_normal_exit(testsrc, message = '')
+ in_c, in_p = IO.pipe
+ out_p, out_c = IO.pipe
+ pid = spawn(EnvUtil.rubybin, '-W0', STDIN=>in_c, STDOUT=>out_c, STDERR=>out_c)
+ in_c.close
+ out_c.close
+ in_p.write testsrc
+ in_p.close
+ msg = out_p.read
+ out_p.close
+ Process.wait pid
+ status = $?
+ faildesc = nil
+ if status.signaled?
+ signo = status.termsig
+ signame = Signal.list.invert[signo]
+ sigdesc = "signal #{signo}"
+ if signame
+ sigdesc = "SIG#{signame} (#{sigdesc})"
+ end
+ if status.coredump?
+ sigdesc << " (core dumped)"
+ end
+ if msg.empty?
+ full_message = build_message(message, "pid ? killed by ?",
+ pid,
+ AssertionMessage::Literal.new(sigdesc))
+ else
+ msg << "\n" if /\n\z/ !~ msg
+ full_message = build_message(message, "pid ? killed by ?\n?",
+ pid,
+ AssertionMessage::Literal.new(sigdesc),
+ AssertionMessage::Literal.new(msg.gsub(/^/, '| ')))
+ end
+ end
+ assert_block(full_message) { !status.signaled? }
+ ensure
+ in_c.close if in_c && !in_c.closed?
+ in_p.close if in_p && !in_p.closed?
+ out_c.close if out_c && !out_c.closed?
+ out_p.close if out_p && !out_p.closed?
+ end
+
+ LANG_ENVS = %w"LANG LC_ALL LC_CTYPE"
+ def assert_in_out_err(args, test_stdin = "", test_stdout = "", test_stderr = "", message = nil)
+ in_c, in_p = IO.pipe
+ out_p, out_c = IO.pipe
+ err_p, err_c = IO.pipe
+ c = "C"
+ env = {}
+ LANG_ENVS.each {|lc| env[lc], ENV[lc] = ENV[lc], c}
+ pid = spawn(EnvUtil.rubybin, *args, STDIN=>in_c, STDOUT=>out_c, STDERR=>err_c)
+ in_c.close
+ out_c.close
+ err_c.close
+ in_p.write test_stdin
+ in_p.close
+ th_stdout = Thread.new { out_p.read }
+ th_stderr = Thread.new { err_p.read }
+ if th_stdout.join(10) && th_stderr.join(10)
+ stdout = th_stdout.value
+ stderr = th_stderr.value
+ else
+ flunk("timeout")
+ end
+ out_p.close
+ err_p.close
+ Process.wait pid
+ if block_given?
+ yield(stdout.lines.map {|l| l.chomp }, stderr.lines.map {|l| l.chomp })
+ else
+ if test_stdout.is_a?(Regexp)
+ assert_match(test_stdout, stdout, message)
+ else
+ assert_equal(test_stdout, stdout.lines.map {|l| l.chomp }, message)
+ end
+ if test_stderr.is_a?(Regexp)
+ assert_match(test_stderr, stderr, message)
+ else
+ assert_equal(test_stderr, stderr.lines.map {|l| l.chomp }, message)
+ end
+ end
+ ensure
+ env.each_pair {|lc, v|
+ if v
+ ENV[lc] = v
+ else
+ ENV.delete(lc)
+ end
+ } if env
+ in_c.close if in_c && !in_c.closed?
+ in_p.close if in_p && !in_p.closed?
+ out_c.close if out_c && !out_c.closed?
+ out_p.close if out_p && !out_p.closed?
+ err_c.close if err_c && !err_c.closed?
+ err_p.close if err_p && !err_p.closed?
+ (th_stdout.kill; th_stdout.join) if th_stdout
+ (th_stderr.kill; th_stderr.join) if th_stderr
+ end
+ end
+ end
+end
+
diff --git a/trunk/test/ruby/lbtest.rb b/trunk/test/ruby/lbtest.rb
new file mode 100644
index 0000000000..df7872dc76
--- /dev/null
+++ b/trunk/test/ruby/lbtest.rb
@@ -0,0 +1,48 @@
+require 'thread'
+
+class LocalBarrier
+ def initialize(n)
+ @wait = Queue.new
+ @done = Queue.new
+ @keeper = begin_keeper(n)
+ end
+
+ def sync
+ @done.push(true)
+ @wait.pop
+ end
+
+ def join
+ @keeper.join
+ end
+
+ private
+ def begin_keeper(n)
+ Thread.start do
+ n.times do
+ @done.pop
+ end
+ n.times do
+ @wait.push(true)
+ end
+ end
+ end
+end
+
+n = 10
+
+lb = LocalBarrier.new(n)
+
+(n - 1).times do |i|
+ Thread.start do
+ sleep((rand(n) + 1) / 10.0)
+ puts "#{i}: done"
+ lb.sync
+ puts "#{i}: cont"
+ end
+end
+
+lb.sync
+puts "#{n-1}: cone"
+
+puts "exit."
diff --git a/trunk/test/ruby/marshaltestlib.rb b/trunk/test/ruby/marshaltestlib.rb
new file mode 100644
index 0000000000..0a70380d44
--- /dev/null
+++ b/trunk/test/ruby/marshaltestlib.rb
@@ -0,0 +1,499 @@
+module MarshalTestLib
+ # include this module to a Test::Unit::TestCase and definde encode(o) and
+ # decode(s) methods. e.g.
+ #
+ # def encode(o)
+ # SOAPMarshal.dump(o)
+ # end
+ #
+ # def decode(s)
+ # SOAPMarshal.load(s)
+ # end
+
+ NegativeZero = (-1.0 / (1.0 / 0.0))
+
+ module Mod1; end
+ module Mod2; end
+
+ def marshaltest(o1)
+ str = encode(o1)
+ print str.dump, "\n" if $DEBUG
+ o2 = decode(str)
+ o2
+ end
+
+ def marshal_equal(o1, msg = nil)
+ msg = msg ? msg + "(#{ caller[0] })" : caller[0]
+ o2 = marshaltest(o1)
+ assert_equal(o1.class, o2.class, msg)
+ iv1 = o1.instance_variables.sort
+ iv2 = o2.instance_variables.sort
+ assert_equal(iv1, iv2)
+ val1 = iv1.map {|var| o1.instance_eval {eval var.to_s}}
+ val2 = iv1.map {|var| o2.instance_eval {eval var.to_s}}
+ assert_equal(val1, val2, msg)
+ if block_given?
+ assert_equal(yield(o1), yield(o2), msg)
+ else
+ assert_equal(o1, o2, msg)
+ end
+ end
+
+ class MyObject; def initialize(v) @v = v end; attr_reader :v; end
+ def test_object
+ o1 = Object.new
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_object_subclass
+ marshal_equal(MyObject.new(2)) {|o| o.v}
+ end
+
+ def test_object_extend
+ o1 = Object.new
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ def test_object_subclass_extend
+ o1 = MyObject.new(2)
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ class MyArray < Array
+ def initialize(v, *args)
+ super(args)
+ @v = v
+ end
+ end
+ def test_array
+ marshal_equal(5)
+ marshal_equal([1,2,3])
+ end
+
+ def test_array_subclass
+ marshal_equal(MyArray.new(0, 1, 2, 3))
+ end
+
+ def test_array_ivar
+ o1 = Array.new
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ class MyException < Exception; def initialize(v, *args) super(*args); @v = v; end; attr_reader :v; end
+ def test_exception
+ marshal_equal(Exception.new('foo')) {|o| o.message}
+ marshal_equal(assert_raise(NoMethodError) {no_such_method()}) {|o| o.message}
+ end
+
+ def test_exception_subclass
+ marshal_equal(MyException.new(20, "bar")) {|o| [o.message, o.v]}
+ end
+
+ def test_false
+ marshal_equal(false)
+ end
+
+ class MyHash < Hash; def initialize(v, *args) super(*args); @v = v; end end
+ def test_hash
+ marshal_equal({1=>2, 3=>4})
+ end
+
+ def test_hash_default
+ h = Hash.new(:default)
+ h[5] = 6
+ marshal_equal(h)
+ end
+
+ def test_hash_subclass
+ h = MyHash.new(7, 8)
+ h[4] = 5
+ marshal_equal(h)
+ end
+
+ def test_hash_default_proc
+ h = Hash.new {}
+ assert_raises(TypeError) { marshaltest(h) }
+ end
+
+ def test_hash_ivar
+ o1 = Hash.new
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_hash_extend
+ o1 = Hash.new
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ def test_hash_subclass_extend
+ o1 = MyHash.new(2)
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ def test_bignum
+ marshal_equal(-0x4000_0000_0000_0001)
+ marshal_equal(-0x4000_0001)
+ marshal_equal(0x4000_0000)
+ marshal_equal(0x4000_0000_0000_0000)
+ end
+
+ def test_fixnum
+ marshal_equal(-0x4000_0000)
+ marshal_equal(-0x3fff_ffff)
+ marshal_equal(-1)
+ marshal_equal(0)
+ marshal_equal(1)
+ marshal_equal(0x3fff_ffff)
+ end
+
+ def test_fixnum_ivar
+ o1 = 1
+ o1.instance_eval { @iv = 2 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ ensure
+ 1.instance_eval { remove_instance_variable("@iv") }
+ end
+
+ def test_fixnum_ivar_self
+ o1 = 1
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ ensure
+ 1.instance_eval { remove_instance_variable("@iv") }
+ end
+
+ def test_float
+ marshal_equal(-1.0)
+ marshal_equal(0.0)
+ marshal_equal(1.0)
+ end
+
+ def test_float_inf_nan
+ marshal_equal(1.0/0.0)
+ marshal_equal(-1.0/0.0)
+ marshal_equal(0.0/0.0) {|o| o.nan?}
+ marshal_equal(NegativeZero) {|o| 1.0/o}
+ end
+
+ def test_float_ivar
+ o1 = 1.23
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_float_ivar_self
+ o1 = 5.5
+ o1.instance_eval { @iv = o1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_float_extend
+ o1 = 0.0/0.0
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ class MyRange < Range; def initialize(v, *args) super(*args); @v = v; end end
+ def test_range
+ marshal_equal(1..2)
+ marshal_equal(1...3)
+ end
+
+ def test_range_subclass
+ marshal_equal(MyRange.new(4,5,8, false))
+ end
+
+ class MyRegexp < Regexp; def initialize(v, *args) super(*args); @v = v; end end
+ def test_regexp
+ marshal_equal(/a/)
+ marshal_equal(/A/i)
+ marshal_equal(/A/mx)
+ end
+
+ def test_regexp_subclass
+ marshal_equal(MyRegexp.new(10, "a"))
+ end
+
+ class MyString < String; def initialize(v, *args) super(*args); @v = v; end end
+ def test_string
+ marshal_equal("abc")
+ end
+
+ def test_string_ivar
+ o1 = ""
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_string_subclass
+ marshal_equal(MyString.new(10, "a"))
+ end
+
+ def test_string_subclass_cycle
+ str = MyString.new(10, "b")
+ str.instance_eval { @v = str }
+ marshal_equal(str) { |o|
+ assert_equal(o.__id__, o.instance_eval { @v }.__id__)
+ o.instance_eval { @v }
+ }
+ end
+
+ def test_string_subclass_extend
+ o = "abc"
+ o.extend(Mod1)
+ str = MyString.new(o, "c")
+ marshal_equal(str) { |o|
+ assert(o.instance_eval { @v }).kind_of?(Mod1)
+ }
+ end
+
+ MyStruct = Struct.new("MyStruct", :a, :b)
+ if RUBY_VERSION < "1.8.0"
+ # Struct#== is not defined in ruby/1.6
+ class MyStruct
+ def ==(rhs)
+ return true if __id__ == rhs.__id__
+ return false unless rhs.is_a?(::Struct)
+ return false if self.class != rhs.class
+ members.each do |member|
+ return false if self.__send__(member) != rhs.__send__(member)
+ end
+ return true
+ end
+ end
+ end
+ class MySubStruct < MyStruct; def initialize(v, *args) super(*args); @v = v; end end
+ def test_struct
+ marshal_equal(MyStruct.new(1,2))
+ end
+
+ def test_struct_subclass
+ if RUBY_VERSION < "1.8.0"
+ # Substruct instance cannot be dumped in ruby/1.6
+ # ::Marshal.dump(MySubStruct.new(10, 1, 2)) #=> uninitialized struct
+ return false
+ end
+ marshal_equal(MySubStruct.new(10,1,2))
+ end
+
+ def test_struct_ivar
+ o1 = MyStruct.new
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_struct_subclass_extend
+ o1 = MyStruct.new
+ o1.extend(Mod1)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ o1.extend(Mod2)
+ marshal_equal(o1) { |o|
+ (class << self; self; end).ancestors
+ }
+ end
+
+ def test_symbol
+ marshal_equal(:a)
+ marshal_equal(:a?)
+ marshal_equal(:a!)
+ marshal_equal(:a=)
+ marshal_equal(:|)
+ marshal_equal(:^)
+ marshal_equal(:&)
+ marshal_equal(:<=>)
+ marshal_equal(:==)
+ marshal_equal(:===)
+ marshal_equal(:=~)
+ marshal_equal(:>)
+ marshal_equal(:>=)
+ marshal_equal(:<)
+ marshal_equal(:<=)
+ marshal_equal(:<<)
+ marshal_equal(:>>)
+ marshal_equal(:+)
+ marshal_equal(:-)
+ marshal_equal(:*)
+ marshal_equal(:/)
+ marshal_equal(:%)
+ marshal_equal(:**)
+ marshal_equal(:~)
+ marshal_equal(:+@)
+ marshal_equal(:-@)
+ marshal_equal(:[])
+ marshal_equal(:[]=)
+ marshal_equal(:`) #`
+ marshal_equal("a b".intern)
+ end
+
+ class MyTime < Time; def initialize(v, *args) super(*args); @v = v; end end
+ def test_time
+ # once there was a bug caused by usec overflow. try a little harder.
+ 10.times do
+ t = Time.now
+ marshal_equal(t, t.usec.to_s)
+ end
+ end
+
+ def test_time_subclass
+ marshal_equal(MyTime.new(10))
+ end
+
+ def test_time_ivar
+ o1 = Time.now
+ o1.instance_eval { @iv = 1 }
+ marshal_equal(o1) {|o| o.instance_eval { @iv }}
+ end
+
+ def test_time_in_array
+ t = Time.now
+ assert_equal([t,t], Marshal.load(Marshal.dump([t, t])), "[ruby-dev:34159]")
+ end
+
+ def test_true
+ marshal_equal(true)
+ end
+
+ def test_nil
+ marshal_equal(nil)
+ end
+
+ def test_share
+ o = [:share]
+ o1 = [o, o]
+ o2 = marshaltest(o1)
+ assert_same(o2.first, o2.last)
+ end
+
+ class CyclicRange < Range
+ def <=>(other); true; end
+ end
+ def test_range_cyclic
+ return unless CyclicRange.respond_to?(:allocate) # test for 1.8
+ o1 = CyclicRange.allocate
+ o1.instance_eval { initialize(o1, o1) }
+ o2 = marshaltest(o1)
+ assert_same(o2, o2.begin)
+ assert_same(o2, o2.end)
+ end
+
+ def test_singleton
+ o = Object.new
+ def o.m() end
+ assert_raises(TypeError) { marshaltest(o) }
+ o = Object.new
+ c = class << o
+ @v = 1
+ class C; self; end
+ end
+ assert_raises(TypeError) { marshaltest(o) }
+ assert_raises(TypeError) { marshaltest(c) }
+ assert_raises(TypeError) { marshaltest(ARGF) }
+ assert_raises(TypeError) { marshaltest(ENV) }
+ end
+
+ def test_extend
+ o = Object.new
+ o.extend Mod1
+ marshal_equal(o) { |obj| obj.kind_of? Mod1 }
+ o = Object.new
+ o.extend Mod1
+ o.extend Mod2
+ marshal_equal(o) {|obj| class << obj; ancestors end}
+ o = Object.new
+ o.extend Module.new
+ assert_raises(TypeError) { marshaltest(o) }
+ end
+
+ def test_extend_string
+ o = ""
+ o.extend Mod1
+ marshal_equal(o) { |obj| obj.kind_of? Mod1 }
+ o = ""
+ o.extend Mod1
+ o.extend Mod2
+ marshal_equal(o) {|obj| class << obj; ancestors end}
+ o = ""
+ o.extend Module.new
+ assert_raises(TypeError) { marshaltest(o) }
+ end
+
+ def test_anonymous
+ c = Class.new
+ assert_raises(TypeError) { marshaltest(c) }
+ o = c.new
+ assert_raises(TypeError) { marshaltest(o) }
+ m = Module.new
+ assert_raises(TypeError) { marshaltest(m) }
+ end
+
+ def test_string_empty
+ marshal_equal("")
+ end
+
+ def test_string_crlf
+ marshal_equal("\r\n")
+ end
+
+ def test_string_escape
+ marshal_equal("\0<;;>\1;;")
+ end
+
+ MyStruct2 = Struct.new(:a, :b)
+ if RUBY_VERSION < "1.8.0"
+ # Struct#== is not defined in ruby/1.6
+ class MyStruct2
+ def ==(rhs)
+ return true if __id__ == rhs.__id__
+ return false unless rhs.is_a?(::Struct)
+ return false if self.class != rhs.class
+ members.each do |member|
+ return false if self.__send__(member) != rhs.__send__(member)
+ end
+ return true
+ end
+ end
+ end
+ def test_struct_toplevel
+ o = MyStruct2.new(1,2)
+ marshal_equal(o)
+ end
+end
diff --git a/trunk/test/ruby/sentence.rb b/trunk/test/ruby/sentence.rb
new file mode 100644
index 0000000000..50f42d6885
--- /dev/null
+++ b/trunk/test/ruby/sentence.rb
@@ -0,0 +1,668 @@
+# == sentence library
+#
+# = Features
+#
+# * syntax based sentences generation
+# * sentence operations such as substitution.
+#
+# = Example
+#
+# Some arithmetic expressions using "+", "-", "*" and "/" are generated as follows.
+#
+# require 'sentence'
+# Sentence.each({
+# :exp => [["num"],
+# [:exp, "+", :exp],
+# [:exp, "-", :exp],
+# [:exp, "*", :exp],
+# [:exp, "/", :exp]]
+# }, :exp, 2) {|sent| p sent }
+# #=>
+# #<Sentence: "num">
+# #<Sentence: ("num") "+" ("num")>
+# #<Sentence: ("num") "+" (("num") "+" ("num"))>
+# #<Sentence: ("num") "+" (("num") "-" ("num"))>
+# #<Sentence: ("num") "+" (("num") "*" ("num"))>
+# #<Sentence: ("num") "+" (("num") "/" ("num"))>
+# #<Sentence: (("num") "+" ("num")) "+" ("num")>
+# ...
+#
+# Sentence.each takes 3 arguments.
+# The first argument is the syntax for the expressions.
+# The second argument, :exp, is a generating nonterminal.
+# The third argument, 2, limits derivation to restrict results finitely.
+#
+# Some arithmetic expressions including parenthesis can be generated as follows.
+#
+# syntax = {
+# :factor => [["n"],
+# ["(", :exp, ")"]],
+# :term => [[:factor],
+# [:term, "*", :factor],
+# [:term, "/", :factor]],
+# :exp => [[:term],
+# [:exp, "+", :term],
+# [:exp, "-", :term]]
+# }
+# Sentence.each(syntax, :exp, 2) {|sent| p sent }
+# #=>
+# #<Sentence: (("n"))>
+# #<Sentence: (("(" ((("n"))) ")"))>
+# #<Sentence: (("(" ((("(" ((("n"))) ")"))) ")"))>
+# #<Sentence: (("(" (((("n")) "*" ("n"))) ")"))>
+# #<Sentence: (("(" (((("n")) "/" ("n"))) ")"))>
+# #<Sentence: (("(" (((("n"))) "+" (("n"))) ")"))>
+# #<Sentence: (("(" (((("n"))) "-" (("n"))) ")"))>
+# #<Sentence: ((("n")) "*" ("n"))>
+# #<Sentence: ((("n")) "*" ("(" ((("n"))) ")"))>
+# ...
+#
+# Sentence#to_s can be used to concatenate strings
+# in a sentence:
+#
+# Sentence.each(syntax, :exp, 2) {|sent| p sent.to_s }
+# #=>
+# "n"
+# "(n)"
+# "((n))"
+# "(n*n)"
+# "(n/n)"
+# "(n+n)"
+# "(n-n)"
+# "n*n"
+# "n*(n)"
+# ...
+#
+
+# Sentence() instantiates a sentence object.
+#
+# Sentence("foo", "bar")
+# #=> #<Sentence: "foo" "bar">
+#
+# Sentence("foo", ["bar", "baz"])
+# #=> #<Sentence: "foo" ("bar" "baz")>
+#
+def Sentence(*ary)
+ Sentence.new(ary)
+end
+
+# Sentence class represents a tree with string leaves.
+#
+class Sentence
+ # _ary_ represents a tree.
+ # It should be a possibly nested array which contains strings.
+ #
+ # Note that _ary_ is not copied.
+ # Don't modify _ary_ after the sentence object is instantiated.
+ #
+ # Sentence.new(["a", "pen"])
+ # #<Sentence: "a" "pen">
+ #
+ # Sentence.new(["I", "have", ["a", "pen"]])
+ # #<Sentence: "I" "have" ("a" "pen")>
+ #
+ def initialize(ary)
+ @sent = ary
+ end
+
+ # returns a string which is concatenation of all strings.
+ # No separator is used.
+ #
+ # Sentence("2", "+", "3").to_s
+ # "2+3"
+ #
+ # Sentence("2", "+", ["3", "*", "5"]).to_s
+ # "2+3*5"
+ #
+ def to_s
+ @sent.join('')
+ end
+
+ # returns a string which is concatenation of all strings separated by _sep_.
+ # If _sep_ is not given, single space is used.
+ #
+ # Sentence("I", "have", ["a", "pen"]).join
+ # "I have a pen"
+ #
+ # Sentence("I", "have", ["a", "pen"]).join("/")
+ # "I/have/a/pen"
+ #
+ # Sentence("a", [], "b").join("/")
+ # "a/b"
+ #
+ def join(sep=' ')
+ @sent.flatten.join(sep)
+ end
+
+ # returns a tree as a nested array.
+ #
+ # Note that the result is not copied.
+ # Don't modify the result.
+ #
+ # Sentence(["foo", "bar"], "baz").to_a
+ # #=> [["foo", "bar"], "baz"]
+ #
+ def to_a
+ @sent
+ end
+
+ # returns <i>i</i>th element as a sentence or string.
+ #
+ # s = Sentence(["foo", "bar"], "baz")
+ # s #=> #<Sentence: ("foo" "bar") "baz">
+ # s[0] #=> #<Sentence: "foo" "bar">
+ # s[1] #=> "baz"
+ #
+ def [](i)
+ e = @sent[i]
+ e.respond_to?(:to_ary) ? Sentence.new(e) : e
+ end
+
+ # returns the number of top level elements.
+ #
+ # Sentence.new(%w[foo bar]).length
+ # #=> 2
+ #
+ # Sentence(%w[2 * 7], "+", %w[3 * 5]).length
+ # #=> 3
+ #
+ def length
+ @sent.length
+ end
+
+ # iterates over children.
+ #
+ # Sentence(%w[2 * 7], "+", %w[3 * 5]).each {|v| p v }
+ # #=>
+ # #<Sentence: "2" "*" "7">
+ # "+"
+ # #<Sentence: "3" "*" "5">
+ #
+ def each # :yield: element
+ @sent.each_index {|i|
+ yield self[i]
+ }
+ end
+ include Enumerable
+
+ def inspect
+ "#<#{self.class}: #{inner_inspect(@sent, '')}>"
+ end
+
+ # :stopdoc:
+ def inner_inspect(ary, r)
+ first = true
+ ary.each {|obj|
+ r << ' ' if !first
+ first = false
+ if obj.respond_to? :to_ary
+ r << '('
+ inner_inspect(obj, r)
+ r << ')'
+ else
+ r << obj.inspect
+ end
+ }
+ r
+ end
+ # :startdoc:
+
+ # returns new sentence object which
+ # _target_ is substituted by the block.
+ #
+ # Sentence#subst invokes <tt>_target_ === _string_</tt> for each
+ # string in the sentence.
+ # The strings which === returns true are substituted by the block.
+ # The block is invoked with the substituting string.
+ #
+ # Sentence.new(%w[2 + 3]).subst("+") { "*" }
+ # #<Sentence: "2" "*" "3">
+ #
+ # Sentence.new(%w[2 + 3]).subst(/\A\d+\z/) {|s| ((s.to_i)*2).to_s }
+ # #=> #<Sentence: "4" "+" "6">
+ #
+ def subst(target, &b) # :yield: string
+ Sentence.new(subst_rec(@sent, target, &b))
+ end
+
+ # :stopdoc:
+ def subst_rec(obj, target, &b)
+ if obj.respond_to? :to_ary
+ a = []
+ obj.each {|e| a << subst_rec(e, target, &b) }
+ a
+ elsif target === obj
+ yield obj
+ else
+ obj
+ end
+ end
+ # :startdoc:
+
+ # find a subsentence and return it.
+ # The block is invoked for each subsentence in preorder manner.
+ # The first subsentence which the block returns true is returned.
+ #
+ # Sentence(%w[2 * 7], "+", %w[3 * 5]).find_subtree {|s| s[1] == "*" }
+ # #=> #<Sentence: "2" "*" "7">
+ #
+ def find_subtree(&b) # :yield: sentence
+ find_subtree_rec(@sent, &b)
+ end
+
+ # :stopdoc:
+ def find_subtree_rec(obj, &b)
+ if obj.respond_to? :to_ary
+ s = Sentence.new(obj)
+ if b.call s
+ return s
+ else
+ obj.each {|e|
+ r = find_subtree_rec(e, &b)
+ return r if r
+ }
+ end
+ end
+ nil
+ end
+ # :startdoc:
+
+ # returns a new sentence object which expands according to the condition
+ # given by the block.
+ #
+ # The block is invoked for each subsentence.
+ # The subsentences which the block returns true are
+ # expanded into parent.
+ #
+ # s = Sentence(%w[2 * 7], "+", %w[3 * 5])
+ # #=> #<Sentence: ("2" "*" "7") "+" ("3" "*" "5")>
+ #
+ # s.expand { true }
+ # #=> #<Sentence: "2" "*" "7" "+" "3" "*" "5">
+ #
+ # s.expand {|s| s[0] == "3" }
+ # #=> #<Sentence: (("2" "*" "7") "+" "3" "*" "5")>
+ #
+ def expand(&b) # :yield: sentence
+ Sentence.new(expand_rec(@sent, &b))
+ end
+
+ # :stopdoc:
+ def expand_rec(obj, r=[], &b)
+ if obj.respond_to? :to_ary
+ obj.each {|o|
+ s = Sentence.new(o)
+ if b.call s
+ expand_rec(o, r, &b)
+ else
+ a = []
+ expand_rec(o, a, &b)
+ r << a
+ end
+ }
+ else
+ r << obj
+ end
+ r
+ end
+ # :startdoc:
+
+ # Sentence.each generates sentences
+ # by deriving the start symbol _sym_ using _syntax_.
+ # The derivation is restricted by an positive integer _limit_ to
+ # avoid infinite generation.
+ #
+ # Sentence.each yields the block with a generated sentence.
+ #
+ # Sentence.each({
+ # :exp => [["n"],
+ # [:exp, "+", :exp],
+ # [:exp, "*", :exp]]
+ # }, :exp, 1) {|sent| p sent }
+ # #=>
+ # #<Sentence: "n">
+ # #<Sentence: ("n") "+" ("n")>
+ # #<Sentence: ("n") "*" ("n")>
+ #
+ # Sentence.each({
+ # :exp => [["n"],
+ # [:exp, "+", :exp],
+ # [:exp, "*", :exp]]
+ # }, :exp, 2) {|sent| p sent }
+ # #=>
+ # #<Sentence: "n">
+ # #<Sentence: ("n") "+" ("n")>
+ # #<Sentence: ("n") "+" (("n") "+" ("n"))>
+ # #<Sentence: ("n") "+" (("n") "*" ("n"))>
+ # #<Sentence: (("n") "+" ("n")) "+" ("n")>
+ # #<Sentence: (("n") "*" ("n")) "+" ("n")>
+ # #<Sentence: ("n") "*" ("n")>
+ # #<Sentence: ("n") "*" (("n") "+" ("n"))>
+ # #<Sentence: ("n") "*" (("n") "*" ("n"))>
+ # #<Sentence: (("n") "+" ("n")) "*" ("n")>
+ # #<Sentence: (("n") "*" ("n")) "*" ("n")>
+ #
+ def Sentence.each(syntax, sym, limit)
+ Gen.new(syntax).each_tree(sym, limit) {|tree|
+ yield Sentence.new(tree)
+ }
+ end
+
+ # Sentence.expand_syntax returns an expanded syntax:
+ # * No rule derives to empty sequence
+ # * Underivable rule simplified
+ # * No channel rule
+ # * Symbols which has zero or one choices are not appered in rhs.
+ #
+ # Note that the rules which can derive empty and non-empty
+ # sequences are modified to derive only non-empty sequences.
+ #
+ # Sentence.expand_syntax({
+ # :underivable1 => [],
+ # :underivable2 => [[:underivable1]],
+ # :underivable3 => [[:underivable3]],
+ # :empty_only1 => [[]],
+ # :empty_only2 => [[:just_empty1, :just_empty1]],
+ # :empty_or_not => [[], ["foo"]],
+ # :empty_or_not_2 => [[:empty_or_not, :empty_or_not]],
+ # :empty_or_not_3 => [[:empty_or_not, :empty_or_not, :empty_or_not]],
+ # :empty_or_not_4 => [[:empty_or_not_2, :empty_or_not_2]],
+ # :channel1 => [[:channeled_data]],
+ # :channeled_data => [["a", "b"], ["c", "d"]],
+ # :single_choice => [["single", "choice"]],
+ # :single_choice_2 => [[:single_choice, :single_choice]],
+ # })
+ # #=>
+ # {
+ # :underivable1=>[], # underivable rules are simplified to [].
+ # :underivable2=>[],
+ # :underivable3=>[],
+ # :empty_only1=>[], # derivation to empty sequence are removed.
+ # :empty_only2=>[],
+ # :empty_or_not=>[["foo"]], # empty sequences are removed too.
+ # :empty_or_not_2=>[["foo"], ["foo", "foo"]],
+ # :empty_or_not_3=>[["foo"], ["foo", "foo"], ["foo", "foo", "foo"]],
+ # :empty_or_not_4=> [["foo"], ["foo", "foo"], [:empty_or_not_2, :empty_or_not_2]],
+ # :channel1=>[["a", "b"], ["c", "d"]], # channel rules are removed.
+ # :channeled_data=>[["a", "b"], ["c", "d"]],
+ # :single_choice=>[["single", "choice"]], # single choice rules are expanded.
+ # :single_choice_2=>[["single", "choice", "single", "choice"]],
+ # }
+ #
+ # Sentence.expand_syntax({
+ # :factor => [["n"],
+ # ["(", :exp, ")"]],
+ # :term => [[:factor],
+ # [:term, "*", :factor],
+ # [:term, "/", :factor]],
+ # :exp => [[:term],
+ # [:exp, "+", :term],
+ # [:exp, "-", :term]]
+ # })
+ # #=>
+ # {:exp=> [["n"],
+ # ["(", :exp, ")"],
+ # [:exp, "+", :term],
+ # [:exp, "-", :term],
+ # [:term, "*", :factor],
+ # [:term, "/", :factor]],
+ # :factor=> [["n"],
+ # ["(", :exp, ")"]],
+ # :term=> [["n"],
+ # ["(", :exp, ")"],
+ # [:term, "*", :factor],
+ # [:term, "/", :factor]]
+ # }
+ #
+ def Sentence.expand_syntax(syntax)
+ Sentence::Gen.expand_syntax(syntax)
+ end
+
+ # :stopdoc:
+ class Gen
+ def Gen.each_tree(syntax, sym, limit, &b)
+ Gen.new(syntax).each_tree(sym, limit, &b)
+ end
+
+ def Gen.each_string(syntax, sym, limit, &b)
+ Gen.new(syntax).each_string(sym, limit, &b)
+ end
+
+ def initialize(syntax)
+ @syntax = syntax
+ end
+
+ def self.expand_syntax(syntax)
+ syntax = simplify_underivable_rules(syntax)
+ syntax = simplify_emptyonly_rules(syntax)
+ syntax = make_rules_no_empseq(syntax)
+ syntax = expand_channel_rules(syntax)
+
+ syntax = expand_noalt_rules(syntax)
+ syntax = reorder_rules(syntax)
+ end
+
+ def self.simplify_underivable_rules(syntax)
+ deribable_syms = {}
+ changed = true
+ while changed
+ changed = false
+ syntax.each {|sym, rules|
+ next if deribable_syms[sym]
+ rules.each {|rhs|
+ if rhs.all? {|e| String === e || deribable_syms[e] }
+ deribable_syms[sym] = true
+ changed = true
+ break
+ end
+ }
+ }
+ end
+ result = {}
+ syntax.each {|sym, rules|
+ if deribable_syms[sym]
+ rules2 = []
+ rules.each {|rhs|
+ rules2 << rhs if rhs.all? {|e| String === e || deribable_syms[e] }
+ }
+ result[sym] = rules2.uniq
+ else
+ result[sym] = []
+ end
+ }
+ result
+ end
+
+ def self.simplify_emptyonly_rules(syntax)
+ justempty_syms = {}
+ changed = true
+ while changed
+ changed = false
+ syntax.each {|sym, rules|
+ next if justempty_syms[sym]
+ if !rules.empty? && rules.all? {|rhs| rhs.all? {|e| justempty_syms[e] } }
+ justempty_syms[sym] = true
+ changed = true
+ end
+ }
+ end
+ result = {}
+ syntax.each {|sym, rules|
+ result[sym] = rules.map {|rhs| rhs.reject {|e| justempty_syms[e] } }.uniq
+ }
+ result
+ end
+
+ def self.expand_emptyable_syms(rhs, emptyable_syms)
+ if rhs.empty?
+ yield []
+ else
+ first = rhs[0]
+ rest = rhs[1..-1]
+ if emptyable_syms[first]
+ expand_emptyable_syms(rest, emptyable_syms) {|rhs2|
+ yield [first] + rhs2
+ yield rhs2
+ }
+ else
+ expand_emptyable_syms(rest, emptyable_syms) {|rhs2|
+ yield [first] + rhs2
+ }
+ end
+ end
+ end
+
+ def self.make_rules_no_empseq(syntax)
+ emptyable_syms = {}
+ changed = true
+ while changed
+ changed = false
+ syntax.each {|sym, rules|
+ next if emptyable_syms[sym]
+ rules.each {|rhs|
+ if rhs.all? {|e| emptyable_syms[e] }
+ emptyable_syms[sym] = true
+ changed = true
+ break
+ end
+ }
+ }
+ end
+ result = {}
+ syntax.each {|sym, rules|
+ rules2 = []
+ rules.each {|rhs|
+ expand_emptyable_syms(rhs, emptyable_syms) {|rhs2|
+ next if rhs2.empty?
+ rules2 << rhs2
+ }
+ }
+ result[sym] = rules2.uniq
+ }
+ result
+ end
+
+ def self.expand_channel_rules(syntax)
+ channel_rules = {}
+ syntax.each {|sym, rules|
+ channel_rules[sym] = {sym=>true}
+ rules.each {|rhs|
+ if rhs.length == 1 && Symbol === rhs[0]
+ channel_rules[sym][rhs[0]] = true
+ end
+ }
+ }
+ changed = true
+ while changed
+ changed = false
+ channel_rules.each {|sym, set|
+ n1 = set.size
+ set.keys.each {|s|
+ set.update(channel_rules[s])
+ }
+ n2 = set.size
+ changed = true if n1 < n2
+ }
+ end
+ result = {}
+ syntax.each {|sym, rules|
+ rules2 = []
+ channel_rules[sym].each_key {|s|
+ syntax[s].each {|rhs|
+ unless rhs.length == 1 && Symbol === rhs[0]
+ rules2 << rhs
+ end
+ }
+ }
+ result[sym] = rules2.uniq
+ }
+ result
+ end
+
+ def self.expand_noalt_rules(syntax)
+ noalt_syms = {}
+ syntax.each {|sym, rules|
+ if rules.length == 1
+ noalt_syms[sym] = true
+ end
+ }
+ result = {}
+ syntax.each {|sym, rules|
+ rules2 = []
+ rules.each {|rhs|
+ rhs2 = []
+ rhs.each {|e|
+ if noalt_syms[e]
+ rhs2.concat syntax[e][0]
+ else
+ rhs2 << e
+ end
+ }
+ rules2 << rhs2
+ }
+ result[sym] = rules2.uniq
+ }
+ result
+ end
+
+ def self.reorder_rules(syntax)
+ result = {}
+ syntax.each {|sym, rules|
+ result[sym] = rules.sort_by {|rhs|
+ [rhs.find_all {|e| Symbol === e }.length, rhs.length]
+ }
+ }
+ result
+ end
+
+ def each_tree(sym, limit)
+ generate_from_sym(sym, limit) {|_, tree|
+ yield tree
+ }
+ nil
+ end
+
+ def each_string(sym, limit)
+ generate_from_sym(sym, limit) {|_, tree|
+ yield [tree].join('')
+ }
+ nil
+ end
+
+ def generate_from_sym(sym, limit, &b)
+ return if limit < 0
+ if String === sym
+ yield limit, sym
+ else
+ rules = @syntax[sym]
+ raise "undefined rule: #{sym}" if !rules
+ rules.each {|rhs|
+ if rhs.length == 1 || rules.length == 1
+ limit1 = limit
+ else
+ limit1 = limit-1
+ end
+ generate_from_rhs(rhs, limit1, &b)
+ }
+ end
+ nil
+ end
+
+ def generate_from_rhs(rhs, limit)
+ return if limit < 0
+ if rhs.empty?
+ yield limit, []
+ else
+ generate_from_sym(rhs[0], limit) {|limit1, child|
+ generate_from_rhs(rhs[1..-1], limit1) {|limit2, arr|
+ yield limit2, [child, *arr]
+ }
+ }
+ end
+ nil
+ end
+ end
+ # :startdoc:
+
+end
+
diff --git a/trunk/test/ruby/test_alias.rb b/trunk/test/ruby/test_alias.rb
new file mode 100644
index 0000000000..d72fe702af
--- /dev/null
+++ b/trunk/test/ruby/test_alias.rb
@@ -0,0 +1,64 @@
+require 'test/unit'
+
+class TestAlias < Test::Unit::TestCase
+ class Alias0
+ def foo
+ "foo"
+ end
+ end
+
+ class Alias1 < Alias0
+ alias bar foo
+
+ def foo
+ "foo+#{super}"
+ end
+ end
+
+ class Alias2 < Alias1
+ alias baz foo
+ undef foo
+ end
+
+ class Alias3 < Alias2
+ def foo
+ super
+ end
+
+ def bar
+ super
+ end
+
+ def quux
+ super
+ end
+ end
+
+ def test_alias
+ x = Alias2.new
+ assert_equal "foo", x.bar
+ assert_equal "foo+foo", x.baz
+ assert_equal "foo+foo", x.baz # test_check for cache
+
+ x = Alias3.new
+ assert_raise(NoMethodError) { x.foo }
+ assert_equal "foo", x.bar
+ assert_raise(NoMethodError) { x.quux }
+ end
+
+ class C
+ def m
+ $SAFE
+ end
+ end
+
+ def test_JVN_83768862
+ d = lambda {
+ $SAFE = 4
+ dclass = Class.new(C)
+ dclass.send(:alias_method, :mm, :m)
+ dclass.new
+ }.call
+ assert_raise(SecurityError) { d.mm }
+ end
+end
diff --git a/trunk/test/ruby/test_argf.rb b/trunk/test/ruby/test_argf.rb
new file mode 100644
index 0000000000..eb5556b98a
--- /dev/null
+++ b/trunk/test/ruby/test_argf.rb
@@ -0,0 +1,701 @@
+require 'test/unit'
+require 'timeout'
+require 'tmpdir'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestArgf < Test::Unit::TestCase
+ def setup
+ @t1 = Tempfile.new("foo")
+ @t1.binmode
+ @t1.puts "1"
+ @t1.puts "2"
+ @t1.close
+ @t2 = Tempfile.new("bar")
+ @t2.binmode
+ @t2.puts "3"
+ @t2.puts "4"
+ @t2.close
+ @t3 = Tempfile.new("baz")
+ @t3.binmode
+ @t3.puts "5"
+ @t3.puts "6"
+ @t3.close
+ @tmps = [@t1, @t2, @t3]
+ end
+
+ def teardown
+ @tmps.each {|t|
+ bak = t.path + ".bak"
+ File.unlink bak if File.file? bak
+ }
+ end
+
+ def make_tempfile
+ t = Tempfile.new("foo")
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ @tmps << t
+ t
+ end
+
+ def ruby(*args)
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def no_safe_rename
+ /cygwin|mswin|mingw|bccwin/ =~ RUBY_PLATFORM
+ end
+
+ def test_argf
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF
+ b = a.dup
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 1]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 2]
+ a.rewind
+ b.rewind
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 3]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 4]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["3", 3, "3", 5]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["4", 4, "4", 6]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 7]
+ a.rewind
+ b.rewind
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 8]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["6", 6, "6", 9]
+ SRC
+ a = f.read.split("\n")
+ assert_equal('["1", 1, "1", 1]', a.shift)
+ assert_equal('["2", 2, "2", 2]', a.shift)
+ assert_equal('["1", 1, "1", 3]', a.shift)
+ assert_equal('["2", 2, "2", 4]', a.shift)
+ assert_equal('["3", 3, "3", 5]', a.shift)
+ assert_equal('["4", 4, "4", 6]', a.shift)
+ assert_equal('["5", 5, "5", 7]', a.shift)
+ assert_equal('["5", 5, "5", 8]', a.shift)
+ assert_equal('["6", 6, "6", 9]', a.shift)
+
+ # is this test OK? [ruby-dev:34445]
+ end
+ end
+
+ def test_lineno
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 3
+ a.rewind; p $. #=> 3
+ a.gets; p $. #=> 3
+ a.gets; p $. #=> 4
+ a.rewind; p $. #=> 4
+ a.gets; p $. #=> 3
+ a.lineno = 1000; p $. #=> 1000
+ a.gets; p $. #=> 1001
+ a.gets; p $. #=> 1002
+ $. = 2000
+ a.gets; p $. #=> 2001
+ a.gets; p $. #=> 2001
+ SRC
+ assert_equal("1,2,3,3,3,4,4,3,1000,1001,1002,2001,2001", f.read.chomp.gsub("\n", ","))
+ end
+ end
+
+ def test_lineno2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF.dup
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 1
+ a.rewind; p $. #=> 1
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 1
+ a.lineno = 1000; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 2
+ $. = 2000
+ a.gets; p $. #=> 2001
+ a.gets; p $. #=> 2000
+ SRC
+ assert_equal("1,2,1,1,1,2,1,1,2,2,2000,2000", f.read.chomp.gsub("\n", ","))
+ end
+ end
+
+ def test_inplace
+ assert_in_out_err(["-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+ ARGF.inplace_mode = '.bak'
+ while line = ARGF.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ assert_equal("1.new\n2.new\n", File.read(@t1.path))
+ assert_equal("3.new\n4.new\n", File.read(@t2.path))
+ assert_equal("5.new\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal("3\n4\n", File.read(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+
+ def test_inplace2
+ assert_in_out_err(["-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+ ARGF.inplace_mode = '.bak'
+ puts ARGF.gets.chomp + '.new'
+ puts ARGF.gets.chomp + '.new'
+ p ARGF.inplace_mode
+ ARGF.inplace_mode = nil
+ puts ARGF.gets.chomp + '.new'
+ puts ARGF.gets.chomp + '.new'
+ p ARGF.inplace_mode
+ ARGF.inplace_mode = '.bak'
+ puts ARGF.gets.chomp + '.new'
+ p ARGF.inplace_mode
+ ARGF.inplace_mode = nil
+ puts ARGF.gets.chomp + '.new'
+ INPUT
+ assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+ assert_equal("3\n4\n", File.read(@t2.path))
+ assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal(false, File.file?(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+
+ def test_inplace3
+ assert_in_out_err(["-i.bak", "-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+ puts ARGF.gets.chomp + '.new'
+ puts ARGF.gets.chomp + '.new'
+ p $-i
+ $-i = nil
+ puts ARGF.gets.chomp + '.new'
+ puts ARGF.gets.chomp + '.new'
+ p $-i
+ $-i = '.bak'
+ puts ARGF.gets.chomp + '.new'
+ p $-i
+ $-i = nil
+ puts ARGF.gets.chomp + '.new'
+ INPUT
+ assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+ assert_equal("3\n4\n", File.read(@t2.path))
+ assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal(false, File.file?(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+
+ def test_inplace_rename_impossible
+ t = make_tempfile
+
+ assert_in_out_err(["-", t.path], <<-INPUT) do |r, e|
+ ARGF.inplace_mode = '/\\\\'
+ while line = ARGF.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ if no_safe_rename
+ assert_equal([], e)
+ assert_equal([], r)
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ else
+ assert_match(/Can't rename .* to .*: .*. skipping file/, e.first) #'
+ assert_equal([], r)
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+ end
+ end
+ end
+
+ def test_inplace_no_backup
+ t = make_tempfile
+
+ assert_in_out_err(["-", t.path], <<-INPUT) do |r, e|
+ ARGF.inplace_mode = ''
+ while line = ARGF.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ if no_safe_rename
+ assert_match(/Can't do inplace edit without backup/, e.join) #'
+ else
+ assert_equal([], e)
+ assert_equal([], r)
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ end
+ end
+ end
+
+ def test_inplace_dup
+ t = make_tempfile
+
+ assert_in_out_err(["-", t.path], <<-INPUT, [], [])
+ ARGF.inplace_mode = '.bak'
+ f = ARGF.dup
+ while line = f.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ end
+
+ def test_inplace_stdin
+ t = make_tempfile
+
+ assert_in_out_err(["-", "-"], <<-INPUT, [], /Can't do inplace edit for stdio; skipping/)
+ ARGF.inplace_mode = '.bak'
+ f = ARGF.dup
+ while line = f.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ end
+
+ def test_inplace_stdin2
+ t = make_tempfile
+
+ assert_in_out_err(["-"], <<-INPUT, [], /Can't do inplace edit for stdio/)
+ ARGF.inplace_mode = '.bak'
+ while line = ARGF.gets
+ puts line.chomp + '.new'
+ end
+ INPUT
+ end
+
+ def test_encoding
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ p ARGF.external_encoding.is_a?(Encoding)
+ p ARGF.internal_encoding.is_a?(Encoding)
+ ARGF.gets
+ p ARGF.external_encoding.is_a?(Encoding)
+ p ARGF.internal_encoding
+ SRC
+ assert_equal("true\ntrue\ntrue\nnil\n", f.read)
+ end
+ end
+
+ def test_tell
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ ARGF.binmode
+ loop do
+ p ARGF.tell
+ p ARGF.gets
+ end
+ rescue ArgumentError
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ [0, 2, 4, 2, 4, 2, 4].map {|i| i.to_s }.
+ zip((1..6).map {|i| '"' + i.to_s + '\n"' } + ["nil"]).flatten.
+ each do |x|
+ assert_equal(x, a.shift)
+ end
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_seek
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.seek(4)
+ p ARGF.gets #=> "3"
+ ARGF.seek(0, IO::SEEK_END)
+ p ARGF.gets #=> "5"
+ ARGF.seek(4)
+ p ARGF.gets #=> nil
+ begin
+ ARGF.seek(0)
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_set_pos
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.pos = 4
+ p ARGF.gets #=> "3"
+ ARGF.pos = 4
+ p ARGF.gets #=> "5"
+ ARGF.pos = 4
+ p ARGF.gets #=> nil
+ begin
+ ARGF.pos = 4
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_rewind
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.pos = 4
+ ARGF.rewind
+ p ARGF.gets #=> "1"
+ ARGF.pos = 4
+ p ARGF.gets #=> "3"
+ ARGF.pos = 4
+ p ARGF.gets #=> "5"
+ ARGF.pos = 4
+ p ARGF.gets #=> nil
+ begin
+ ARGF.rewind
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"1\n"', a.shift)
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_fileno
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ begin
+ ARGF.fileno
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ fd1, fd2, fd3, fd4, tag = a
+ assert_match(/^\d+$/, fd1)
+ assert_match(/^\d+$/, fd2)
+ assert_match(/^\d+$/, fd3)
+ assert_match(/^\d+$/, fd4)
+ assert_equal('end', tag)
+ end
+ end
+
+ def test_to_io
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ 8.times do
+ p ARGF.to_io
+ ARGF.gets
+ end
+ SRC
+ a = f.read.split("\n")
+ f11, f12, f13, f21, f22, f31, f32, f4 = a
+ assert_equal(f11, f12)
+ assert_equal(f11, f13)
+ assert_equal(f21, f22)
+ assert_equal(f31, f32)
+ assert_match(/\(closed\)/, f4)
+ f4.sub!(/ \(closed\)/, "")
+ assert_equal(f31, f4)
+ end
+ end
+
+ def test_eof
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ 8.times do
+ p ARGF.eof?
+ ARGF.gets
+ end
+ rescue IOError
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ ((%w(true false) * 4).take(7) + %w(end)).each do |x|
+ assert_equal(x, a.shift)
+ end
+ end
+ end
+
+ def test_read
+ ruby('-e', "p ARGF.read(8)", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
+ end
+ end
+
+ def test_read2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ ARGF.read(8, s)
+ p s
+ SRC
+ assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
+ end
+ end
+
+ def test_read3
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ nil while ARGF.gets
+ p ARGF.read
+ p ARGF.read(0, "")
+ SRC
+ assert_equal("nil\n\"\"\n", f.read)
+ end
+ end
+
+ def test_readpartial
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ begin
+ loop do
+ s << ARGF.readpartial(1)
+ t = ""; ARGF.readpartial(1, t); s << t
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_readpartial2
+ ruby('-e', <<-SRC) do |f|
+ s = ""
+ begin
+ loop do
+ s << ARGF.readpartial(1)
+ t = ""; ARGF.readpartial(1, t); s << t
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ f.puts("foo")
+ f.puts("bar")
+ f.puts("baz")
+ f.close_write
+ assert_equal("foo\nbar\nbaz\n", f.read)
+ end
+ end
+
+ def test_getc
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ while c = ARGF.getc
+ s << c
+ end
+ puts s
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_getbyte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ while c = ARGF.getbyte
+ s << c
+ end
+ p s
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_readchar
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ begin
+ while c = ARGF.readchar
+ s << c
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_readbyte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ s = []
+ while c = ARGF.readbyte
+ s << c
+ end
+ rescue EOFError
+ p s
+ end
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_each_line
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ ARGF.each_line {|l| s << l }
+ p s
+ SRC
+ assert_equal("[\"1\\n\", \"2\\n\", \"3\\n\", \"4\\n\", \"5\\n\", \"6\\n\"]\n", f.read)
+ end
+ end
+
+ def test_each_line_paragraph
+ assert_in_out_err(['-e', 'ARGF.each_line("") {|para| p para}'], "a\n\nb\n",
+ ["\"a\\n\\n\"", "\"b\\n\""], [])
+ end
+
+ def test_each_byte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ ARGF.each_byte {|c| s << c }
+ p s
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_each_char
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ ARGF.each_char {|c| s << c }
+ puts s
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_filename
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts ARGF.filename.dump
+ end while ARGF.gets
+ puts ARGF.filename.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_filename2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts $FILENAME.dump
+ end while ARGF.gets
+ puts $FILENAME.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_file
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts ARGF.file.path.dump
+ end while ARGF.gets
+ puts ARGF.file.path.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_binmode
+ ruby('-e', "ARGF.binmode; STDOUT.binmode; puts ARGF.read", @t1.path, @t2.path, @t3.path) do |f|
+ f.binmode
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_skip
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ ARGF.skip
+ rescue
+ puts "cannot skip" # ???
+ end
+ puts ARGF.gets
+ ARGF.skip
+ puts ARGF.read
+ SRC
+ assert_equal("cannot skip\n1\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_close
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.close
+ puts ARGF.read
+ SRC
+ assert_equal("3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_closed
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ 3.times do
+ p ARGF.closed?
+ ARGF.gets
+ ARGF.gets
+ end
+ p ARGF.closed?
+ ARGF.gets
+ p ARGF.closed?
+ SRC
+ assert_equal("false\nfalse\nfalse\nfalse\ntrue\n", f.read)
+ end
+ end
+
+ def test_argv
+ ruby('-e', "p ARGF.argv; p $*", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
+ assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_array.rb b/trunk/test/ruby/test_array.rb
new file mode 100644
index 0000000000..234fb238a2
--- /dev/null
+++ b/trunk/test/ruby/test_array.rb
@@ -0,0 +1,1603 @@
+require 'test/unit'
+
+class TestArray < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ @cls = Array
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_0_literal
+ assert_equal([1, 2, 3, 4], [1, 2] + [3, 4])
+ assert_equal([1, 2, 1, 2], [1, 2] * 2)
+ assert_equal("1:2", [1, 2] * ":")
+
+ assert_equal([1, 2].hash, [1, 2].hash)
+
+ assert_equal([2,3], [1,2,3] & [2,3,4])
+ assert_equal([1,2,3,4], [1,2,3] | [2,3,4])
+ assert_equal([1,2,3] - [2,3], [1])
+
+ x = [0, 1, 2, 3, 4, 5]
+ assert_equal(2, x[2])
+ assert_equal([1, 2, 3], x[1..3])
+ assert_equal([1, 2, 3], x[1,3])
+
+ x[0, 2] = 10
+ assert(x[0] == 10 && x[1] == 2)
+
+ x[0, 0] = -1
+ assert(x[0] == -1 && x[1] == 10)
+
+ x[-1, 1] = 20
+ assert(x[-1] == 20 && x.pop == 20)
+ end
+
+ def test_array_andor_0
+ assert_equal([2], ([1,2,3]&[2,4,6]))
+ assert_equal([1,2,3,4,6], ([1,2,3]|[2,4,6]))
+ end
+
+ def test_compact_0
+ a = [nil, 1, nil, nil, 5, nil, nil]
+ assert_equal [1, 5], a.compact
+ assert_equal [nil, 1, nil, nil, 5, nil, nil], a
+ a.compact!
+ assert_equal [1, 5], a
+ end
+
+ def test_uniq_0
+ x = [1, 1, 4, 2, 5, 4, 5, 1, 2]
+ x.uniq!
+ assert_equal([1, 4, 2, 5], x)
+ end
+
+ def test_empty_0
+ assert_equal true, [].empty?
+ assert_equal false, [1].empty?
+ assert_equal false, [1, 1, 4, 2, 5, 4, 5, 1, 2].empty?
+ end
+
+ def test_sort_0
+ x = ["it", "came", "to", "pass", "that", "..."]
+ x = x.sort.join(" ")
+ assert_equal("... came it pass that to", x)
+ x = [2,5,3,1,7]
+ x.sort!{|a,b| a<=>b} # sort with condition
+ assert_equal([1,2,3,5,7], x)
+ x.sort!{|a,b| b-a} # reverse sort
+ assert_equal([7,5,3,2,1], x)
+ end
+
+ def test_split_0
+ x = "The Book of Mormon"
+ assert_equal(x.reverse, x.split(//).reverse!.join)
+ assert_equal(x.reverse, x.reverse!)
+ assert_equal("g:n:i:r:t:s: :e:t:y:b: :1", "1 byte string".split(//).reverse.join(":"))
+ x = "a b c d"
+ assert_equal(['a', 'b', 'c', 'd'], x.split)
+ assert_equal(['a', 'b', 'c', 'd'], x.split(' '))
+ end
+
+ def test_misc_0
+ assert(defined? "a".chomp)
+ assert_equal(["a", "b", "c"], "abc".scan(/./))
+ assert_equal([["1a"], ["2b"], ["3c"]], "1a2b3c".scan(/(\d.)/))
+ # non-greedy match
+ assert_equal([["a", "12"], ["b", "22"]], "a=12;b=22".scan(/(.*?)=(\d*);?/))
+
+ x = [1]
+ assert_equal('1:1:1:1:1', (x * 5).join(":"))
+ assert_equal('1', (x * 1).join(":"))
+ assert_equal('', (x * 0).join(":"))
+
+ *x = *(1..7).to_a
+ assert_equal(7, x.size)
+ assert_equal([1, 2, 3, 4, 5, 6, 7], x)
+
+ x = [1,2,3]
+ x[1,0] = x
+ assert_equal([1,1,2,3,2,3], x)
+
+ x = [1,2,3]
+ x[-1,0] = x
+ assert_equal([1,2,1,2,3,3], x)
+
+ x = [1,2,3]
+ x.concat(x)
+ assert_equal([1,2,3,1,2,3], x)
+
+ x = [1,2,3]
+ x.clear
+ assert_equal([], x)
+
+ x = [1,2,3]
+ y = x.dup
+ x << 4
+ y << 5
+ assert_equal([1,2,3,4], x)
+ assert_equal([1,2,3,5], y)
+ end
+
+ def test_beg_end_0
+ x = [1, 2, 3, 4, 5]
+
+ assert_equal(1, x.first)
+ assert_equal([1], x.first(1))
+ assert_equal([1, 2, 3], x.first(3))
+
+ assert_equal(5, x.last)
+ assert_equal([5], x.last(1))
+ assert_equal([3, 4, 5], x.last(3))
+
+ assert_equal(1, x.shift)
+ assert_equal([2, 3, 4], x.shift(3))
+ assert_equal([5], x)
+
+ assert_equal([2, 3, 4, 5], x.unshift(2, 3, 4))
+ assert_equal([1, 2, 3, 4, 5], x.unshift(1))
+ assert_equal([1, 2, 3, 4, 5], x)
+
+ assert_equal(5, x.pop)
+ assert_equal([3, 4], x.pop(2))
+ assert_equal([1, 2], x)
+
+ assert_equal([1, 2, 3, 4], x.push(3, 4))
+ assert_equal([1, 2, 3, 4, 5], x.push(5))
+ assert_equal([1, 2, 3, 4, 5], x)
+ end
+
+ def test_find_all_0
+ assert_respond_to([], :find_all)
+ assert_respond_to([], :select) # Alias
+ assert_equal([], [].find_all{ |obj| obj == "foo"})
+
+ x = ["foo", "bar", "baz", "baz", 1, 2, 3, 3, 4]
+ assert_equal(["baz","baz"], x.find_all{ |obj| obj == "baz" })
+ assert_equal([3,3], x.find_all{ |obj| obj == 3 })
+ end
+
+ def test_fill_0
+ assert_equal([-1, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1))
+ assert_equal([0, 1, 2, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 3))
+ assert_equal([0, 1, 2, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3, 2))
+ assert_equal([0, 1, 2, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 3, 5))
+ assert_equal([0, 1, -1, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2, 2))
+ assert_equal([0, 1, -1, -1, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, 2, 5))
+ assert_equal([0, 1, 2, 3, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, -2, 1))
+ assert_equal([0, 1, 2, 3, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, -2, 3))
+ assert_equal([0, 1, 2, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3..4))
+ assert_equal([0, 1, 2, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3...4))
+ assert_equal([0, 1, -1, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2..-2))
+ assert_equal([0, 1, -1, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2...-2))
+ assert_equal([10, 11, 12, 13, 14, 15], [0, 1, 2, 3, 4, 5].fill{|i| i+10})
+ assert_equal([0, 1, 2, 13, 14, 15], [0, 1, 2, 3, 4, 5].fill(3){|i| i+10})
+ assert_equal([0, 1, 2, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(3, 2){|i| i+10})
+ assert_equal([0, 1, 2, 13, 14, 15, 16, 17], [0, 1, 2, 3, 4, 5].fill(3, 5){|i| i+10})
+ assert_equal([0, 1, 2, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(3..4){|i| i+10})
+ assert_equal([0, 1, 2, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(3...4){|i| i+10})
+ assert_equal([0, 1, 12, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(2..-2){|i| i+10})
+ assert_equal([0, 1, 12, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(2...-2){|i| i+10})
+ end
+
+ # From rubicon
+
+ def test_00_new
+ a = @cls.new()
+ assert_instance_of(@cls, a)
+ assert_equal(0, a.length)
+ assert_nil(a[0])
+ end
+
+ def test_01_square_brackets
+ a = @cls[ 5, 4, 3, 2, 1 ]
+ assert_instance_of(@cls, a)
+ assert_equal(5, a.length)
+ 5.times { |i| assert_equal(5-i, a[i]) }
+ assert_nil(a[6])
+ end
+
+ def test_AND # '&'
+ assert_equal(@cls[1, 3], @cls[ 1, 1, 3, 5 ] & @cls[ 1, 2, 3 ])
+ assert_equal(@cls[], @cls[ 1, 1, 3, 5 ] & @cls[ ])
+ assert_equal(@cls[], @cls[ ] & @cls[ 1, 2, 3 ])
+ assert_equal(@cls[], @cls[ 1, 2, 3 ] & @cls[ 4, 5, 6 ])
+ end
+
+ def test_MUL # '*'
+ assert_equal(@cls[], @cls[]*3)
+ assert_equal(@cls[1, 1, 1], @cls[1]*3)
+ assert_equal(@cls[1, 2, 1, 2, 1, 2], @cls[1, 2]*3)
+ assert_equal(@cls[], @cls[1, 2, 3] * 0)
+ assert_raise(ArgumentError) { @cls[1, 2]*(-3) }
+
+ assert_equal('1-2-3-4-5', @cls[1, 2, 3, 4, 5] * '-')
+ assert_equal('12345', @cls[1, 2, 3, 4, 5] * '')
+
+ end
+
+ def test_PLUS # '+'
+ assert_equal(@cls[], @cls[] + @cls[])
+ assert_equal(@cls[1], @cls[1] + @cls[])
+ assert_equal(@cls[1], @cls[] + @cls[1])
+ assert_equal(@cls[1, 1], @cls[1] + @cls[1])
+ assert_equal(@cls['cat', 'dog', 1, 2, 3], %w(cat dog) + (1..3).to_a)
+ end
+
+ def test_MINUS # '-'
+ assert_equal(@cls[], @cls[1] - @cls[1])
+ assert_equal(@cls[1], @cls[1, 2, 3, 4, 5] - @cls[2, 3, 4, 5])
+ # Ruby 1.8 feature change
+ #assert_equal(@cls[1], @cls[1, 2, 1, 3, 1, 4, 1, 5] - @cls[2, 3, 4, 5])
+ assert_equal(@cls[1, 1, 1, 1], @cls[1, 2, 1, 3, 1, 4, 1, 5] - @cls[2, 3, 4, 5])
+ a = @cls[]
+ 1000.times { a << 1 }
+ assert_equal(1000, a.length)
+ #assert_equal(@cls[1], a - @cls[2])
+ assert_equal(@cls[1] * 1000, a - @cls[2])
+ #assert_equal(@cls[1], @cls[1, 2, 1] - @cls[2])
+ assert_equal(@cls[1, 1], @cls[1, 2, 1] - @cls[2])
+ assert_equal(@cls[1, 2, 3], @cls[1, 2, 3] - @cls[4, 5, 6])
+ end
+
+ def test_LSHIFT # '<<'
+ a = @cls[]
+ a << 1
+ assert_equal(@cls[1], a)
+ a << 2 << 3
+ assert_equal(@cls[1, 2, 3], a)
+ a << nil << 'cat'
+ assert_equal(@cls[1, 2, 3, nil, 'cat'], a)
+ a << a
+ assert_equal(@cls[1, 2, 3, nil, 'cat', a], a)
+ end
+
+ def test_CMP # '<=>'
+ assert_equal(0, @cls[] <=> @cls[])
+ assert_equal(0, @cls[1] <=> @cls[1])
+ assert_equal(0, @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3, 'cat'])
+ assert_equal(-1, @cls[] <=> @cls[1])
+ assert_equal(1, @cls[1] <=> @cls[])
+ assert_equal(-1, @cls[1, 2, 3] <=> @cls[1, 2, 3, 'cat'])
+ assert_equal(1, @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3])
+ assert_equal(-1, @cls[1, 2, 3, 'cat'] <=> @cls[1, 2, 3, 'dog'])
+ assert_equal(1, @cls[1, 2, 3, 'dog'] <=> @cls[1, 2, 3, 'cat'])
+ end
+
+ def test_EQUAL # '=='
+ assert(@cls[] == @cls[])
+ assert(@cls[1] == @cls[1])
+ assert(@cls[1, 1, 2, 2] == @cls[1, 1, 2, 2])
+ assert(@cls[1.0, 1.0, 2.0, 2.0] == @cls[1, 1, 2, 2])
+ end
+
+ def test_VERY_EQUAL # '==='
+ assert(@cls[] === @cls[])
+ assert(@cls[1] === @cls[1])
+ assert(@cls[1, 1, 2, 2] === @cls[1, 1, 2, 2])
+ assert(@cls[1.0, 1.0, 2.0, 2.0] === @cls[1, 1, 2, 2])
+ end
+
+ def test_AREF # '[]'
+ a = @cls[*(1..100).to_a]
+
+ assert_equal(1, a[0])
+ assert_equal(100, a[99])
+ assert_nil(a[100])
+ assert_equal(100, a[-1])
+ assert_equal(99, a[-2])
+ assert_equal(1, a[-100])
+ assert_nil(a[-101])
+ assert_nil(a[-101,0])
+ assert_nil(a[-101,1])
+ assert_nil(a[-101,-1])
+ assert_nil(a[10,-1])
+
+ assert_equal(@cls[1], a[0,1])
+ assert_equal(@cls[100], a[99,1])
+ assert_equal(@cls[], a[100,1])
+ assert_equal(@cls[100], a[99,100])
+ assert_equal(@cls[100], a[-1,1])
+ assert_equal(@cls[99], a[-2,1])
+ assert_equal(@cls[], a[-100,0])
+ assert_equal(@cls[1], a[-100,1])
+
+ assert_equal(@cls[10, 11, 12], a[9, 3])
+ assert_equal(@cls[10, 11, 12], a[-91, 3])
+
+ assert_equal(@cls[1], a[0..0])
+ assert_equal(@cls[100], a[99..99])
+ assert_equal(@cls[], a[100..100])
+ assert_equal(@cls[100], a[99..200])
+ assert_equal(@cls[100], a[-1..-1])
+ assert_equal(@cls[99], a[-2..-2])
+
+ assert_equal(@cls[10, 11, 12], a[9..11])
+ assert_equal(@cls[10, 11, 12], a[-91..-89])
+
+ assert_nil(a[10, -3])
+ # Ruby 1.8 feature change:
+ # Array#[size..x] returns [] instead of nil.
+ #assert_nil(a[10..7])
+ assert_equal [], a[10..7]
+
+ assert_raise(TypeError) {a['cat']}
+ end
+
+ def test_ASET # '[]='
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[0] = 0)
+ assert_equal(@cls[0] + @cls[*(1..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[10,10] = 0)
+ assert_equal(@cls[*(0..9).to_a] + @cls[0] + @cls[*(20..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[-1] = 0)
+ assert_equal(@cls[*(0..98).to_a] + @cls[0], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[-10, 10] = 0)
+ assert_equal(@cls[*(0..89).to_a] + @cls[0], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[0,1000] = 0)
+ assert_equal(@cls[0] , a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a[10..19] = 0)
+ assert_equal(@cls[*(0..9).to_a] + @cls[0] + @cls[*(20..99).to_a], a)
+
+ b = @cls[*%w( a b c )]
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[0,1] = b)
+ assert_equal(b + @cls[*(1..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[10,10] = b)
+ assert_equal(@cls[*(0..9).to_a] + b + @cls[*(20..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[-1, 1] = b)
+ assert_equal(@cls[*(0..98).to_a] + b, a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[-10, 10] = b)
+ assert_equal(@cls[*(0..89).to_a] + b, a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[0,1000] = b)
+ assert_equal(b , a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(b, a[10..19] = b)
+ assert_equal(@cls[*(0..9).to_a] + b + @cls[*(20..99).to_a], a)
+
+ # Ruby 1.8 feature change:
+ # assigning nil does not remove elements.
+=begin
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[0,1] = nil)
+ assert_equal(@cls[*(1..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[10,10] = nil)
+ assert_equal(@cls[*(0..9).to_a] + @cls[*(20..99).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[-1, 1] = nil)
+ assert_equal(@cls[*(0..98).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[-10, 10] = nil)
+ assert_equal(@cls[*(0..89).to_a], a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[0,1000] = nil)
+ assert_equal(@cls[] , a)
+
+ a = @cls[*(0..99).to_a]
+ assert_equal(nil, a[10..19] = nil)
+ assert_equal(@cls[*(0..9).to_a] + @cls[*(20..99).to_a], a)
+=end
+
+ a = @cls[1, 2, 3]
+ a[1, 0] = a
+ assert_equal([1, 1, 2, 3, 2, 3], a)
+
+ a = @cls[1, 2, 3]
+ a[-1, 0] = a
+ assert_equal([1, 2, 1, 2, 3, 3], a)
+ end
+
+ def test_assoc
+ a1 = @cls[*%w( cat feline )]
+ a2 = @cls[*%w( dog canine )]
+ a3 = @cls[*%w( mule asinine )]
+
+ a = @cls[ a1, a2, a3 ]
+
+ assert_equal(a1, a.assoc('cat'))
+ assert_equal(a3, a.assoc('mule'))
+ assert_equal(nil, a.assoc('asinine'))
+ assert_equal(nil, a.assoc('wombat'))
+ assert_equal(nil, a.assoc(1..2))
+ end
+
+ def test_at
+ a = @cls[*(0..99).to_a]
+ assert_equal(0, a.at(0))
+ assert_equal(10, a.at(10))
+ assert_equal(99, a.at(99))
+ assert_equal(nil, a.at(100))
+ assert_equal(99, a.at(-1))
+ assert_equal(0, a.at(-100))
+ assert_equal(nil, a.at(-101))
+ assert_raise(TypeError) { a.at('cat') }
+ end
+
+ def test_clear
+ a = @cls[1, 2, 3]
+ b = a.clear
+ assert_equal(@cls[], a)
+ assert_equal(@cls[], b)
+ assert_equal(a.__id__, b.__id__)
+ end
+
+ def test_clone
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = @cls[*(0..99).to_a]
+ a.taint if taint
+ a.untrust if untrust
+ a.freeze if frozen
+ b = a.clone
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(a.frozen?, b.frozen?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+ end
+
+ def test_collect
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal([ Fixnum, String, Range], a.collect {|e| e.class} )
+ assert_equal([ 99, 99, 99], a.collect { 99 } )
+
+ assert_equal([], @cls[].collect { 99 })
+
+ # Ruby 1.9 feature change:
+ # Enumerable#collect without block returns an Enumerator.
+ #assert_equal([1, 2, 3], @cls[1, 2, 3].collect)
+ assert_kind_of Enumerator, @cls[1, 2, 3].collect
+ end
+
+ # also update map!
+ def test_collect!
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal([ Fixnum, String, Range], a.collect! {|e| e.class} )
+ assert_equal([ Fixnum, String, Range], a)
+
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal([ 99, 99, 99], a.collect! { 99 } )
+ assert_equal([ 99, 99, 99], a)
+
+ a = @cls[ ]
+ assert_equal([], a.collect! { 99 })
+ assert_equal([], a)
+ end
+
+ def test_compact
+ a = @cls[ 1, nil, nil, 2, 3, nil, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact)
+
+ a = @cls[ nil, 1, nil, 2, 3, nil, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact)
+
+ a = @cls[ 1, nil, nil, 2, 3, nil, 4, nil ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact)
+
+ a = @cls[ 1, 2, 3, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact)
+ end
+
+ def test_compact!
+ a = @cls[ 1, nil, nil, 2, 3, nil, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+
+ a = @cls[ nil, 1, nil, 2, 3, nil, 4 ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+
+ a = @cls[ 1, nil, nil, 2, 3, nil, 4, nil ]
+ assert_equal(@cls[1, 2, 3, 4], a.compact!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+
+ a = @cls[ 1, 2, 3, 4 ]
+ assert_equal(nil, a.compact!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+ end
+
+ def test_concat
+ assert_equal(@cls[1, 2, 3, 4], @cls[1, 2].concat(@cls[3, 4]))
+ assert_equal(@cls[1, 2, 3, 4], @cls[].concat(@cls[1, 2, 3, 4]))
+ assert_equal(@cls[1, 2, 3, 4], @cls[1, 2, 3, 4].concat(@cls[]))
+ assert_equal(@cls[], @cls[].concat(@cls[]))
+ assert_equal(@cls[@cls[1, 2], @cls[3, 4]], @cls[@cls[1, 2]].concat(@cls[@cls[3, 4]]))
+
+ a = @cls[1, 2, 3]
+ a.concat(a)
+ assert_equal([1, 2, 3, 1, 2, 3], a)
+ end
+
+ def test_count
+ a = @cls[1, 2, 3, 1, 2]
+ assert_equal(5, a.count)
+ assert_equal(2, a.count(1))
+ assert_equal(3, a.count {|x| x % 2 == 1 })
+ assert_equal(2, a.count(1) {|x| x % 2 == 1 })
+ assert_raise(ArgumentError) { a.count(0, 1) }
+ end
+
+ def test_delete
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal('cap', a.delete('cap'))
+ assert_equal(@cls[*('cab'..'cao').to_a] + @cls[*('caq'..'cat').to_a], a)
+
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal('cab', a.delete('cab'))
+ assert_equal(@cls[*('cac'..'cat').to_a], a)
+
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal('cat', a.delete('cat'))
+ assert_equal(@cls[*('cab'..'cas').to_a], a)
+
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal(nil, a.delete('cup'))
+ assert_equal(@cls[*('cab'..'cat').to_a], a)
+
+ a = @cls[*('cab'..'cat').to_a]
+ assert_equal(99, a.delete('cup') { 99 } )
+ assert_equal(@cls[*('cab'..'cat').to_a], a)
+ end
+
+ def test_delete_at
+ a = @cls[*(1..5).to_a]
+ assert_equal(3, a.delete_at(2))
+ assert_equal(@cls[1, 2, 4, 5], a)
+
+ a = @cls[*(1..5).to_a]
+ assert_equal(4, a.delete_at(-2))
+ assert_equal(@cls[1, 2, 3, 5], a)
+
+ a = @cls[*(1..5).to_a]
+ assert_equal(nil, a.delete_at(5))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[*(1..5).to_a]
+ assert_equal(nil, a.delete_at(-6))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+ end
+
+ # also reject!
+ def test_delete_if
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.delete_if { false })
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.delete_if { true })
+ assert_equal(@cls[], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.delete_if { |i| i > 3 })
+ assert_equal(@cls[1, 2, 3], a)
+ end
+
+ def test_dup
+ for taint in [ false, true ]
+ for frozen in [ false, true ]
+ a = @cls[*(0..99).to_a]
+ a.taint if taint
+ a.freeze if frozen
+ b = a.dup
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(false, b.frozen?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+
+ def test_each
+ a = @cls[*%w( ant bat cat dog )]
+ i = 0
+ a.each { |e|
+ assert_equal(a[i], e)
+ i += 1
+ }
+ assert_equal(4, i)
+
+ a = @cls[]
+ i = 0
+ a.each { |e|
+ assert_equal(a[i], e)
+ i += 1
+ }
+ assert_equal(0, i)
+
+ assert_equal(a, a.each {})
+ end
+
+ def test_each_index
+ a = @cls[*%w( ant bat cat dog )]
+ i = 0
+ a.each_index { |ind|
+ assert_equal(i, ind)
+ i += 1
+ }
+ assert_equal(4, i)
+
+ a = @cls[]
+ i = 0
+ a.each_index { |ind|
+ assert_equal(i, ind)
+ i += 1
+ }
+ assert_equal(0, i)
+
+ assert_equal(a, a.each_index {})
+ end
+
+ def test_empty?
+ assert(@cls[].empty?)
+ assert(!@cls[1].empty?)
+ end
+
+ def test_eql?
+ assert(@cls[].eql?(@cls[]))
+ assert(@cls[1].eql?(@cls[1]))
+ assert(@cls[1, 1, 2, 2].eql?(@cls[1, 1, 2, 2]))
+ assert(!@cls[1.0, 1.0, 2.0, 2.0].eql?(@cls[1, 1, 2, 2]))
+ end
+
+ def test_fill
+ assert_equal(@cls[], @cls[].fill(99))
+ assert_equal(@cls[], @cls[].fill(99, 0))
+ assert_equal(@cls[99], @cls[].fill(99, 0, 1))
+ assert_equal(@cls[99], @cls[].fill(99, 0..0))
+
+ assert_equal(@cls[99], @cls[1].fill(99))
+ assert_equal(@cls[99], @cls[1].fill(99, 0))
+ assert_equal(@cls[99], @cls[1].fill(99, 0, 1))
+ assert_equal(@cls[99], @cls[1].fill(99, 0..0))
+
+ assert_equal(@cls[99, 99], @cls[1, 2].fill(99))
+ assert_equal(@cls[99, 99], @cls[1, 2].fill(99, 0))
+ assert_equal(@cls[99, 99], @cls[1, 2].fill(99, nil))
+ assert_equal(@cls[1, 99], @cls[1, 2].fill(99, 1, nil))
+ assert_equal(@cls[99, 2], @cls[1, 2].fill(99, 0, 1))
+ assert_equal(@cls[99, 2], @cls[1, 2].fill(99, 0..0))
+ end
+
+ def test_first
+ assert_equal(3, @cls[3, 4, 5].first)
+ assert_equal(nil, @cls[].first)
+ end
+
+ def test_flatten
+ a1 = @cls[ 1, 2, 3]
+ a2 = @cls[ 5, 6 ]
+ a3 = @cls[ 4, a2 ]
+ a4 = @cls[ a1, a3 ]
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a4.flatten)
+ assert_equal(@cls[ a1, a3], a4)
+
+ a5 = @cls[ a1, @cls[], a3 ]
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a5.flatten)
+ assert_equal(@cls[], @cls[].flatten)
+ assert_equal(@cls[],
+ @cls[@cls[@cls[@cls[],@cls[]],@cls[@cls[]],@cls[]],@cls[@cls[@cls[]]]].flatten)
+
+ assert_raise(TypeError, "[ruby-dev:31197]") { [[]].flatten("") }
+
+ a6 = @cls[[1, 2], 3]
+ a6.taint
+ a6.untrust
+ a7 = a6.flatten
+ assert_equal(true, a7.tainted?)
+ assert_equal(true, a7.untrusted?)
+ end
+
+ def test_flatten!
+ a1 = @cls[ 1, 2, 3]
+ a2 = @cls[ 5, 6 ]
+ a3 = @cls[ 4, a2 ]
+ a4 = @cls[ a1, a3 ]
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a4.flatten!)
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a4)
+
+ a5 = @cls[ a1, @cls[], a3 ]
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a5.flatten!)
+ assert_equal(@cls[1, 2, 3, 4, 5, 6], a5)
+
+ assert_equal(@cls[], @cls[].flatten)
+ assert_equal(@cls[],
+ @cls[@cls[@cls[@cls[],@cls[]],@cls[@cls[]],@cls[]],@cls[@cls[@cls[]]]].flatten)
+ end
+
+ def test_flatten_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ o = Object.new
+ def o.to_ary() callcc {|k| @cont = k; [1,2,3]} end
+ begin
+ assert_equal([10, 20, 1, 2, 3, 30, 1, 2, 3, 40], [10, 20, o, 30, o, 40].flatten)
+ rescue => e
+ else
+ o.instance_eval {@cont}.call
+ end
+ assert_instance_of(RuntimeError, e, '[ruby-dev:34798]')
+ assert_match(/reentered/, e.message, '[ruby-dev:34798]')
+ end
+
+ def test_hash
+ a1 = @cls[ 'cat', 'dog' ]
+ a2 = @cls[ 'cat', 'dog' ]
+ a3 = @cls[ 'dog', 'cat' ]
+ assert(a1.hash == a2.hash)
+ assert(a1.hash != a3.hash)
+ end
+
+ def test_include?
+ a = @cls[ 'cat', 99, /a/, @cls[ 1, 2, 3] ]
+ assert(a.include?('cat'))
+ assert(a.include?(99))
+ assert(a.include?(/a/))
+ assert(a.include?([1,2,3]))
+ assert(!a.include?('ca'))
+ assert(!a.include?([1,2]))
+ end
+
+ def test_index
+ a = @cls[ 'cat', 99, /a/, 99, @cls[ 1, 2, 3] ]
+ assert_equal(0, a.index('cat'))
+ assert_equal(1, a.index(99))
+ assert_equal(4, a.index([1,2,3]))
+ assert_nil(a.index('ca'))
+ assert_nil(a.index([1,2]))
+ end
+
+ def test_values_at
+ a = @cls[*('a'..'j').to_a]
+ assert_equal(@cls['a', 'c', 'e'], a.values_at(0, 2, 4))
+ assert_equal(@cls['j', 'h', 'f'], a.values_at(-1, -3, -5))
+ assert_equal(@cls['h', nil, 'a'], a.values_at(-3, 99, 0))
+ end
+
+ def test_join
+ $, = ""
+ a = @cls[]
+ assert_equal("", a.join)
+ assert_equal("", a.join(','))
+
+ $, = ""
+ a = @cls[1, 2]
+ assert_equal("12", a.join)
+ assert_equal("1,2", a.join(','))
+
+ $, = ""
+ a = @cls[1, 2, 3]
+ assert_equal("123", a.join)
+ assert_equal("1,2,3", a.join(','))
+
+ $, = ":"
+ a = @cls[1, 2, 3]
+ assert_equal("1:2:3", a.join)
+ assert_equal("1,2,3", a.join(','))
+
+ $, = ""
+ a = @cls[1, 2, 3]
+ a.taint
+ a.untrust
+ s = a.join
+ assert_equal(true, s.tainted?)
+ assert_equal(true, s.untrusted?)
+ end
+
+ def test_last
+ assert_equal(nil, @cls[].last)
+ assert_equal(1, @cls[1].last)
+ assert_equal(99, @cls[*(3..99).to_a].last)
+ end
+
+ def test_length
+ assert_equal(0, @cls[].length)
+ assert_equal(1, @cls[1].length)
+ assert_equal(2, @cls[1, nil].length)
+ assert_equal(2, @cls[nil, 1].length)
+ assert_equal(234, @cls[*(0..233).to_a].length)
+ end
+
+ # also update collect!
+ def test_map!
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal(@cls[ Fixnum, String, Range], a.map! {|e| e.class} )
+ assert_equal(@cls[ Fixnum, String, Range], a)
+
+ a = @cls[ 1, 'cat', 1..1 ]
+ assert_equal(@cls[ 99, 99, 99], a.map! { 99 } )
+ assert_equal(@cls[ 99, 99, 99], a)
+
+ a = @cls[ ]
+ assert_equal(@cls[], a.map! { 99 })
+ assert_equal(@cls[], a)
+ end
+
+ def test_pack
+ a = @cls[*%w( cat wombat x yy)]
+ assert_equal("catwomx yy ", a.pack("A3A3A3A3"))
+ assert_equal("cat", a.pack("A*"))
+ assert_equal("cwx yy ", a.pack("A3@1A3@2A3A3"))
+ assert_equal("catwomx\000\000yy\000", a.pack("a3a3a3a3"))
+ assert_equal("cat", a.pack("a*"))
+ assert_equal("ca", a.pack("a2"))
+ assert_equal("cat\000\000", a.pack("a5"))
+
+ assert_equal("\x61", @cls["01100001"].pack("B8"))
+ assert_equal("\x61", @cls["01100001"].pack("B*"))
+ assert_equal("\x61", @cls["0110000100110111"].pack("B8"))
+ assert_equal("\x61\x37", @cls["0110000100110111"].pack("B16"))
+ assert_equal("\x61\x37", @cls["01100001", "00110111"].pack("B8B8"))
+ assert_equal("\x60", @cls["01100001"].pack("B4"))
+ assert_equal("\x40", @cls["01100001"].pack("B2"))
+
+ assert_equal("\x86", @cls["01100001"].pack("b8"))
+ assert_equal("\x86", @cls["01100001"].pack("b*"))
+ assert_equal("\x86", @cls["0110000100110111"].pack("b8"))
+ assert_equal("\x86\xec", @cls["0110000100110111"].pack("b16"))
+ assert_equal("\x86\xec", @cls["01100001", "00110111"].pack("b8b8"))
+ assert_equal("\x06", @cls["01100001"].pack("b4"))
+ assert_equal("\x02", @cls["01100001"].pack("b2"))
+
+ assert_equal("ABC", @cls[ 65, 66, 67 ].pack("C3"))
+ assert_equal("\377BC", @cls[ -1, 66, 67 ].pack("C*"))
+ assert_equal("ABC", @cls[ 65, 66, 67 ].pack("c3"))
+ assert_equal("\377BC", @cls[ -1, 66, 67 ].pack("c*"))
+
+
+ assert_equal("AB\n\x10", @cls["4142", "0a", "12"].pack("H4H2H1"))
+ assert_equal("AB\n\x02", @cls["1424", "a0", "21"].pack("h4h2h1"))
+
+ assert_equal("abc=02def=\ncat=\n=01=\n",
+ @cls["abc\002def", "cat", "\001"].pack("M9M3M4"))
+
+ assert_equal("aGVsbG8K\n", @cls["hello\n"].pack("m"))
+ assert_equal(",:&5L;&\\*:&5L;&\\*\n", @cls["hello\nhello\n"].pack("u"))
+
+ assert_equal("\xc2\xa9B\xe2\x89\xa0", @cls[0xa9, 0x42, 0x2260].pack("U*"))
+
+
+ format = "c2x5CCxsdils_l_a6";
+ # Need the expression in here to force ary[5] to be numeric. This avoids
+ # test2 failing because ary2 goes str->numeric->str and ary does not.
+ ary = [1, -100, 127, 128, 32767, 987.654321098/100.0,
+ 12345, 123456, -32767, -123456, "abcdef"]
+ x = ary.pack(format)
+ ary2 = x.unpack(format)
+
+ assert_equal(ary.length, ary2.length)
+ assert_equal(ary.join(':'), ary2.join(':'))
+ assert_not_nil(x =~ /def/)
+
+=begin
+ skipping "Not tested:
+ D,d & double-precision float, native format\\
+ E & double-precision float, little-endian byte order\\
+ e & single-precision float, little-endian byte order\\
+ F,f & single-precision float, native format\\
+ G & double-precision float, network (big-endian) byte order\\
+ g & single-precision float, network (big-endian) byte order\\
+ I & unsigned integer\\
+ i & integer\\
+ L & unsigned long\\
+ l & long\\
+
+ N & long, network (big-endian) byte order\\
+ n & short, network (big-endian) byte-order\\
+ P & pointer to a structure (fixed-length string)\\
+ p & pointer to a null-terminated string\\
+ S & unsigned short\\
+ s & short\\
+ V & long, little-endian byte order\\
+ v & short, little-endian byte order\\
+ X & back up a byte\\
+ x & null byte\\
+ Z & ASCII string (null padded, count is width)\\
+"
+=end
+ end
+
+ def test_pop
+ a = @cls[ 'cat', 'dog' ]
+ assert_equal('dog', a.pop)
+ assert_equal(@cls['cat'], a)
+ assert_equal('cat', a.pop)
+ assert_equal(@cls[], a)
+ assert_nil(a.pop)
+ assert_equal(@cls[], a)
+ end
+
+ def test_push
+ a = @cls[1, 2, 3]
+ assert_equal(@cls[1, 2, 3, 4, 5], a.push(4, 5))
+ assert_equal(@cls[1, 2, 3, 4, 5, nil], a.push(nil))
+ # Ruby 1.8 feature:
+ # Array#push accepts any number of arguments.
+ #assert_raise(ArgumentError, "a.push()") { a.push() }
+ a.push
+ assert_equal @cls[1, 2, 3, 4, 5, nil], a
+ a.push 6, 7
+ assert_equal @cls[1, 2, 3, 4, 5, nil, 6, 7], a
+ end
+
+ def test_rassoc
+ a1 = @cls[*%w( cat feline )]
+ a2 = @cls[*%w( dog canine )]
+ a3 = @cls[*%w( mule asinine )]
+ a = @cls[ a1, a2, a3 ]
+
+ assert_equal(a1, a.rassoc('feline'))
+ assert_equal(a3, a.rassoc('asinine'))
+ assert_equal(nil, a.rassoc('dog'))
+ assert_equal(nil, a.rassoc('mule'))
+ assert_equal(nil, a.rassoc(1..2))
+ end
+
+ # also delete_if
+ def test_reject!
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(nil, a.reject! { false })
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.reject! { true })
+ assert_equal(@cls[], a)
+
+ a = @cls[ 1, 2, 3, 4, 5 ]
+ assert_equal(a, a.reject! { |i| i > 3 })
+ assert_equal(@cls[1, 2, 3], a)
+ end
+
+ def test_replace
+ a = @cls[ 1, 2, 3]
+ a_id = a.__id__
+ assert_equal(@cls[4, 5, 6], a.replace(@cls[4, 5, 6]))
+ assert_equal(@cls[4, 5, 6], a)
+ assert_equal(a_id, a.__id__)
+ assert_equal(@cls[], a.replace(@cls[]))
+ end
+
+ def test_reverse
+ a = @cls[*%w( dog cat bee ant )]
+ assert_equal(@cls[*%w(ant bee cat dog)], a.reverse)
+ assert_equal(@cls[*%w(dog cat bee ant)], a)
+ assert_equal(@cls[], @cls[].reverse)
+ end
+
+ def test_reverse!
+ a = @cls[*%w( dog cat bee ant )]
+ assert_equal(@cls[*%w(ant bee cat dog)], a.reverse!)
+ assert_equal(@cls[*%w(ant bee cat dog)], a)
+ # Ruby 1.8 feature change:
+ # Array#reverse always returns self.
+ #assert_nil(@cls[].reverse!)
+ assert_equal @cls[], @cls[].reverse!
+ end
+
+ def test_reverse_each
+ a = @cls[*%w( dog cat bee ant )]
+ i = a.length
+ a.reverse_each { |e|
+ i -= 1
+ assert_equal(a[i], e)
+ }
+ assert_equal(0, i)
+
+ a = @cls[]
+ i = 0
+ a.reverse_each { |e|
+ assert(false, "Never get here")
+ }
+ assert_equal(0, i)
+ end
+
+ def test_rindex
+ a = @cls[ 'cat', 99, /a/, 99, [ 1, 2, 3] ]
+ assert_equal(0, a.rindex('cat'))
+ assert_equal(3, a.rindex(99))
+ assert_equal(4, a.rindex([1,2,3]))
+ assert_nil(a.rindex('ca'))
+ assert_nil(a.rindex([1,2]))
+ end
+
+ def test_shift
+ a = @cls[ 'cat', 'dog' ]
+ assert_equal('cat', a.shift)
+ assert_equal(@cls['dog'], a)
+ assert_equal('dog', a.shift)
+ assert_equal(@cls[], a)
+ assert_nil(a.shift)
+ assert_equal(@cls[], a)
+ end
+
+ def test_size
+ assert_equal(0, @cls[].size)
+ assert_equal(1, @cls[1].size)
+ assert_equal(100, @cls[*(0..99).to_a].size)
+ end
+
+ def test_slice
+ a = @cls[*(1..100).to_a]
+
+ assert_equal(1, a.slice(0))
+ assert_equal(100, a.slice(99))
+ assert_nil(a.slice(100))
+ assert_equal(100, a.slice(-1))
+ assert_equal(99, a.slice(-2))
+ assert_equal(1, a.slice(-100))
+ assert_nil(a.slice(-101))
+
+ assert_equal(@cls[1], a.slice(0,1))
+ assert_equal(@cls[100], a.slice(99,1))
+ assert_equal(@cls[], a.slice(100,1))
+ assert_equal(@cls[100], a.slice(99,100))
+ assert_equal(@cls[100], a.slice(-1,1))
+ assert_equal(@cls[99], a.slice(-2,1))
+
+ assert_equal(@cls[10, 11, 12], a.slice(9, 3))
+ assert_equal(@cls[10, 11, 12], a.slice(-91, 3))
+
+ assert_nil(a.slice(-101, 2))
+
+ assert_equal(@cls[1], a.slice(0..0))
+ assert_equal(@cls[100], a.slice(99..99))
+ assert_equal(@cls[], a.slice(100..100))
+ assert_equal(@cls[100], a.slice(99..200))
+ assert_equal(@cls[100], a.slice(-1..-1))
+ assert_equal(@cls[99], a.slice(-2..-2))
+
+ assert_equal(@cls[10, 11, 12], a.slice(9..11))
+ assert_equal(@cls[10, 11, 12], a.slice(-91..-89))
+
+ assert_nil(a.slice(-101..-1))
+
+ assert_nil(a.slice(10, -3))
+ # Ruby 1.8 feature change:
+ # Array#slice[size..x] always returns [].
+ #assert_nil(a.slice(10..7))
+ assert_equal @cls[], a.slice(10..7)
+ end
+
+ def test_slice!
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(3, a.slice!(2))
+ assert_equal(@cls[1, 2, 4, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(4, a.slice!(-2))
+ assert_equal(@cls[1, 2, 3, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(@cls[3,4], a.slice!(2,2))
+ assert_equal(@cls[1, 2, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(@cls[4,5], a.slice!(-2,2))
+ assert_equal(@cls[1, 2, 3], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(@cls[3,4], a.slice!(2..3))
+ assert_equal(@cls[1, 2, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(nil, a.slice!(20))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(nil, a.slice!(-6))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(nil, a.slice!(-6..4))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+
+ a = @cls[1, 2, 3, 4, 5]
+ assert_equal(nil, a.slice!(-6,2))
+ assert_equal(@cls[1, 2, 3, 4, 5], a)
+ end
+
+ def test_sort
+ a = @cls[ 4, 1, 2, 3 ]
+ assert_equal(@cls[1, 2, 3, 4], a.sort)
+ assert_equal(@cls[4, 1, 2, 3], a)
+
+ assert_equal(@cls[4, 3, 2, 1], a.sort { |x, y| y <=> x} )
+ assert_equal(@cls[4, 1, 2, 3], a)
+
+ a.fill(1)
+ assert_equal(@cls[1, 1, 1, 1], a.sort)
+
+ assert_equal(@cls[], @cls[].sort)
+ end
+
+ def test_sort!
+ a = @cls[ 4, 1, 2, 3 ]
+ assert_equal(@cls[1, 2, 3, 4], a.sort!)
+ assert_equal(@cls[1, 2, 3, 4], a)
+
+ assert_equal(@cls[4, 3, 2, 1], a.sort! { |x, y| y <=> x} )
+ assert_equal(@cls[4, 3, 2, 1], a)
+
+ a.fill(1)
+ assert_equal(@cls[1, 1, 1, 1], a.sort!)
+
+ assert_equal(@cls[1], @cls[1].sort!)
+ assert_equal(@cls[], @cls[].sort!)
+ end
+
+ def test_sort_with_callcc
+ respond_to?(:callcc, true) or require 'continuation'
+ n = 1000
+ cont = nil
+ ary = (1..100).to_a
+ begin
+ ary.sort! {|a,b|
+ callcc {|k| cont = k} unless cont
+ assert_equal(100, ary.size, '[ruby-core:16679]')
+ a <=> b
+ }
+ rescue => e
+ end
+ n -= 1
+ cont.call if 0 < n
+ assert_instance_of(RuntimeError, e, '[ruby-core:16679]')
+ assert_match(/reentered/, e.message, '[ruby-core:16679]')
+ end
+
+ def test_sort_with_replace
+ xary = (1..100).to_a
+ 100.times do
+ ary = (1..100).to_a
+ ary.sort! {|a,b| ary.replace(xary); a <=> b}
+ GC.start
+ assert_equal(xary, ary, '[ruby-dev:34732]')
+ end
+ end
+
+ def test_to_a
+ a = @cls[ 1, 2, 3 ]
+ a_id = a.__id__
+ assert_equal(a, a.to_a)
+ assert_equal(a_id, a.to_a.__id__)
+ end
+
+ def test_to_ary
+ a = [ 1, 2, 3 ]
+ b = @cls[*a]
+
+ a_id = a.__id__
+ assert_equal(a, b.to_ary)
+ if (@cls == Array)
+ assert_equal(a_id, a.to_ary.__id__)
+ end
+ end
+
+ def test_to_s
+ $, = ""
+ a = @cls[]
+ assert_equal("[]", a.to_s)
+
+ $, = ""
+ a = @cls[1, 2]
+ assert_equal("[1, 2]", a.to_s)
+
+ $, = ""
+ a = @cls[1, 2, 3]
+ assert_equal("[1, 2, 3]", a.to_s)
+
+ $, = ":"
+ a = @cls[1, 2, 3]
+ assert_equal("[1, 2, 3]", a.to_s)
+
+ $, = ""
+ end
+
+ def test_uniq
+ a = @cls[ 1, 2, 3, 2, 1, 2, 3, 4, nil ]
+ b = a.dup
+ assert_equal(@cls[1, 2, 3, 4, nil], a.uniq)
+ assert_equal(b, a)
+
+ assert_equal(@cls[1, 2, 3], @cls[1, 2, 3].uniq)
+ end
+
+ def test_uniq!
+ a = @cls[ 1, 2, 3, 2, 1, 2, 3, 4, nil ]
+ assert_equal(@cls[1, 2, 3, 4, nil], a.uniq!)
+ assert_equal(@cls[1, 2, 3, 4, nil], a)
+
+ assert_nil(@cls[1, 2, 3].uniq!)
+ end
+
+ def test_unshift
+ a = @cls[]
+ assert_equal(@cls['cat'], a.unshift('cat'))
+ assert_equal(@cls['dog', 'cat'], a.unshift('dog'))
+ assert_equal(@cls[nil, 'dog', 'cat'], a.unshift(nil))
+ assert_equal(@cls[@cls[1,2], nil, 'dog', 'cat'], a.unshift(@cls[1, 2]))
+ end
+
+ def test_OR # '|'
+ assert_equal(@cls[], @cls[] | @cls[])
+ assert_equal(@cls[1], @cls[1] | @cls[])
+ assert_equal(@cls[1], @cls[] | @cls[1])
+ assert_equal(@cls[1], @cls[1] | @cls[1])
+
+ assert_equal(@cls[1,2], @cls[1] | @cls[2])
+ assert_equal(@cls[1,2], @cls[1, 1] | @cls[2, 2])
+ assert_equal(@cls[1,2], @cls[1, 2] | @cls[1, 2])
+ end
+
+ def test_combination
+ assert_equal(@cls[[]], @cls[1,2,3,4].combination(0).to_a)
+ assert_equal(@cls[[1],[2],[3],[4]], @cls[1,2,3,4].combination(1).to_a)
+ assert_equal(@cls[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]], @cls[1,2,3,4].combination(2).to_a)
+ assert_equal(@cls[[1,2,3],[1,2,4],[1,3,4],[2,3,4]], @cls[1,2,3,4].combination(3).to_a)
+ assert_equal(@cls[[1,2,3,4]], @cls[1,2,3,4].combination(4).to_a)
+ assert_equal(@cls[], @cls[1,2,3,4].combination(5).to_a)
+ end
+
+ def test_product
+ assert_equal(@cls[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]],
+ @cls[1,2,3].product([4,5]))
+ assert_equal(@cls[[1,1],[1,2],[2,1],[2,2]], @cls[1,2].product([1,2]))
+
+ assert_equal(@cls[[1,3,5],[1,3,6],[1,4,5],[1,4,6],
+ [2,3,5],[2,3,6],[2,4,5],[2,4,6]],
+ @cls[1,2].product([3,4],[5,6]))
+ assert_equal(@cls[[1],[2]], @cls[1,2].product)
+ assert_equal(@cls[], @cls[1,2].product([]))
+ end
+
+ def test_permutation
+ a = @cls[1,2,3]
+ assert_equal(@cls[[]], a.permutation(0).to_a)
+ assert_equal(@cls[[1],[2],[3]], a.permutation(1).to_a.sort)
+ assert_equal(@cls[[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]],
+ a.permutation(2).to_a.sort)
+ assert_equal(@cls[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]],
+ a.permutation(3).sort.to_a)
+ assert_equal(@cls[], a.permutation(4).to_a)
+ assert_equal(@cls[], a.permutation(-1).to_a)
+ assert_equal("abcde".each_char.to_a.permutation(5).sort,
+ "edcba".each_char.to_a.permutation(5).sort)
+ assert_equal(@cls[].permutation(0).to_a, @cls[[]])
+
+ end
+
+ def test_take
+ assert_equal([1,2,3], [1,2,3,4,5,0].take(3))
+ assert_raise(ArgumentError, '[ruby-dev:34123]') { [1,2].take(-1) }
+ assert_equal([1,2], [1,2].take(1000000000), '[ruby-dev:34123]')
+ end
+
+ def test_take_while
+ assert_equal([1,2], [1,2,3,4,5,0].take_while {|i| i < 3 })
+ end
+
+ def test_drop
+ assert_equal([4,5,0], [1,2,3,4,5,0].drop(3))
+ assert_raise(ArgumentError, '[ruby-dev:34123]') { [1,2].drop(-1) }
+ assert_equal([], [1,2].drop(1000000000), '[ruby-dev:34123]')
+ end
+
+ def test_drop_while
+ assert_equal([3,4,5,0], [1,2,3,4,5,0].drop_while {|i| i < 3 })
+ end
+
+ def test_modify_check
+ a = []
+ a.freeze
+ assert_raise(RuntimeError) { a.shift }
+ a = [1, 2]
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ a.shift
+ end.value
+ end
+ end
+
+ LONGP = [127, 63, 31, 15, 7].map {|x| 2**x-1 }.find do |x|
+ begin
+ [].first(x)
+ rescue ArgumentError
+ true
+ rescue RangeError
+ false
+ end
+ end
+
+ def test_ary_new
+ assert_raise(ArgumentError) { [].to_enum.first(-1) }
+ assert_raise(ArgumentError) { [].to_enum.first(LONGP) }
+ end
+
+ def test_try_convert
+ assert_equal([1], Array.try_convert([1]))
+ assert_equal(nil, Array.try_convert("1"))
+ end
+
+ def test_initialize
+ assert_nothing_raised { [].instance_eval { initialize } }
+ assert_nothing_raised { Array.new { } }
+ assert_equal([1, 2, 3], Array.new([1, 2, 3]))
+ assert_raise(ArgumentError) { Array.new(-1, 1) }
+ assert_raise(ArgumentError) { Array.new(LONGP, 1) }
+ assert_equal([1, 1, 1], Array.new(3, 1))
+ assert_equal([1, 1, 1], Array.new(3) { 1 })
+ assert_equal([1, 1, 1], Array.new(3, 1) { 1 })
+ end
+
+ def test_aset
+ assert_raise(IndexError) { [0][-2] = 1 }
+ assert_raise(IndexError) { [0][LONGP] = 2 }
+ assert_raise(IndexError) { [0][(LONGP + 1) / 2 - 1] = 2 }
+ a = [0]
+ a[2] = 4
+ assert_equal([0, nil, 4], a)
+ assert_raise(ArgumentError) { [0][0, 0, 0] = 0 }
+ end
+
+ def test_first2
+ assert_equal([0], [0].first(2))
+ assert_raise(ArgumentError) { [0].first(-1) }
+ end
+
+ def test_shift2
+ assert_equal(0, ([0] * 16).shift)
+ # check
+ a = [0, 1, 2]
+ a[3] = 3
+ a.shift(2)
+ assert_equal([2, 3], a)
+ end
+
+ def test_unshift2
+ Struct.new(:a, :b, :c)
+ end
+
+ def test_aref
+ assert_raise(ArgumentError) { [][0, 0, 0] }
+ end
+
+ def test_fetch
+ assert_equal(1, [].fetch(0, 0) { 1 })
+ assert_equal(1, [0, 1].fetch(-1))
+ assert_raise(IndexError) { [0, 1].fetch(2) }
+ assert_raise(IndexError) { [0, 1].fetch(-3) }
+ assert_equal(2, [0, 1].fetch(2, 2))
+ end
+
+ def test_index2
+ a = [0, 1, 2]
+ assert_equal(a, a.index.to_a)
+ assert_equal(1, a.index {|x| x == 1 })
+ end
+
+ def test_rindex2
+ a = [0, 1, 2]
+ assert_equal([2, 1, 0], a.rindex.to_a)
+ assert_equal(1, a.rindex {|x| x == 1 })
+
+ a = [0, 1]
+ e = a.rindex
+ assert_equal(1, e.next)
+ a.clear
+ assert_raise(StopIteration) { e.next }
+
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:==) {|x| a.clear; false }
+ end
+ a = [nil, o]
+ assert_equal(nil, a.rindex(0))
+ end
+
+ def test_ary_to_ary
+ o = Object.new
+ def o.to_ary; [1, 2, 3]; end
+ a, b, c = o
+ assert_equal([1, 2, 3], [a, b, c])
+ end
+
+ def test_splice
+ a = [0]
+ assert_raise(IndexError) { a[-2, 0] = nil }
+ end
+
+ def test_insert
+ a = [0]
+ assert_equal([0], a.insert(1))
+ assert_equal([0, 1], a.insert(1, 1))
+ assert_raise(ArgumentError) { a.insert }
+ assert_equal([0, 1, 2], a.insert(-1, 2))
+ assert_equal([0, 1, 3, 2], a.insert(-2, 3))
+ end
+
+ def test_join2
+ a = []
+ a << a
+ assert_equal("[...]", a.join)
+ end
+
+ def test_to_a2
+ klass = Class.new(Array)
+ a = klass.new.to_a
+ assert_equal([], a)
+ assert_equal(Array, a.class)
+ end
+
+ def test_values_at2
+ a = [0, 1, 2, 3, 4, 5]
+ assert_equal([1, 2, 3], a.values_at(1..3))
+ assert_equal([], a.values_at(7..8))
+ assert_equal([nil], a.values_at(2**31-1))
+ end
+
+ def test_select
+ assert_equal([0, 2], [0, 1, 2, 3].select {|x| x % 2 == 0 })
+ end
+
+ def test_delete2
+ a = [0] * 1024 + [1] + [0] * 1024
+ a.delete(0)
+ assert_equal([1], a)
+ end
+
+ def test_reject
+ assert_equal([1, 3], [0, 1, 2, 3].reject {|x| x % 2 == 0 })
+ end
+
+ def test_zip
+ assert_equal([[1, :a, "a"], [2, :b, "b"], [3, nil, "c"]],
+ [1, 2, 3].zip([:a, :b], ["a", "b", "c", "d"]))
+ a = []
+ [1, 2, 3].zip([:a, :b], ["a", "b", "c", "d"]) {|x| a << x }
+ assert_equal([[1, :a, "a"], [2, :b, "b"], [3, nil, "c"]], a)
+ end
+
+ def test_transpose
+ assert_equal([[1, :a], [2, :b], [3, :c]],
+ [[1, 2, 3], [:a, :b, :c]].transpose)
+ assert_raise(IndexError) { [[1, 2, 3], [:a, :b]].transpose }
+ end
+
+ def test_clear2
+ assert_equal([], ([0] * 1024).clear)
+ end
+
+ def test_fill2
+ assert_raise(ArgumentError) { [].fill(0, 1, LONGP) }
+ end
+
+ def test_times
+ assert_raise(ArgumentError) { [0, 0, 0, 0] * ((LONGP + 1) / 4) }
+ end
+
+ def test_equal
+ o = Object.new
+ def o.to_ary; end
+ def o.==(x); :foo; end
+ assert(:foo, [0, 1, 2] == o)
+ assert([0, 1, 2] != [0, 1, 3])
+ end
+
+ def test_hash2
+ a = []
+ a << a
+ b = []
+ b << b
+ assert_equal(a.hash, b.hash)
+ end
+
+ def test_flatten2
+ a = []
+ a << a
+ assert_raise(ArgumentError) { a.flatten }
+ end
+
+ def test_shuffle
+ 100.times do
+ assert_equal([0, 1, 2], [2, 1, 0].shuffle.sort)
+ end
+ end
+
+ def test_sample
+ 100.times do
+ assert([0, 1, 2].include?([2, 1, 0].sample))
+ samples = [2, 1, 0].sample(2)
+ samples.each{|sample|
+ assert([0, 1, 2].include?(sample))
+ }
+ end
+ end
+
+ def test_cycle
+ a = []
+ [0, 1, 2].cycle do |i|
+ a << i
+ break if a.size == 10
+ end
+ assert_equal([0, 1, 2, 0, 1, 2, 0, 1, 2, 0], a)
+
+ a = [0, 1, 2]
+ assert_nil(a.cycle { a.clear })
+
+ a = []
+ [0, 1, 2].cycle(3) {|i| a << i }
+ assert_equal([0, 1, 2, 0, 1, 2, 0, 1, 2], a)
+ end
+
+ def test_reverse_each2
+ a = [0, 1, 2, 3, 4, 5]
+ r = []
+ a.reverse_each do |x|
+ r << x
+ a.pop
+ a.pop
+ end
+ assert_equal([5, 3, 1], r)
+ end
+
+ def test_combination2
+ assert_raise(RangeError) do
+ (0..100).to_a.combination(50) {}
+ end
+ end
+
+ def test_product2
+ a = (0..100).to_a
+ assert_raise(RangeError) do
+ a.product(a, a, a, a, a, a, a, a, a, a) {}
+ end
+ end
+
+ class Array2 < Array
+ end
+
+ def test_array_subclass
+ assert_equal(Array2, Array2[1,2,3].uniq.class, "[ruby-dev:34581]")
+ end
+
+ def test_inspect
+ a = @cls[1, 2, 3]
+ a.taint
+ a.untrust
+ s = a.inspect
+ assert_equal(true, s.tainted?)
+ assert_equal(true, s.untrusted?)
+ end
+end
diff --git a/trunk/test/ruby/test_assignment.rb b/trunk/test/ruby/test_assignment.rb
new file mode 100644
index 0000000000..b82cee81d1
--- /dev/null
+++ b/trunk/test/ruby/test_assignment.rb
@@ -0,0 +1,687 @@
+require 'test/unit'
+
+class TestAssignment < Test::Unit::TestCase
+ def test_assign
+ a=[]; a[0] ||= "bar";
+ assert_equal("bar", a[0])
+ h={}; h["foo"] ||= "bar";
+ assert_equal("bar", h["foo"])
+
+ aa = 5
+ aa ||= 25
+ assert_equal(5, aa)
+ bb ||= 25
+ assert_equal(25, bb)
+ cc &&=33
+ assert_nil(cc)
+ cc = 5
+ cc &&=44
+ assert_equal(44, cc)
+
+ a = nil; assert_nil(a)
+ a = 1; assert_equal(1, a)
+ a = []; assert_equal([], a)
+ a = [1]; assert_equal([1], a)
+ a = [nil]; assert_equal([nil], a)
+ a = [[]]; assert_equal([[]], a)
+ a = [1,2]; assert_equal([1,2], a)
+ a = [*[]]; assert_equal([], a)
+ a = [*[1]]; assert_equal([1], a)
+ a = [*[1,2]]; assert_equal([1,2], a)
+
+ a = *[]; assert_equal([], a)
+ a = *[1]; assert_equal([1], a)
+ a = *[nil]; assert_equal([nil], a)
+ a = *[[]]; assert_equal([[]], a)
+ a = *[1,2]; assert_equal([1,2], a)
+ a = *[*[]]; assert_equal([], a)
+ a = *[*[1]]; assert_equal([1], a)
+ a = *[*[1,2]]; assert_equal([1,2], a)
+
+ *a = nil; assert_equal([nil], a)
+ *a = 1; assert_equal([1], a)
+ *a = []; assert_equal([], a)
+ *a = [1]; assert_equal([1], a)
+ *a = [nil]; assert_equal([nil], a)
+ *a = [[]]; assert_equal([[]], a)
+ *a = [1,2]; assert_equal([1,2], a)
+ *a = [*[]]; assert_equal([], a)
+ *a = [*[1]]; assert_equal([1], a)
+ *a = [*[1,2]]; assert_equal([1,2], a)
+
+ *a = *[]; assert_equal([], a)
+ *a = *[1]; assert_equal([1], a)
+ *a = *[nil]; assert_equal([nil], a)
+ *a = *[[]]; assert_equal([[]], a)
+ *a = *[1,2]; assert_equal([1,2], a)
+ *a = *[*[]]; assert_equal([], a)
+ *a = *[*[1]]; assert_equal([1], a)
+ *a = *[*[1,2]]; assert_equal([1,2], a)
+
+ a,b,*c = nil; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = 1; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = []; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = [1]; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = [nil]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = [[]]; assert_equal([[],nil,[]], [a,b,c])
+ a,b,*c = [1,2]; assert_equal([1,2,[]], [a,b,c])
+ a,b,*c = [*[]]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = [*[1]]; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = [*[1,2]]; assert_equal([1,2,[]], [a,b,c])
+
+ a,b,*c = *[]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = *[1]; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = *[nil]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = *[[]]; assert_equal([[],nil,[]], [a,b,c])
+ a,b,*c = *[1,2]; assert_equal([1,2,[]], [a,b,c])
+ a,b,*c = *[*[]]; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = *[*[1]]; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = *[*[1,2]]; assert_equal([1,2,[]], [a,b,c])
+ end
+
+ def test_yield
+ def f; yield(nil); end; f {|a| assert_nil(a)}; undef f
+ def f; yield(1); end; f {|a| assert_equal(1, a)}; undef f
+ def f; yield([]); end; f {|a| assert_equal([], a)}; undef f
+ def f; yield([1]); end; f {|a| assert_equal([1], a)}; undef f
+ def f; yield([nil]); end; f {|a| assert_equal([nil], a)}; undef f
+ def f; yield([[]]); end; f {|a| assert_equal([[]], a)}; undef f
+ def f; yield([*[]]); end; f {|a| assert_equal([], a)}; undef f
+ def f; yield([*[1]]); end; f {|a| assert_equal([1], a)}; undef f
+ def f; yield([*[1,2]]); end; f {|a| assert_equal([1,2], a)}; undef f
+
+ def f; yield(*[1]); end; f {|a| assert_equal(1, a)}; undef f
+ def f; yield(*[nil]); end; f {|a| assert_equal(nil, a)}; undef f
+ def f; yield(*[[]]); end; f {|a| assert_equal([], a)}; undef f
+ def f; yield(*[*[1]]); end; f {|a| assert_equal(1, a)}; undef f
+
+ def f; yield; end; f {|*a| assert_equal([], a)}; undef f
+ def f; yield(nil); end; f {|*a| assert_equal([nil], a)}; undef f
+ def f; yield(1); end; f {|*a| assert_equal([1], a)}; undef f
+ def f; yield([]); end; f {|*a| assert_equal([[]], a)}; undef f
+ def f; yield([1]); end; f {|*a| assert_equal([[1]], a)}; undef f
+ def f; yield([nil]); end; f {|*a| assert_equal([[nil]], a)}; undef f
+ def f; yield([[]]); end; f {|*a| assert_equal([[[]]], a)}; undef f
+ def f; yield([1,2]); end; f {|*a| assert_equal([[1,2]], a)}; undef f
+ def f; yield([*[]]); end; f {|*a| assert_equal([[]], a)}; undef f
+ def f; yield([*[1]]); end; f {|*a| assert_equal([[1]], a)}; undef f
+ def f; yield([*[1,2]]); end; f {|*a| assert_equal([[1,2]], a)}; undef f
+
+ def f; yield(*[]); end; f {|*a| assert_equal([], a)}; undef f
+ def f; yield(*[1]); end; f {|*a| assert_equal([1], a)}; undef f
+ def f; yield(*[nil]); end; f {|*a| assert_equal([nil], a)}; undef f
+ def f; yield(*[[]]); end; f {|*a| assert_equal([[]], a)}; undef f
+ def f; yield(*[*[]]); end; f {|*a| assert_equal([], a)}; undef f
+ def f; yield(*[*[1]]); end; f {|*a| assert_equal([1], a)}; undef f
+ def f; yield(*[*[1,2]]); end; f {|*a| assert_equal([1,2], a)}; undef f
+
+ def f; yield; end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(nil); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(1); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield([]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield([1]); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield([nil]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield([[]]); end; f {|a,b,*c| assert_equal([[],nil,[]], [a,b,c])}; undef f
+ def f; yield([*[]]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield([*[1]]); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield([*[1,2]]); end; f {|a,b,*c| assert_equal([1,2,[]], [a,b,c])}; undef f
+
+ def f; yield(*[]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[1]); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[nil]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[[]]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[*[]]); end; f {|a,b,*c| assert_equal([nil,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[*[1]]); end; f {|a,b,*c| assert_equal([1,nil,[]], [a,b,c])}; undef f
+ def f; yield(*[*[1,2]]); end; f {|a,b,*c| assert_equal([1,2,[]], [a,b,c])}; undef f
+ end
+
+ def test_return
+ def r; return; end; a = r(); assert_nil(a); undef r
+ def r; return nil; end; a = r(); assert_nil(a); undef r
+ def r; return 1; end; a = r(); assert_equal(1, a); undef r
+ def r; return []; end; a = r(); assert_equal([], a); undef r
+ def r; return [1]; end; a = r(); assert_equal([1], a); undef r
+ def r; return [nil]; end; a = r(); assert_equal([nil], a); undef r
+ def r; return [[]]; end; a = r(); assert_equal([[]], a); undef r
+ def r; return [*[]]; end; a = r(); assert_equal([], a); undef r
+ def r; return [*[1]]; end; a = r(); assert_equal([1], a); undef r
+ def r; return [*[1,2]]; end; a = r(); assert_equal([1,2], a); undef r
+
+ def r; return *[]; end; a = r(); assert_equal([], a); undef r
+ def r; return *[1]; end; a = r(); assert_equal([1], a); undef r
+ def r; return *[nil]; end; a = r(); assert_equal([nil], a); undef r
+ def r; return *[[]]; end; a = r(); assert_equal([[]], a); undef r
+ def r; return *[*[]]; end; a = r(); assert_equal([], a); undef r
+ def r; return *[*[1]]; end; a = r(); assert_equal([1], a); undef r
+ def r; return *[*[1,2]]; end; a = r(); assert_equal([1,2], a); undef r
+
+ def r; return *[[]]; end; a = *r(); assert_equal([[]], a); undef r
+ def r; return *[*[1,2]]; end; a = *r(); assert_equal([1,2], a); undef r
+
+ def r; return; end; *a = r(); assert_equal([nil], a); undef r
+ def r; return nil; end; *a = r(); assert_equal([nil], a); undef r
+ def r; return 1; end; *a = r(); assert_equal([1], a); undef r
+ def r; return []; end; *a = r(); assert_equal([], a); undef r
+ def r; return [1]; end; *a = r(); assert_equal([1], a); undef r
+ def r; return [nil]; end; *a = r(); assert_equal([nil], a); undef r
+ def r; return [[]]; end; *a = r(); assert_equal([[]], a); undef r
+ def r; return [1,2]; end; *a = r(); assert_equal([1,2], a); undef r
+ def r; return [*[]]; end; *a = r(); assert_equal([], a); undef r
+ def r; return [*[1]]; end; *a = r(); assert_equal([1], a); undef r
+ def r; return [*[1,2]]; end; *a = r(); assert_equal([1,2], a); undef r
+
+ def r; return *[]; end; *a = r(); assert_equal([], a); undef r
+ def r; return *[1]; end; *a = r(); assert_equal([1], a); undef r
+ def r; return *[nil]; end; *a = r(); assert_equal([nil], a); undef r
+ def r; return *[[]]; end; *a = r(); assert_equal([[]], a); undef r
+ def r; return *[1,2]; end; *a = r(); assert_equal([1,2], a); undef r
+ def r; return *[*[]]; end; *a = r(); assert_equal([], a); undef r
+ def r; return *[*[1]]; end; *a = r(); assert_equal([1], a); undef r
+ def r; return *[*[1,2]]; end; *a = r(); assert_equal([1,2], a); undef r
+
+ def r; return *[[]]; end; *a = *r(); assert_equal([[]], a); undef r
+ def r; return *[1,2]; end; *a = *r(); assert_equal([1,2], a); undef r
+ def r; return *[*[1,2]]; end; *a = *r(); assert_equal([1,2], a); undef r
+
+ def r; return; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return nil; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return 1; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return []; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return [1]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return [nil]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return [[]]; end; a,b,*c = r(); assert_equal([[],nil,[]], [a,b,c]); undef r
+ def r; return [1,2]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c]); undef r
+ def r; return [*[]]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return [*[1]]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return [*[1,2]]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c]); undef r
+
+ def r; return *[]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return *[1]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return *[nil]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return *[[]]; end; a,b,*c = r(); assert_equal([[],nil,[]], [a,b,c]); undef r
+ def r; return *[1,2]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c]); undef r
+ def r; return *[*[]]; end; a,b,*c = r(); assert_equal([nil,nil,[]], [a,b,c]); undef r
+ def r; return *[*[1]]; end; a,b,*c = r(); assert_equal([1,nil,[]], [a,b,c]); undef r
+ def r; return *[*[1,2]]; end; a,b,*c = r(); assert_equal([1,2,[]], [a,b,c]); undef r
+
+ def r; return 1, *[]; end; a,b = r(); assert_equal([1,nil], [a,b]); undef r
+ def r; return 1,2,*[1]; end; a,b = r(); assert_equal([1,2], [a,b]); undef r
+ def r; return 1,2,3,*[1,2]; end; a,b = r(); assert_equal([1,2], [a,b]); undef r
+ end
+
+ def test_lambda
+ f = lambda {|r,| assert_equal([], r)}
+ f.call([], *[])
+
+ f = lambda {|r,*l| assert_equal([], r); assert_equal([1], l)}
+ f.call([], *[1])
+
+ f = lambda{|x| x}
+ assert_equal(42, f.call(42))
+ assert_equal([42], f.call([42]))
+ assert_equal([[42]], f.call([[42]]))
+ assert_equal([42,55], f.call([42,55]))
+
+ f = lambda{|x,| x}
+ assert_equal(42, f.call(42))
+ assert_equal([42], f.call([42]))
+ assert_equal([[42]], f.call([[42]]))
+ assert_equal([42,55], f.call([42,55]))
+
+ f = lambda{|*x| x}
+ assert_equal([42], f.call(42))
+ assert_equal([[42]], f.call([42]))
+ assert_equal([[[42]]], f.call([[42]]))
+ assert_equal([[42,55]], f.call([42,55]))
+ assert_equal([42,55], f.call(42,55))
+ end
+
+ def test_multi
+ a,=*[1]
+ assert_equal(1, a)
+ a,=*[[1]]
+ assert_equal([1], a)
+ a,=*[[[1]]]
+ assert_equal([[1]], a)
+
+ x, (y, z) = 1, 2, 3
+ assert_equal([1,2,nil], [x,y,z])
+ x, (y, z) = 1, [2,3]
+ assert_equal([1,2,3], [x,y,z])
+ x, (y, z) = 1, [2]
+ assert_equal([1,2,nil], [x,y,z])
+ end
+
+ def test_break
+ a = loop do break; end; assert_nil(a)
+ a = loop do break nil; end; assert_nil(a)
+ a = loop do break 1; end; assert_equal(1, a)
+ a = loop do break []; end; assert_equal([], a)
+ a = loop do break [1]; end; assert_equal([1], a)
+ a = loop do break [nil]; end; assert_equal([nil], a)
+ a = loop do break [[]]; end; assert_equal([[]], a)
+ a = loop do break [*[]]; end; assert_equal([], a)
+ a = loop do break [*[1]]; end; assert_equal([1], a)
+ a = loop do break [*[1,2]]; end; assert_equal([1,2], a)
+
+ a = loop do break *[]; end; assert_equal([], a)
+ a = loop do break *[1]; end; assert_equal([1], a)
+ a = loop do break *[nil]; end; assert_equal([nil], a)
+ a = loop do break *[[]]; end; assert_equal([[]], a)
+ a = loop do break *[*[]]; end; assert_equal([], a)
+ a = loop do break *[*[1]]; end; assert_equal([1], a)
+ a = loop do break *[*[1,2]]; end; assert_equal([1,2], a)
+
+ *a = loop do break; end; assert_equal([nil], a)
+ *a = loop do break nil; end; assert_equal([nil], a)
+ *a = loop do break 1; end; assert_equal([1], a)
+ *a = loop do break []; end; assert_equal([], a)
+ *a = loop do break [1]; end; assert_equal([1], a)
+ *a = loop do break [nil]; end; assert_equal([nil], a)
+ *a = loop do break [[]]; end; assert_equal([[]], a)
+ *a = loop do break [1,2]; end; assert_equal([1,2], a)
+ *a = loop do break [*[]]; end; assert_equal([], a)
+ *a = loop do break [*[1]]; end; assert_equal([1], a)
+ *a = loop do break [*[1,2]]; end; assert_equal([1,2], a)
+
+ *a = loop do break *[]; end; assert_equal([], a)
+ *a = loop do break *[1]; end; assert_equal([1], a)
+ *a = loop do break *[nil]; end; assert_equal([nil], a)
+ *a = loop do break *[[]]; end; assert_equal([[]], a)
+ *a = loop do break *[1,2]; end; assert_equal([1,2], a)
+ *a = loop do break *[*[]]; end; assert_equal([], a)
+ *a = loop do break *[*[1]]; end; assert_equal([1], a)
+ *a = loop do break *[*[1,2]]; end; assert_equal([1,2], a)
+
+ *a = *loop do break *[[]]; end; assert_equal([[]], a)
+ *a = *loop do break *[1,2]; end; assert_equal([1,2], a)
+ *a = *loop do break *[*[1,2]]; end; assert_equal([1,2], a)
+
+ a,b,*c = loop do break; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break nil; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break 1; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break []; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break [1]; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break [nil]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break [[]]; end; assert_equal([[],nil,[]], [a,b,c])
+ a,b,*c = loop do break [1,2]; end; assert_equal([1,2,[]], [a,b,c])
+ a,b,*c = loop do break [*[]]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break [*[1]]; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break [*[1,2]]; end; assert_equal([1,2,[]], [a,b,c])
+
+ a,b,*c = loop do break *[]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[1]; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[nil]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[[]]; end; assert_equal([[],nil,[]], [a,b,c])
+ a,b,*c = loop do break *[1,2]; end; assert_equal([1,2,[]], [a,b,c])
+ a,b,*c = loop do break *[*[]]; end; assert_equal([nil,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[*[1]]; end; assert_equal([1,nil,[]], [a,b,c])
+ a,b,*c = loop do break *[*[1,2]]; end; assert_equal([1,2,[]], [a,b,c])
+ end
+
+ def test_next
+ def r(val); a = yield(); assert_equal(val, a); end
+ r(nil){next}
+ r(nil){next nil}
+ r(1){next 1}
+ r([]){next []}
+ r([1]){next [1]}
+ r([nil]){next [nil]}
+ r([[]]){next [[]]}
+ r([]){next [*[]]}
+ r([1]){next [*[1]]}
+ r([1,2]){next [*[1,2]]}
+
+ r([]){next *[]}
+ r([1]){next *[1]}
+ r([nil]){next *[nil]}
+ r([[]]){next *[[]]}
+ r([]){next *[*[]]}
+ r([1]){next *[*[1]]}
+ r([1,2]){next *[*[1,2]]}
+ undef r
+
+ def r(val); *a = yield(); assert_equal(val, a); end
+ r([nil]){next}
+ r([nil]){next nil}
+ r([1]){next 1}
+ r([]){next []}
+ r([1]){next [1]}
+ r([nil]){next [nil]}
+ r([[]]){next [[]]}
+ r([1,2]){next [1,2]}
+ r([]){next [*[]]}
+ r([1]){next [*[1]]}
+ r([1,2]){next [*[1,2]]}
+ undef r
+
+ def r(val); *a = *yield(); assert_equal(val, a); end
+ r([[]]){next *[[]]}
+ r([1,2]){next *[1,2]}
+ r([1,2]){next *[*[1,2]]}
+ undef r
+
+ def r(val); a,b,*c = yield(); assert_equal(val, [a,b,c]); end
+ r([nil,nil,[]]){next}
+ r([nil,nil,[]]){next nil}
+ r([1,nil,[]]){next 1}
+ r([nil,nil,[]]){next []}
+ r([1,nil,[]]){next [1]}
+ r([nil,nil,[]]){next [nil]}
+ r([[],nil,[]]){next [[]]}
+ r([1,2,[]]){next [1,2]}
+ r([nil,nil,[]]){next [*[]]}
+ r([1,nil,[]]){next [*[1]]}
+ r([1,2,[]]){next [*[1,2]]}
+ undef r
+
+ def r(val); a,b,*c = *yield(); assert_equal(val, [a,b,c]); end
+ r([[],nil,[]]){next *[[]]}
+ r([1,2,[]]){next *[1,2]}
+ r([1,2,[]]){next *[*[1,2]]}
+ undef r
+ end
+
+ def test_massign
+ a = nil
+ assert(defined?(a))
+ assert_nil(a)
+
+ # multiple asignment
+ a, b = 1, 2
+ assert_equal 1, a
+ assert_equal 2, b
+
+ a, b, c = 1, 2, 3
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+
+ a = 1
+ b = 2
+ a, b = b, a
+ assert_equal 2, a
+ assert_equal 1, b
+
+ a, = 1, 2
+ assert_equal 1, a
+
+ a, = 1, 2, 3
+ assert_equal 1, a
+
+ a, * = 1, 2, 3
+ assert_equal 1, a
+
+ a, *b = 1, 2, 3
+ assert_equal 1, a
+ assert_equal [2, 3], b
+
+ # not supported yet
+ #a, *b, c = 1, 2, 3, 4
+ #assert_equal 1, a
+ #assert_equal [2,3], b
+ #assert_equal 4, c
+
+ a = 1, 2
+ assert_equal [1, 2], a
+
+ a = [1, 2], [3, 4]
+ assert_equal [[1,2], [3,4]], a
+
+ a, (b, c), d = 1, [2, 3], 4
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+ assert_equal 4, d
+
+ *a = 1, 2, 3
+ assert_equal([1, 2, 3], a)
+
+ *a = 4
+ assert_equal([4], a)
+
+ *a = nil
+ assert_equal([nil], a)
+
+ a, b = 1
+ assert_equal 1, a
+ assert_nil b
+
+ a, b = [1, 2]
+ assert_equal 1, a
+ assert_equal 2, b
+ end
+
+ def test_nested_massign
+ (a, b), c = [[1, 2], 3]; assert_equal [1,2,3], [a,b,c]
+ a, (b, c) = [[1, 2], 3]; assert_equal [[1,2], 3, nil], [a,b,c]
+ a, (b, c) = [1, [2, 3]]; assert_equal [1,2,3], [a,b,c]
+ (a, b), *c = [[1, 2], 3]; assert_equal [1,2,[3]], [a,b,c]
+ (a,b),c,(d,e) = [[1,2],3,[4,5]]; assert_equal [1,2,3,4,5],[a,b,c,d,e]
+ (a,*b),c,(d,e,*) = [[1,2],3,[4,5]]; assert_equal [1,[2],3,4,5],[a,b,c,d,e]
+ (a,b),c,(d,*e) = [[1,2,3],4,[5,6,7,8]]; assert_equal [1,2,4,5,[6,7,8]],[a,b,c,d,e]
+ (a,(b1,b2)),c,(d,e) = [[1,2],3,[4,5]]; assert_equal [1,2,nil,3,4,5],[a,b1,b2,c,d,e]
+ (a,(b1,b2)),c,(d,e) = [[1,[21,22]],3,[4,5]]; assert_equal [1,21,22,3,4,5],[a,b1,b2,c,d,e]
+ end
+
+ class MyObj
+ def to_ary
+ [[1,2],[3,4]]
+ end
+ end
+
+ def test_to_ary_splat
+ a, b = MyObj.new
+ assert_equal [[1,2],[3,4]], [a,b]
+ end
+
+ A = 1
+ B = 2
+ X, Y = A, B
+ class Base
+ A = 3
+ B = 4
+ end
+
+ def test_const_massign
+ assert_equal [1,2], [X,Y]
+ a, b = Base::A, Base::B
+ assert_equal [3,4], [a,b]
+ end
+end
+
+require_relative 'sentence'
+class TestAssignmentGen < Test::Unit::TestCase
+ Syntax = {
+ :exp => [["0"],
+ ["nil"],
+ ["false"],
+ ["[]"],
+ ["[",:exps,"]"]],
+ :exps => [[:exp],
+ [:exp,",",:exps]],
+ :arg => [[:exp]],
+ :mrhs => [[:args,",",:arg],
+ [:args,",","*",:arg],
+ ["*",:arg]],
+ :args => [[:arg],
+ ["*",:arg],
+ [:args,",",:arg],
+ [:args,",","*",:arg]],
+ :mlhs => [[:mlhs_basic],
+ ["(",:mlhs_inner,")"]],
+ :mlhs_inner => [[:mlhs_basic],
+ ["(",:mlhs_inner,")"]],
+ :mlhs_basic => [[:mlhs_head],
+ [:mlhs_head,:mlhs_item],
+ [:mlhs_head,"*",:mlhs_node],
+ [:mlhs_head,"*",:mlhs_node,",",:mlhs_post],
+ [:mlhs_head,"*"],
+ [:mlhs_head,"*",",", :mlhs_post],
+ [ "*",:mlhs_node],
+ [ "*",:mlhs_node,",",:mlhs_post],
+ [ "*"],
+ [ "*",",", :mlhs_post]],
+ :mlhs_head => [[:mlhs_item,","],
+ [:mlhs_head,:mlhs_item,","]],
+ :mlhs_post => [[:mlhs_item],
+ [:mlhs_post,",",:mlhs_item]],
+ :mlhs_item => [[:mlhs_node],
+ ["(",:mlhs_inner,")"]],
+ :mlhs_node => [["var"]],
+ :xassign => [["var"," = ",:exp],
+ ["var"," = ",:mrhs],
+ [:mlhs," = ",:exp],
+ [:mlhs," = ",:mrhs]],
+ }
+
+ def rename_var(obj)
+ vars = []
+ r = obj.subst('var') {
+ var = "v#{vars.length}"
+ vars << var
+ var
+ }
+ return r, vars
+ end
+
+ def expand_except_paren(obj)
+ return obj if obj.respond_to? :to_str
+ obj.expand {|s|
+ !(s[0] == '(' && s[-1] == ')') &&
+ !(s[0] == '[' && s[-1] == ']')
+ }
+ end
+
+ def extract_single_element(ary)
+ raise "not a single element array: #{ary.inspect}" if ary.length != 1
+ ary[0]
+ end
+
+ def emu_assign_ary(lhs, rv, h)
+ rv = rv.respond_to?(:to_ary) ? rv : [rv]
+ rv = rv.dup
+ a = [[]]
+ lhs.each {|e|
+ if e == ','
+ a << []
+ else
+ a.last << e
+ end
+ }
+ a.pop if a.last == []
+ pre = []
+ star = post = nil
+ a.each {|e|
+ if post
+ post << e
+ elsif e[0] == '*'
+ star = e
+ post = []
+ else
+ pre << e
+ end
+ }
+ pre.map! {|e| extract_single_element(e) }
+ if star
+ if star == ['*']
+ star = nil
+ else
+ star = extract_single_element(star[1..-1])
+ end
+ end
+ post.map! {|e| extract_single_element(e) } if post
+
+ until pre.empty?
+ emu_assign_single(pre.shift, rv.shift, h)
+ end
+
+ if post
+ if rv.length < post.length
+ until post.empty?
+ emu_assign_single(post.shift, rv.shift, h)
+ end
+ else
+ until post.empty?
+ emu_assign_single(post.pop, rv.pop, h)
+ end
+ end
+ end
+
+ if star
+ emu_assign_single(star, rv, h)
+ end
+ end
+
+ def emu_assign_single(lhs, rv, h={})
+ if lhs.respond_to? :to_str
+ if /\A[a-z0-9]+\z/ =~ lhs
+ h[lhs] = rv
+ else
+ raise "unexpected lhs string: #{lhs.inspect}"
+ end
+ elsif Sentence === lhs
+ if lhs[0] == '(' && lhs[-1] == ')'
+ emu_assign_ary(lhs[1...-1], rv, h)
+ elsif lhs.length == 1 && String === lhs[0] && /\A[a-z0-9]+\z/ =~ lhs[0]
+ h[lhs[0]] = rv
+ else
+ raise "unexpected lhs sentence: #{lhs.inspect}"
+ end
+ else
+ raise "unexpected lhs: #{lhs.inspect}"
+ end
+ h
+ end
+
+ def emu_assign(assign)
+ lhs = expand_except_paren(assign[0])
+ rhs = expand_except_paren(assign[2])
+ lopen = Sentence === lhs && lhs[-1] != ')' && lhs.any? {|e| e == '*' || e == ',' }
+ ropen = Sentence === rhs && rhs[-1] != ']' && rhs.any? {|e| e == '*' || e == ',' }
+ lhs = Sentence.new(['(']+lhs.to_a+[')']) if lopen
+ begin
+ rv = eval((ropen ? ["[",assign[2],"]"] : assign[2]).join(''))
+ rescue Exception
+ rv = $!.message
+ end
+ emu_assign_single(lhs, rv)
+ end
+
+ def do_assign(assign, vars)
+ assign = assign.to_s
+ code1 = "#{assign}; [#{vars.join(",")}]"
+ assign.gsub!(/\bv\d+\b/, "o.a")
+ code2 = "o=[];class << o; self end.send(:define_method,:a=){|v|self << v};#{assign};o"
+ begin
+ vals1 = eval(code1)
+ rescue Exception
+ return {:ex=>$!.message}
+ end
+ begin
+ vals2 = eval(code2)
+ rescue Exception
+ return {:ex=>$!.message}
+ end
+ assert_equal(vals1, vals2, code1)
+ vals = vals1
+ h = {}
+ [vars, vals].transpose.each {|k,v| h[k] = v }
+ h
+ end
+
+ def check(assign)
+ assign, vars = rename_var(assign)
+ sent = assign.to_s
+ bruby = do_assign(assign, vars).to_a.sort
+ bemu = emu_assign(assign).to_a.sort
+ assert_equal(bemu, bruby, sent)
+ end
+
+ def test_assignment
+ syntax = Sentence.expand_syntax(Syntax)
+ Sentence.each(syntax, :xassign, 4) {|assign|
+ check(assign)
+ }
+ end
+end
diff --git a/trunk/test/ruby/test_basicinstructions.rb b/trunk/test/ruby/test_basicinstructions.rb
new file mode 100644
index 0000000000..6ac93e037a
--- /dev/null
+++ b/trunk/test/ruby/test_basicinstructions.rb
@@ -0,0 +1,628 @@
+require 'test/unit'
+
+ConstTest = 3
+class Class
+ alias _remove_const remove_const
+ public :_remove_const
+end
+
+class TestBasicInstructions < Test::Unit::TestCase
+
+ def test_immediates
+ assert_equal((1==1), true)
+ assert_equal((1==2), false)
+ assert_equal [][0], nil
+ assert_equal "sym".intern, :sym
+ assert_equal "sym".intern, :"sym"
+ assert_equal 1234 + 0, 1234
+ assert_equal 1234, 1_2_3_4
+ assert_equal 41, 0b0101001
+ assert_equal 420, 0644
+ assert_equal 18, 0x12
+ assert_equal 123456789012345678901234567890 + 0,
+ 123456789012345678901234567890
+ assert_equal 1.234 + 0.0, 1.234
+ end
+
+ def test_self
+ assert_equal self, self
+ assert_equal false, (self == false) # Qfalse==0 in C
+ assert_equal false, (self == nil)
+ assert_equal false, (self == 0)
+ end
+
+ def test_string
+ expected = "str" + "ing"
+ assert_equal expected, 'string'
+ assert_equal expected, "string"
+ assert_equal expected, %q(string)
+ assert_equal expected, %Q(string)
+ assert_equal expected, %(string)
+ end
+
+ def test_dstring
+ assert_equal "2", "#{1+1}"
+ s = "OK"
+ assert_equal "OK", "#{s}"
+ assert_equal "OKx", "#{s}x"
+ assert_equal "xOK", "x#{s}"
+ assert_equal "xOKx", "x#{s}x"
+ end
+
+ def test_dsym
+ assert_equal :a3c, :"a#{1+2}c"
+ s = "sym"
+ assert_equal :sym, :"#{s}"
+ assert_equal :sym, :"#{"#{"#{s}"}"}"
+ end
+
+ def test_xstr
+ assert_equal 'hoge', `echo hoge`.chomp
+ assert_equal '3', `echo #{1 + 2}`.chomp
+ hoge = 'huga'
+ assert_equal 'huga', `echo #{hoge}`.chomp
+ end
+
+ def test_regexp
+ assert_equal /test/, /test/
+ assert_equal 'test', /test/.source
+ assert_equal 'TEST', /TEST/.source
+ assert_equal true, !!(/test/ =~ 'test')
+ assert_equal false, !!(/test/ =~ 'does not match')
+
+ re = /test/
+ assert_equal re, re
+ assert_equal 'test', re.source
+ assert_equal true, !!(re =~ 'test')
+ assert_equal false, !!(re =~ 'does not match')
+
+ assert_equal /x#{1+1}x/, /x#{1+1}x/
+ s = "OK"
+ assert_equal /x#{s}x/, /x#{s}x/
+ assert_equal true, !!(/x#{s}x/ =~ "xOKx")
+ assert_equal false, !!(/x#{s}x/ =~ "does not match")
+
+ s = "OK"
+ prev = nil
+ 3.times do
+ assert_equal prev.object_id, (prev ||= /#{s}/o).object_id if prev
+ end
+ end
+
+ def test_array
+ assert_equal [], []
+ assert_equal 0, [].size
+ assert_equal [1, 2, 3], [1, 2, 3]
+ assert_equal [3, 7, 11], [1+2, 3+4, 5+6]
+ assert_equal [[1], [2], [3]], [[1], [2], [3]]
+
+ a = [1, 2, 3]
+ assert_equal 1, a[0]
+ assert_equal 2, a[1]
+ assert_equal 3, a[2]
+ assert_nil a[3]
+
+ a = %w( a b c )
+ assert_equal 'a', a[0]
+ assert_equal 'b', a[1]
+ assert_equal 'c', a[2]
+ assert_nil a[3]
+ end
+
+ def test_hash
+ assert_equal({}, {})
+ assert_equal({1=>2}, {1=>2})
+ assert_equal({1=>2, 3=>4}, {1=>2, 3=>4})
+ assert_equal({1=>2, 3=>4}, {3=>4, 1=>2})
+ # assert_equal({1=>2, 3=>4}, {1,2, 3,4}) # 1.9 doesn't support
+ assert_equal({"key"=>"val"}, {"key"=>"val"})
+ end
+
+ def test_range
+ assert_equal((1..3), (1..3))
+ assert_equal((1...3), (1...3))
+ assert_not_equal((1...3), (1..3))
+ assert_not_equal((1..3), (1...3))
+ assert_equal((1..3), (1..2+1))
+ assert_equal((1...3), (1...2+1))
+ assert_equal(('a'..'z'), ('a'..'z'))
+ end
+
+ def test_not
+ assert_equal true, !nil
+ assert_equal true, !false
+ assert_equal false, !true
+ assert_equal false, !3
+ assert_equal false, !(1+1)
+
+ assert_equal false, !!nil
+ assert_equal false, !!false
+ assert_equal true, !!true
+ assert_equal true, !!3
+ assert_equal true, !!(1+1)
+
+ assert_equal true, (not nil)
+ assert_equal true, (not false)
+ assert_equal false, (not true)
+ assert_equal false, (not 3)
+ assert_equal false, (not (1 + 1))
+
+ assert_equal false, (not not nil)
+ assert_equal false, (not not false)
+ assert_equal true, (not not true)
+ assert_equal true, (not not 3)
+ assert_equal true, (not not (1+1))
+ end
+
+ def test_local_variable
+ a = 7
+ assert_equal 7, a
+ assert_equal a, a
+ b = 17
+ assert_equal 7, a
+ assert_equal 17, b
+ assert_equal a, a
+ assert_equal b, b
+ assert_not_equal a, b
+ assert_not_equal b, a
+ a = b
+ assert_equal 17, a
+ assert_equal 17, b
+ assert_equal a, a
+ assert_equal b, b
+ assert_equal a, b
+ assert_equal b, a
+ c = 28
+ assert_equal 17, a
+ assert_equal 17, b
+ assert_equal 28, c
+ assert_equal a, a
+ assert_equal b, b
+ assert_equal a, b
+ assert_equal c, c
+ assert_not_equal a, c
+ assert_not_equal b, c
+ a = b = c
+ assert_equal 28, a
+ assert_equal 28, b
+ assert_equal 28, c
+ assert_equal a, a
+ assert_equal b, b
+ assert_equal a, b
+ assert_equal b, a
+ assert_equal a, c
+ assert_equal c, a
+ assert_equal b, c
+ assert_equal c, b
+
+ a = 1
+ b = 2
+ c = 3
+ set_lvar_in_another_method
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+ end
+
+ def set_lvar_in_another_method
+ assert_raise(NameError) { a }
+ assert_raise(NameError) { b }
+ assert_raise(NameError) { c }
+ a = "NOT OK"
+ b = "NOT OK"
+ c = "NOT OK"
+ end
+
+ class Const
+ $Const = self
+ C = 'Const::C'
+ def self.c() C end
+ def c() C end
+
+ class A
+ C = 'Const::A::C'
+ def self.c() C end
+ def c() C end
+ CC = 'Const::A::CC'
+ def self.cc() CC end
+ def cc() CC end
+
+ class B
+ C = 'Const::A::B::C'
+ def self.c() C end
+ def c() C end
+ def self.cc() CC end
+ def cc() CC end
+ end
+ end
+
+ class AA < A
+ def self.cc() CC end
+ def cc() CC end
+ end
+
+ class AAA < AA
+ def self.cc() CC end
+ def cc() CC end
+ end
+ end
+ C = 0
+
+ def test_const_path
+ do_test_const_path
+ do_test_const_path
+ do_test_const_path
+ end
+
+ def do_test_const_path
+ assert_equal 0, C
+ assert_equal 0, C
+ assert_equal 3, ::ConstTest
+ assert_equal 3, ::ConstTest
+ assert_equal $Const, Const
+
+ assert_equal 'Const::C', Const::C
+ assert_equal 'Const::C', Const::C
+ assert_equal 'Const::A::C', Const::A::C
+ assert_equal 'Const::A::C', Const::A::C
+ assert_equal 'Const::A::B::C', Const::A::B::C
+ assert_equal 'Const::A::B::C', Const::A::B::C
+
+ Const::A::B._remove_const :C
+ assert_equal 'Const::C', Const::C
+ assert_equal 'Const::A::C', Const::A::C
+ assert_raise(NameError) { Const::A::B::C }
+
+ Const::A._remove_const :C
+ assert_equal 'Const::C', Const::C
+ assert_raise(NameError) { Const::A::C }
+ assert_raise(NameError) { Const::A::B::C }
+
+ Const._remove_const :C
+ assert_raise(NameError) { Const::C }
+ assert_raise(NameError) { Const::A::C }
+ assert_raise(NameError) { Const::A::B::C }
+
+ Const::A.const_set :C, 'Const::A::C'
+ assert_raise(NameError) { Const::C }
+ assert_equal 'Const::A::C', Const::A::C
+ assert_raise(NameError) { Const::A::B::C }
+
+ Const::A::B.const_set :C, 'Const::A::B::C'
+ assert_raise(NameError) { Const::C }
+ assert_equal 'Const::A::C', Const::A::C
+ assert_equal 'Const::A::B::C', Const::A::B::C
+
+ Const.const_set :C, 'Const::C'
+ assert_equal 'Const::C', Const::C
+ assert_equal 'Const::A::C', Const::A::C
+ assert_equal 'Const::A::B::C', Const::A::B::C
+ end
+
+ def test_const_cref
+ do_test_const_cref
+ do_test_const_cref
+ do_test_const_cref
+ end
+
+ def do_test_const_cref
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::A::C', Const::A.new.c
+ assert_equal 'Const::A::B::C', Const::A::B.new.c
+
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::A::C', Const::A.c
+ assert_equal 'Const::A::B::C', Const::A::B.c
+
+ Const::A::B._remove_const :C
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::A::C', Const::A.c
+ assert_equal 'Const::A::C', Const::A::B.c
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::A::C', Const::A.new.c
+ assert_equal 'Const::A::C', Const::A::B.new.c
+
+ Const::A._remove_const :C
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::C', Const::A.c
+ assert_equal 'Const::C', Const::A::B.c
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::C', Const::A.new.c
+ assert_equal 'Const::C', Const::A::B.new.c
+
+ Const::A::B.const_set :C, 'Const::A::B::C'
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::C', Const::A.c
+ assert_equal 'Const::A::B::C', Const::A::B.c
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::C', Const::A.new.c
+ assert_equal 'Const::A::B::C', Const::A::B.new.c
+
+ Const::A.const_set :C, 'Const::A::C'
+ assert_equal 'Const::C', Const.c
+ assert_equal 'Const::A::C', Const::A.c
+ assert_equal 'Const::A::B::C', Const::A::B.c
+ assert_equal 'Const::C', Const.new.c
+ assert_equal 'Const::A::C', Const::A.new.c
+ assert_equal 'Const::A::B::C', Const::A::B.new.c
+ ensure
+ # reset
+ Const.const_set :C, 'Const::C' unless Const.const_defined?(:C)
+ Const::A.const_set :C, 'Const::A::C' unless Const::A.const_defined?(:C)
+ Const::A::B.const_set :C, 'Const::A::B::C' unless Const::A::B.const_defined?(:C)
+ end
+
+ def test_const_inherit
+ do_test_const_inherit
+ do_test_const_inherit
+ do_test_const_inherit
+ end
+
+ def do_test_const_inherit
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::A::CC', Const::AA.cc
+ assert_equal 'Const::A::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::A::CC', Const::AA.new.cc
+ assert_equal 'Const::A::CC', Const::AAA.new.cc
+
+ Const::AA.const_set :CC, 'Const::AA::CC'
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::AA::CC', Const::AA.cc
+ assert_equal 'Const::AA::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::AA::CC', Const::AA.new.cc
+ assert_equal 'Const::AA::CC', Const::AAA.new.cc
+
+ Const::AAA.const_set :CC, 'Const::AAA::CC'
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::AA::CC', Const::AA.cc
+ assert_equal 'Const::AAA::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::AA::CC', Const::AA.new.cc
+ assert_equal 'Const::AAA::CC', Const::AAA.new.cc
+
+ Const::AA._remove_const :CC
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::A::CC', Const::AA.cc
+ assert_equal 'Const::AAA::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::A::CC', Const::AA.new.cc
+ assert_equal 'Const::AAA::CC', Const::AAA.new.cc
+
+ Const::AAA._remove_const :CC
+ assert_equal 'Const::A::CC', Const::A.cc
+ assert_equal 'Const::A::CC', Const::AA.cc
+ assert_equal 'Const::A::CC', Const::AAA.cc
+ assert_equal 'Const::A::CC', Const::A.new.cc
+ assert_equal 'Const::A::CC', Const::AA.new.cc
+ assert_equal 'Const::A::CC', Const::AAA.new.cc
+ end
+
+ def test_global_variable
+ $gvar1 = 1
+ assert_equal 1, $gvar1
+ $gvar1 = 2
+ assert_equal 2, $gvar1
+ $gvar2 = 77
+ assert_equal 2, $gvar1
+ assert_equal 77, $gvar2
+ $gvar2 = $gvar1
+ assert_equal 2, $gvar1
+ assert_equal 2, $gvar2
+ $gvar1 = 1
+ assert_equal 1, $gvar1
+ assert_equal 2, $gvar2
+ set_gvar_in_another_method
+ assert_equal "OK1", $gvar1
+ assert_equal "OK2", $gvar2
+ end
+
+ def set_gvar_in_another_method
+ assert_equal 1, $gvar1
+ assert_equal 2, $gvar2
+ $gvar1 = "OK1"
+ $gvar2 = "OK2"
+ end
+
+ class CVarA
+ @@cv = 'CVarA@@cv'
+ def self.cv() @@cv end
+ def self.cv=(v) @@cv = v end
+ class << self
+ def cv2() @@cv end
+ end
+ def cv() @@cv end
+ def cv=(v) @@cv = v end
+ end
+
+ class CVarB < CVarA
+ def self.cvB() @@cv end
+ def self.cvB=(v) @@cv = v end
+ class << self
+ def cvB2() @@cv end
+ end
+ def cvB() @@cv end
+ def cvB=(v) @@cv = v end
+ end
+
+ def test_class_variable
+ assert_equal 'CVarA@@cv', CVarA.cv
+ assert_equal 'CVarA@@cv', CVarA.cv2
+ assert_equal 'CVarA@@cv', CVarA.new.cv
+ CVarA.cv = 'singleton'
+ assert_equal 'singleton', CVarA.cv
+ assert_equal 'singleton', CVarA.cv2
+ assert_equal 'singleton', CVarA.new.cv
+ CVarA.new.cv = 'instance'
+ assert_equal 'instance', CVarA.cv
+ assert_equal 'instance', CVarA.cv2
+ assert_equal 'instance', CVarA.new.cv
+
+ CVarA.cv = 'CVarA@@cv'
+ CVarB.cv = 'B/singleton'
+ assert_equal 'B/singleton', CVarB.cv
+ assert_equal 'B/singleton', CVarB.cv2
+ assert_equal 'B/singleton', CVarB.new.cv
+ assert_equal 'B/singleton', CVarA.cv
+ assert_equal 'B/singleton', CVarA.cv2
+ assert_equal 'B/singleton', CVarA.new.cv
+ CVarB.new.cv = 'B/instance'
+ assert_equal 'B/instance', CVarB.cv
+ assert_equal 'B/instance', CVarB.cv2
+ assert_equal 'B/instance', CVarB.new.cv
+ assert_equal 'B/instance', CVarA.cv
+ assert_equal 'B/instance', CVarA.cv2
+ assert_equal 'B/instance', CVarA.new.cv
+
+ CVarA.cv = 'CVarA@@cv'
+ assert_equal('CVarA@@cv', CVarB.cvB)
+ assert_equal('CVarA@@cv', CVarB.cvB2)
+ assert_equal('CVarA@@cv', CVarB.new.cvB)
+ CVarB.cvB = 'B/singleton'
+ assert_equal 'B/singleton', CVarB.cvB
+ assert_equal 'B/singleton', CVarB.cvB2
+ assert_equal 'B/singleton', CVarB.new.cvB
+ assert_equal 'B/singleton', CVarA.cv
+ assert_equal 'B/singleton', CVarA.cv2
+ assert_equal 'B/singleton', CVarA.new.cv
+ CVarB.new.cvB = 'B/instance'
+ assert_equal 'B/instance', CVarB.cvB
+ assert_equal 'B/instance', CVarB.cvB2
+ assert_equal 'B/instance', CVarB.new.cvB
+ assert_equal 'B/instance', CVarA.cv
+ assert_equal 'B/instance', CVarA.cv2
+ assert_equal 'B/instance', CVarA.new.cv
+
+ CVarA.cv = 'CVarA@@cv'
+ CVarB.cvB = 'CVarB@@cv'
+ end
+
+ class OP
+ attr_accessor :x
+ end
+
+ def test_opassign
+ x = nil
+ x ||= 1
+ assert_equal 1, x
+ x &&= 2
+ assert_equal 2, x
+ x ||= 3
+ assert_equal 2, x
+ x &&= 4
+ assert_equal 4, x
+
+ y = OP.new
+ y.x = nil
+ y.x ||= 1
+ assert_equal 1, y.x
+ y.x &&= 2
+ assert_equal 2, y.x
+ y.x ||= 3
+ assert_equal 2, y.x
+ y.x &&= 4
+ assert_equal 4, y.x
+
+ z = OP.new
+ z.x = y
+ z.x.x = nil
+ z.x.x ||= 1
+ assert_equal 1, z.x.x
+ z.x.x &&= 2
+ assert_equal 2, z.x.x
+ z.x.x ||= 3
+ assert_equal 2, z.x.x
+ z.x.x &&= 4
+ assert_equal 4, z.x.x
+
+ a = []
+ a[0] = nil
+ a[0] ||= 1
+ assert_equal 1, a[0]
+ a[0] &&= 2
+ assert_equal 2, a[0]
+ a[0] ||= 3
+ assert_equal 2, a[0]
+ a[0] &&= 4
+ assert_equal 4, a[0]
+ end
+
+ def test_backref
+ /re/ =~ 'not match'
+ assert_nil $~
+ assert_nil $`
+ assert_nil $&
+ assert_nil $'
+ assert_nil $+
+ assert_nil $1
+ assert_nil $2
+ assert_nil $3
+ assert_nil $4
+ assert_nil $5
+ assert_nil $6
+ assert_nil $7
+ assert_nil $8
+ assert_nil $9
+
+ /(a)(b)(c)(d)(e)(f)(g)(h)(i)/ =~ 'xabcdefghiy'
+ assert_not_nil $~
+ assert_instance_of MatchData, $~
+ assert_equal 'abcdefghi', $~[0]
+ assert_equal 'a', $~[1]
+ assert_equal 'b', $~[2]
+ assert_equal 'c', $~[3]
+ assert_equal 'd', $~[4]
+ assert_equal 'e', $~[5]
+ assert_equal 'f', $~[6]
+ assert_equal 'g', $~[7]
+ assert_equal 'h', $~[8]
+ assert_equal 'i', $~[9]
+ assert_equal 'x', $`
+ assert_equal 'abcdefghi', $&
+ assert_equal 'y', $'
+ assert_equal 'i', $+
+ assert_equal 'a', $1
+ assert_equal 'b', $2
+ assert_equal 'c', $3
+ assert_equal 'd', $4
+ assert_equal 'e', $5
+ assert_equal 'f', $6
+ assert_equal 'g', $7
+ assert_equal 'h', $8
+ assert_equal 'i', $9
+
+ /re/ =~ 'not match'
+ assert_nil $~
+ assert_nil $`
+ assert_nil $&
+ assert_nil $'
+ assert_nil $+
+ assert_nil $1
+ assert_nil $2
+ assert_nil $3
+ assert_nil $4
+ assert_nil $5
+ assert_nil $6
+ assert_nil $7
+ assert_nil $8
+ assert_nil $9
+ end
+
+ def test_array_splat
+ a = []
+ assert_equal [], [*a]
+ assert_equal [1], [1, *a]
+ a = [2]
+ assert_equal [2], [*a]
+ assert_equal [1, 2], [1, *a]
+ a = [2, 3]
+ assert_equal [2, 3], [*a]
+ assert_equal [1, 2, 3], [1, *a]
+
+ a = nil
+ assert_equal [], [*a]
+ assert_equal [1], [1, *a]
+ end
+
+end
diff --git a/trunk/test/ruby/test_beginendblock.rb b/trunk/test/ruby/test_beginendblock.rb
new file mode 100644
index 0000000000..594596698b
--- /dev/null
+++ b/trunk/test/ruby/test_beginendblock.rb
@@ -0,0 +1,101 @@
+require 'test/unit'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestBeginEndBlock < Test::Unit::TestCase
+ DIR = File.dirname(File.expand_path(__FILE__))
+
+ def q(content)
+ "\"#{content}\""
+ end
+
+ def test_beginendblock
+ ruby = EnvUtil.rubybin
+ target = File.join(DIR, 'beginmainend.rb')
+ result = IO.popen([ruby, target]){|io|io.read}
+ assert_equal(%w(b1 b2-1 b2 main b3-1 b3 b4 e1 e4 e3 e2 e4-2 e4-1 e1-1 e4-1-1), result.split)
+
+ input = Tempfile.new(self.class.name)
+ inputpath = input.path
+ input.close
+ result = IO.popen([ruby, "-n", "-eBEGIN{p :begin}", "-eEND{p :end}", inputpath]){|io|io.read}
+ assert_equal(%w(:begin), result.split)
+ result = IO.popen([ruby, "-p", "-eBEGIN{p :begin}", "-eEND{p :end}", inputpath]){|io|io.read}
+ assert_equal(%w(:begin), result.split)
+ input.open
+ input.puts "foo\nbar"
+ input.close
+ result = IO.popen([ruby, "-n", "-eBEGIN{p :begin}", "-eEND{p :end}", inputpath]){|io|io.read}
+ assert_equal(%w(:begin :end), result.split)
+ result = IO.popen([ruby, "-p", "-eBEGIN{p :begin}", "-eEND{p :end}", inputpath]){|io|io.read}
+ assert_equal(%w(:begin foo bar :end), result.split)
+ end
+
+ def test_begininmethod
+ assert_raises(SyntaxError) do
+ eval("def foo; BEGIN {}; end")
+ end
+
+ assert_raises(SyntaxError) do
+ eval('eval("def foo; BEGIN {}; end")')
+ end
+ end
+
+ def test_endblockwarn
+ ruby = EnvUtil.rubybin
+ # Use Tempfile to create temporary file path.
+ launcher = Tempfile.new(self.class.name)
+ errout = Tempfile.new(self.class.name)
+
+ launcher << <<EOF
+errout = ARGV.shift
+STDERR.reopen(File.open(errout, "w"))
+STDERR.sync = true
+Dir.chdir(#{q(DIR)})
+system("#{ruby}", "endblockwarn_rb")
+EOF
+ launcher.close
+ launcherpath = launcher.path
+ errout.close
+ erroutpath = errout.path
+ system(ruby, launcherpath, erroutpath)
+ expected = <<EOW
+endblockwarn_rb:2: warning: END in method; use at_exit
+(eval):2: warning: END in method; use at_exit
+EOW
+ assert_equal(expected, File.read(erroutpath))
+ # expecting Tempfile to unlink launcher and errout file.
+ end
+
+ def test_raise_in_at_exit
+ ruby = EnvUtil.rubybin
+ out = IO.popen([ruby, '-e', 'STDERR.reopen(STDOUT)',
+ '-e', 'at_exit{raise %[SomethingBad]}',
+ '-e', 'raise %[SomethingElse]']) {|f|
+ f.read
+ }
+ assert_match /SomethingBad/, out, "[ruby-core:9675]"
+ assert_match /SomethingElse/, out, "[ruby-core:9675]"
+ end
+
+ def test_should_propagate_exit_code
+ ruby = EnvUtil.rubybin
+ assert_equal false, system(ruby, '-e', 'at_exit{exit 2}')
+ assert_equal 2, $?.exitstatus
+ assert_nil $?.termsig
+ end
+
+ def test_should_propagate_signaled
+ ruby = EnvUtil.rubybin
+ out = IO.popen(
+ [ruby,
+ '-e', 'STDERR.reopen(STDOUT)',
+ '-e', 'at_exit{Process.kill(:INT, $$); loop{}}']) {|f|
+ f.read
+ }
+ assert_match /Interrupt$/, out
+ Process.kill(0, 0) rescue return # check if signal works
+ assert_nil $?.exitstatus
+ assert_equal Signal.list["INT"], $?.termsig
+ end
+end
diff --git a/trunk/test/ruby/test_bignum.rb b/trunk/test/ruby/test_bignum.rb
new file mode 100644
index 0000000000..f6e9e65544
--- /dev/null
+++ b/trunk/test/ruby/test_bignum.rb
@@ -0,0 +1,390 @@
+require 'test/unit'
+
+class TestBignum < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def fact(n)
+ return 1 if n == 0
+ f = 1
+ while n>0
+ f *= n
+ n -= 1
+ end
+ return f
+ end
+
+ def test_bignum
+ $x = fact(40)
+ assert_equal($x, $x)
+ assert_equal($x, fact(40))
+ assert($x < $x+2)
+ assert($x > $x-2)
+ assert_equal(815915283247897734345611269596115894272000000000, $x)
+ assert_not_equal(815915283247897734345611269596115894272000000001, $x)
+ assert_equal(815915283247897734345611269596115894272000000001, $x+1)
+ assert_equal(335367096786357081410764800000, $x/fact(20))
+ $x = -$x
+ assert_equal(-815915283247897734345611269596115894272000000000, $x)
+ assert_equal(2-(2**32), -(2**32-2))
+ assert_equal(2**32 - 5, (2**32-3)-2)
+
+ for i in 1000..1014
+ assert_equal(2 ** i, 1 << i)
+ end
+
+ n1 = 1 << 1000
+ for i in 1000..1014
+ assert_equal(n1, 1 << i)
+ n1 *= 2
+ end
+
+ n2=n1
+ for i in 1..10
+ n1 = n1 / 2
+ n2 = n2 >> 1
+ assert_equal(n1, n2)
+ end
+
+ for i in 4000..4096
+ n1 = 1 << i;
+ assert_equal(n1-1, (n1**2-1) / (n1+1))
+ end
+ end
+
+ def test_calc
+ b = 10**80
+ a = b * 9 + 7
+ assert_equal(7, a.modulo(b))
+ assert_equal(-b + 7, a.modulo(-b))
+ assert_equal(b + -7, (-a).modulo(b))
+ assert_equal(-7, (-a).modulo(-b))
+ assert_equal(7, a.remainder(b))
+ assert_equal(7, a.remainder(-b))
+ assert_equal(-7, (-a).remainder(b))
+ assert_equal(-7, (-a).remainder(-b))
+
+ assert_equal(10000000000000000000100000000000000000000, 10**40+10**20)
+ assert_equal(100000000000000000000, 10**40/10**20)
+
+ a = 677330545177305025495135714080
+ b = 14269972710765292560
+ assert_equal(0, a % b)
+ assert_equal(0, -a % b)
+ end
+
+ def shift_test(a)
+ b = a / (2 ** 32)
+ c = a >> 32
+ assert_equal(b, c)
+
+ b = a * (2 ** 32)
+ c = a << 32
+ assert_equal(b, c)
+ end
+
+ def test_shift
+ shift_test(-4518325415524767873)
+ shift_test(-0xfffffffffffffffff)
+ end
+
+ def test_to_s
+ assert_equal("fvvvvvvvvvvvv" ,18446744073709551615.to_s(32), "[ruby-core:10686]")
+ assert_equal("g000000000000" ,18446744073709551616.to_s(32), "[ruby-core:10686]")
+ assert_equal("3w5e11264sgsf" ,18446744073709551615.to_s(36), "[ruby-core:10686]")
+ assert_equal("3w5e11264sgsg" ,18446744073709551616.to_s(36), "[ruby-core:10686]")
+ assert_equal("nd075ib45k86f" ,18446744073709551615.to_s(31), "[ruby-core:10686]")
+ assert_equal("nd075ib45k86g" ,18446744073709551616.to_s(31), "[ruby-core:10686]")
+ assert_equal("1777777777777777777777" ,18446744073709551615.to_s(8))
+ assert_equal("-1777777777777777777777" ,-18446744073709551615.to_s(8))
+ end
+
+
+ T_ZERO = (2**32).coerce(0).first
+ T_ONE = (2**32).coerce(1).first
+ T_MONE = (2**32).coerce(-1).first
+ T31 = 2**31 # 2147483648
+ T31P = T31 - 1 # 2147483647
+ T32 = 2**32 # 4294967296
+ T32P = T32 - 1 # 4294967295
+ T64 = 2**64 # 18446744073709551616
+ T64P = T64 - 1 # 18446744073709551615
+
+ def test_big_2comp
+ assert_equal("-4294967296", (~T32P).to_s)
+ assert_equal("..f00000000", "%x" % -T32)
+ end
+
+ def test_int2inum
+ assert_equal([T31P], [T31P].pack("I").unpack("I"))
+ assert_equal([T31P], [T31P].pack("i").unpack("i"))
+ end
+
+ def test_quad_pack
+ assert_equal([ 1], [ 1].pack("q").unpack("q"))
+ assert_equal([- 1], [- 1].pack("q").unpack("q"))
+ assert_equal([ T31P], [ T31P].pack("q").unpack("q"))
+ assert_equal([-T31P], [-T31P].pack("q").unpack("q"))
+ assert_equal([ T64P], [ T64P].pack("Q").unpack("Q"))
+ assert_equal([ 0], [ T64 ].pack("Q").unpack("Q"))
+ end
+
+ def test_str_to_inum
+ assert_equal(1, " +1".to_i)
+ assert_equal(-1, " -1".to_i)
+ assert_equal(0, "++1".to_i)
+ assert_equal(73, "111".oct)
+ assert_equal(273, "0x111".oct)
+ assert_equal(7, "0b111".oct)
+ assert_equal(73, "0o111".oct)
+ assert_equal(111, "0d111".oct)
+ assert_equal(73, "0111".oct)
+ assert_equal(111, Integer("111"))
+ assert_equal(13, "111".to_i(3))
+ assert_raise(ArgumentError) { "111".to_i(37) }
+ assert_equal(1333, "111".to_i(36))
+ assert_equal(1057, "111".to_i(32))
+ assert_equal(0, "00a".to_i)
+ assert_equal(1, Integer("1 "))
+ assert_raise(ArgumentError) { Integer("1_") }
+ assert_raise(ArgumentError) { Integer("1__") }
+ assert_raise(ArgumentError) { Integer("1_0 x") }
+ assert_equal(T31P, "1111111111111111111111111111111".to_i(2))
+ assert_equal(0_2, '0_2'.to_i)
+ assert_equal(00_2, '00_2'.to_i)
+ assert_equal(00_02, '00_02'.to_i)
+ end
+
+ def test_to_s2
+ assert_raise(ArgumentError) { T31P.to_s(37) }
+ assert_equal("9" * 32768, (10**32768-1).to_s)
+ assert_raise(RangeError) { Process.wait(1, T64P) }
+ assert_equal("0", T_ZERO.to_s)
+ assert_equal("1", T_ONE.to_s)
+ end
+
+ def test_to_f
+ assert_nothing_raised { T31P.to_f.to_i }
+ assert_raise(FloatDomainError) { (1024**1024).to_f.to_i }
+ end
+
+ def test_cmp
+ assert(T31P > 1)
+ assert(T31P < 2147483648.0)
+ assert(T31P < T64P)
+ assert(T64P > T31P)
+ assert_raise(ArgumentError) { T31P < "foo" }
+ end
+
+ def test_eq
+ assert(T31P != 1)
+ assert(T31P == 2147483647.0)
+ assert(T31P != "foo")
+ end
+
+ def test_eql
+ assert(T31P.eql?(T31P))
+ end
+
+ def test_convert
+ assert_equal([255], [T_MONE].pack("C").unpack("C"))
+ assert_equal([0], [T32].pack("C").unpack("C"))
+ assert_raise(RangeError) { 0.to_s(T32) }
+ assert_raise(Errno::EINVAL) do
+ begin Process.wait(0, T32P); rescue Errno::ECHILD; end
+ begin Process.wait(0, T64P); rescue Errno::ECHILD; end
+ end
+ assert_raise(RangeError) do
+ begin Process.wait(0, T32); rescue Errno::ECHILD; end
+ begin Process.wait(0, T64); rescue Errno::ECHILD; end
+ end
+ assert_raise(RangeError) do
+ begin Process.wait(0, -T32P); rescue Errno::ECHILD; end
+ begin Process.wait(0, -T64P); rescue Errno::ECHILD; end
+ end
+ end
+
+ def test_sub
+ assert_equal(-T31, T32 - (T32 + T31))
+ end
+
+ def test_plus
+ assert_equal(T32.to_f, T32P + 1.0)
+ assert_raise(TypeError) { T32 + "foo" }
+ end
+
+ def test_minus
+ assert_equal(T32P.to_f, T32 - 1.0)
+ assert_raise(TypeError) { T32 - "foo" }
+ end
+
+ def test_mul
+ assert_equal(T32.to_f, T32 * 1.0)
+ assert_raise(TypeError) { T32 * "foo" }
+ end
+
+ def test_divrem
+ assert_equal(0, T32 / T64)
+ end
+
+ def test_div
+ assert_equal(T32.to_f, T32 / 1.0)
+ assert_raise(TypeError) { T32 / "foo" }
+ assert_equal(0x20000000, 0x40000001.div(2.0), "[ruby-dev:34553]")
+ end
+
+ def test_idiv
+ assert_equal(715827882, 1073741824.div(Rational(3,2)), ' [ruby-dev:34066]')
+ end
+
+ def test_modulo
+ assert_raise(TypeError) { T32 % "foo" }
+ end
+
+ def test_remainder
+ assert_equal(0, T32.remainder(1))
+ assert_raise(TypeError) { T32.remainder("foo") }
+ end
+
+ def test_divmod
+ assert_equal([T32, 0], T32.divmod(1))
+ assert_equal([2, 0], T32.divmod(T31))
+ assert_raise(TypeError) { T32.divmod("foo") }
+ end
+
+ def test_quo
+ assert_equal(T32.to_f, T32.quo(1))
+ assert_equal(T32.to_f, T32.quo(1.0))
+ assert_equal(T32.to_f, T32.quo(T_ONE))
+
+ assert_raise(TypeError) { T32.quo("foo") }
+
+ assert_equal(1024**1024, (1024**1024).quo(1))
+ assert_equal(1024**1024, (1024**1024).quo(1.0))
+ assert_equal(1024**1024*2, (1024**1024*2).quo(1))
+ inf = 1 / 0.0; nan = inf / inf
+
+ assert((1024**1024*2).quo(nan).nan?)
+ end
+
+ def test_pow
+ assert_equal(1.0, T32 ** 0.0)
+ assert_equal(1.0 / T32, T32 ** -1)
+ assert((T32 ** T32).infinite?)
+ assert((T32 ** (2**30-1)).infinite?)
+
+ ### rational changes the behavior of Bignum#**
+ #assert_raise(TypeError) { T32**"foo" }
+ assert_raise(TypeError, ArgumentError) { T32**"foo" }
+ end
+
+ def test_and
+ assert_equal(0, T32 & 1)
+ assert_equal(-T32, (-T32) & (-T31))
+ assert_equal(0, T32 & T64)
+ end
+
+ def test_or
+ assert_equal(T32 + 1, T32 | 1)
+ assert_equal(T32 + T31, T32 | T31)
+ assert_equal(-T31, (-T32) | (-T31))
+ assert_equal(T64 + T32, T32 | T64)
+ end
+
+ def test_xor
+ assert_equal(T32 + 1, T32 ^ 1)
+ assert_equal(T32 + T31, T32 ^ T31)
+ assert_equal(T31, (-T32) ^ (-T31))
+ assert_equal(T64 + T32, T32 ^ T64)
+ end
+
+ def test_shift2
+ assert_equal(2**33, (2**32) << 1)
+ assert_equal(2**31, (2**32) << -1)
+ assert_equal(2**33, (2**32) << 1.0)
+ assert_equal(2**31, (2**32) << -1.0)
+ assert_equal(2**33, (2**32) << T_ONE)
+ assert_equal(2**31, (2**32) << T_MONE)
+ assert_equal(2**31, (2**32) >> 1)
+ assert_equal(2**33, (2**32) >> -1)
+ assert_equal(2**31, (2**32) >> 1.0)
+ assert_equal(2**33, (2**32) >> -1.0)
+ assert_equal(2**31, (2**32) >> T_ONE)
+ assert_equal(2**33, (2**32) >> T_MONE)
+ assert_equal( 0, (2**32) >> (2**32))
+ assert_equal(-1, -(2**32) >> (2**32))
+ assert_equal( 0, (2**32) >> 128)
+ assert_equal(-1, -(2**32) >> 128)
+ assert_equal( 0, (2**31) >> 32)
+ assert_equal(-1, -(2**31) >> 32)
+ end
+
+ def test_aref
+ assert_equal(0, (2**32)[0])
+ assert_equal(0, (2**32)[2**32])
+ assert_equal(0, (2**32)[-(2**32)])
+ assert_equal(0, (2**32)[T_ZERO])
+ assert_equal(0, (-(2**64))[0])
+ assert_equal(1, (-2**256)[256])
+ end
+
+ def test_hash
+ assert_nothing_raised { T31P.hash }
+ end
+
+ def test_coerce
+ assert_equal([T64P, T31P], T31P.coerce(T64P))
+ assert_raise(TypeError) { T31P.coerce(nil) }
+ end
+
+ def test_abs
+ assert_equal(T31P, (-T31P).abs)
+ end
+
+ def test_size
+ assert(T31P.size.is_a?(Integer))
+ end
+
+ def test_odd
+ assert_equal(true, (2**32+1).odd?)
+ assert_equal(false, (2**32).odd?)
+ end
+
+ def test_even
+ assert_equal(false, (2**32+1).even?)
+ assert_equal(true, (2**32).even?)
+ end
+
+ def interrupt
+ time = Time.now
+ start_flag = false
+ end_flag = false
+ thread = Thread.new do
+ start_flag = true
+ yield
+ end_flag = true
+ end
+ sleep 1
+ thread.raise
+ thread.join rescue nil
+ start_flag && !end_flag && Time.now - time < 10
+ end
+
+ def test_interrupt
+ assert(interrupt { (65536 ** 65536).to_s })
+ end
+
+ def test_too_big_to_s
+ if (big = 2**31-1).is_a?(Fixnum)
+ return
+ end
+ e = assert_raise(RangeError) {(1 << big).to_s}
+ assert_match(/too big to convert/, e.message)
+ end
+end
diff --git a/trunk/test/ruby/test_call.rb b/trunk/test/ruby/test_call.rb
new file mode 100644
index 0000000000..da7ee93c73
--- /dev/null
+++ b/trunk/test/ruby/test_call.rb
@@ -0,0 +1,19 @@
+require 'test/unit'
+
+class TestCall < Test::Unit::TestCase
+ def aaa(a, b=100, *rest)
+ res = [a, b]
+ res += rest if rest
+ return res
+ end
+
+ def test_call
+ assert_raises(ArgumentError) {aaa()}
+ assert_raises(ArgumentError) {aaa}
+
+ assert_equal([1, 100], aaa(1))
+ assert_equal([1, 2], aaa(1, 2))
+ assert_equal([1, 2, 3, 4], aaa(1, 2, 3, 4))
+ assert_equal([1, 2, 3, 4], aaa(1, *[2, 3, 4]))
+ end
+end
diff --git a/trunk/test/ruby/test_case.rb b/trunk/test/ruby/test_case.rb
new file mode 100644
index 0000000000..41a22038a0
--- /dev/null
+++ b/trunk/test/ruby/test_case.rb
@@ -0,0 +1,49 @@
+require 'test/unit'
+
+class TestCase < Test::Unit::TestCase
+ def test_case
+ case 5
+ when 1, 2, 3, 4, 6, 7, 8
+ assert(false)
+ when 5
+ assert(true)
+ end
+
+ case 5
+ when 5
+ assert(true)
+ when 1..10
+ assert(false)
+ end
+
+ case 5
+ when 1..10
+ assert(true)
+ else
+ assert(false)
+ end
+
+ case 5
+ when 5
+ assert(true)
+ else
+ assert(false)
+ end
+
+ case "foobar"
+ when /^f.*r$/
+ assert(true)
+ else
+ assert(false)
+ end
+
+ case
+ when true
+ assert(true)
+ when false, nil
+ assert(false)
+ else
+ assert(false)
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_class.rb b/trunk/test/ruby/test_class.rb
new file mode 100644
index 0000000000..93a19e86e9
--- /dev/null
+++ b/trunk/test/ruby/test_class.rb
@@ -0,0 +1,147 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestClass < Test::Unit::TestCase
+ # ------------------
+ # Various test classes
+ # ------------------
+
+ class ClassOne
+ attr :num_args
+ @@subs = []
+ def initialize(*args)
+ @num_args = args.size
+ @args = args
+ end
+ def [](n)
+ @args[n]
+ end
+ def ClassOne.inherited(klass)
+ @@subs.push klass
+ end
+ def subs
+ @@subs
+ end
+ end
+
+ class ClassTwo < ClassOne
+ end
+
+ class ClassThree < ClassOne
+ end
+
+ class ClassFour < ClassThree
+ end
+
+ # ------------------
+ # Start of tests
+ # ------------------
+
+ def test_s_inherited
+ assert_equal([ClassTwo, ClassThree, ClassFour], ClassOne.new.subs)
+ end
+
+ def test_s_new
+ c = Class.new
+ assert_same(Class, c.class)
+ assert_same(Object, c.superclass)
+
+ c = Class.new(Fixnum)
+ assert_same(Class, c.class)
+ assert_same(Fixnum, c.superclass)
+ end
+
+ def test_00_new_basic
+ a = ClassOne.new
+ assert_equal(ClassOne, a.class)
+ assert_equal(0, a.num_args)
+
+ a = ClassOne.new(1, 2, 3)
+ assert_equal(3, a.num_args)
+ assert_equal(1, a[0])
+ end
+
+ def test_01_new_inherited
+ a = ClassTwo.new
+ assert_equal(ClassTwo, a.class)
+ assert_equal(0, a.num_args)
+
+ a = ClassTwo.new(1, 2, 3)
+ assert_equal(3, a.num_args)
+ assert_equal(1, a[0])
+ end
+
+ def test_superclass
+ assert_equal(ClassOne, ClassTwo.superclass)
+ assert_equal(Object, ClassTwo.superclass.superclass)
+ assert_equal(BasicObject, ClassTwo.superclass.superclass.superclass)
+ end
+
+ def test_class_cmp
+ assert_raise(TypeError) { Class.new <= 1 }
+ assert_raise(TypeError) { Class.new >= 1 }
+ assert_nil(Class.new <=> 1)
+ end
+
+ def test_class_initialize
+ assert_raise(TypeError) do
+ Class.new.instance_eval { initialize }
+ end
+ end
+
+ def test_instanciate_singleton_class
+ c = class << Object.new; self; end
+ assert_raise(TypeError) { c.new }
+ end
+
+ def test_superclass_of_basicobject
+ assert_equal(nil, BasicObject.superclass)
+ end
+
+ def test_module_function
+ c = Class.new
+ assert_raise(TypeError) do
+ Module.instance_method(:module_function).bind(c).call(:foo)
+ end
+ end
+
+ def test_check_inheritable
+ assert_raise(TypeError) { Class.new(Object.new) }
+
+ o = Object.new
+ c = class << o; self; end
+ assert_raise(TypeError) { Class.new(c) }
+
+ assert_nothing_raised { Class.new(Class) } # is it OK?
+ assert_raise(TypeError) { eval("class Foo < Class; end") }
+ end
+
+ def test_initialize_copy
+ c = Class.new
+ assert_raise(TypeError) { c.instance_eval { initialize_copy(1) } }
+
+ o = Object.new
+ c = class << o; self; end
+ assert_raise(TypeError) { c.dup }
+ end
+
+ def test_singleton_class
+ assert_raise(TypeError) { 1.extend(Module.new) }
+ assert_raise(TypeError) { :foo.extend(Module.new) }
+
+ assert_in_out_err([], <<-INPUT, %w(:foo :foo true true), [])
+ module Foo; def foo; :foo; end; end
+ false.extend(Foo)
+ true.extend(Foo)
+ p false.foo
+ p true.foo
+ p FalseClass.include?(Foo)
+ p TrueClass.include?(Foo)
+ INPUT
+ end
+
+ def test_uninitialized
+ assert_raise(TypeError) { Class.allocate.new }
+ assert_raise(TypeError) { Class.allocate.superclass }
+ end
+end
diff --git a/trunk/test/ruby/test_clone.rb b/trunk/test/ruby/test_clone.rb
new file mode 100644
index 0000000000..43c0cffa1d
--- /dev/null
+++ b/trunk/test/ruby/test_clone.rb
@@ -0,0 +1,28 @@
+require 'test/unit'
+
+class TestClone < Test::Unit::TestCase
+ module M001; end
+ module M002; end
+ module M003; include M002; end
+ module M002; include M001; end
+ module M003; include M002; end
+
+ def test_clone
+ foo = Object.new
+ def foo.test
+ "test"
+ end
+ bar = foo.clone
+ def bar.test2
+ "test2"
+ end
+
+ assert_equal("test2", bar.test2)
+ assert_equal("test", bar.test)
+ assert_equal("test", foo.test)
+
+ assert_raises(NoMethodError) {foo.test2}
+
+ assert_equal([M003, M002, M001], M003.ancestors)
+ end
+end
diff --git a/trunk/test/ruby/test_comparable.rb b/trunk/test/ruby/test_comparable.rb
new file mode 100644
index 0000000000..e558b190f0
--- /dev/null
+++ b/trunk/test/ruby/test_comparable.rb
@@ -0,0 +1,66 @@
+require 'test/unit'
+
+class TestComparable < Test::Unit::TestCase
+ def setup
+ @o = Object.new
+ @o.extend(Comparable)
+ end
+
+ def test_equal
+ def @o.<=>(x); 0; end
+ assert_equal(true, @o == nil)
+ def @o.<=>(x); 1; end
+ assert_equal(false, @o == nil)
+ def @o.<=>(x); raise; end
+ assert_equal(false, @o == nil)
+ end
+
+ def test_gt
+ def @o.<=>(x); 1; end
+ assert_equal(true, @o > nil)
+ def @o.<=>(x); 0; end
+ assert_equal(false, @o > nil)
+ def @o.<=>(x); -1; end
+ assert_equal(false, @o > nil)
+ end
+
+ def test_ge
+ def @o.<=>(x); 1; end
+ assert_equal(true, @o >= nil)
+ def @o.<=>(x); 0; end
+ assert_equal(true, @o >= nil)
+ def @o.<=>(x); -1; end
+ assert_equal(false, @o >= nil)
+ end
+
+ def test_lt
+ def @o.<=>(x); 1; end
+ assert_equal(false, @o < nil)
+ def @o.<=>(x); 0; end
+ assert_equal(false, @o < nil)
+ def @o.<=>(x); -1; end
+ assert_equal(true, @o < nil)
+ end
+
+ def test_le
+ def @o.<=>(x); 1; end
+ assert_equal(false, @o <= nil)
+ def @o.<=>(x); 0; end
+ assert_equal(true, @o <= nil)
+ def @o.<=>(x); -1; end
+ assert_equal(true, @o <= nil)
+ end
+
+ def test_between
+ def @o.<=>(x); 0 <=> x end
+ assert_equal(false, @o.between?(1, 2))
+ assert_equal(false, @o.between?(-2, -1))
+ assert_equal(true, @o.between?(-1, 1))
+ assert_equal(true, @o.between?(0, 0))
+ end
+
+ def test_err
+ assert_raise(ArgumentError) { 1.0 < nil }
+ assert_raise(ArgumentError) { 1.0 < Object.new }
+ end
+end
diff --git a/trunk/test/ruby/test_complex.rb b/trunk/test/ruby/test_complex.rb
new file mode 100644
index 0000000000..b661864519
--- /dev/null
+++ b/trunk/test/ruby/test_complex.rb
@@ -0,0 +1,1147 @@
+require 'test/unit'
+
+class ComplexSub < Complex; end
+
+class Complex_Test < Test::Unit::TestCase
+
+ def test_compsub
+ c = ComplexSub.__send__(:new, 1)
+ cc = ComplexSub.__send__(:convert, 1)
+ if defined?(ComplexSub::Unify)
+ assert_instance_of(Fixnum, c)
+ assert_instance_of(Fixnum, cc)
+ else
+ assert_instance_of(ComplexSub, c)
+ assert_instance_of(ComplexSub, cc)
+
+ c2 = c + 1
+ assert_instance_of(ComplexSub, c2)
+ c2 = c - 1
+ assert_instance_of(ComplexSub, c2)
+
+ c3 = c - c2
+ assert_instance_of(ComplexSub, c3)
+
+ s = Marshal.dump(c)
+ c5 = Marshal.load(s)
+ assert_equal(c, c5)
+ assert_instance_of(ComplexSub, c5)
+ end
+
+ end
+
+ def test_eql_p
+ c = Complex(0)
+ c2 = Complex(0)
+ c3 = Complex(1)
+
+ assert_equal(true, c.eql?(c2))
+ assert_equal(false, c.eql?(c3))
+
+ if defined?(Complex::Unify)
+ assert_equal(true, c.eql?(0))
+ else
+ assert_equal(false, c.eql?(0))
+ end
+ end
+
+ def test_hash
+ assert_instance_of(Fixnum, Complex(1,2).hash)
+
+ h = {}
+ h[Complex(0)] = 0
+ h[Complex(0,1)] = 1
+ h[Complex(1,0)] = 2
+ h[Complex(1,1)] = 3
+
+ assert_equal(4, h.size)
+ assert_equal(2, h[Complex(1,0)])
+
+ h[Complex(0,0)] = 9
+ assert_equal(4, h.size)
+ end
+
+ def test_freeze
+ c = Complex(1)
+ c.freeze
+ unless defined?(Complex::Unify)
+ assert_equal(true, c.frozen?)
+ end
+ assert_instance_of(String, c.to_s)
+ end
+
+ def test_new_bang # no unify
+ assert_instance_of(Complex, Complex.__send__(:new!, 2,0))
+ assert_equal([2,0], Complex.__send__(:new!, 2,0).
+ instance_eval{[real, image]})
+ assert_equal([2,4], Complex.__send__(:new!, 2,4).
+ instance_eval{[real, image]})
+ assert_equal([-2,4], Complex.__send__(:new!, -2,4).
+ instance_eval{[real, image]})
+ assert_equal([2,-4], Complex.__send__(:new!, 2,-4).
+ instance_eval{[real, image]})
+ assert_equal([-2,-4], Complex.__send__(:new!, -2,-4).
+ instance_eval{[real, image]})
+
+ assert_equal([2,0], Complex.__send__(:new!, Complex(2)).
+ instance_eval{[real, image]})
+ assert_equal([2,3], Complex.__send__(:new!, Complex(2), Complex(3)).
+ instance_eval{[real, image]})
+ assert_equal([2,3], Complex.__send__(:new!, 2, Complex(3)).
+ instance_eval{[real, image]})
+
+ assert_equal([1.1,0], Complex.__send__(:new!, 1.1).
+ instance_eval{[real, image]})
+ assert_equal([-1.1,0], Complex.__send__(:new!, -1.1).
+ instance_eval{[real, image]})
+ assert_equal([1,0], Complex.__send__(:new!, '1').
+ instance_eval{[real, image]})
+ assert_equal([0,0], Complex.__send__(:new!, nil).
+ instance_eval{[real, image]})
+ end
+
+ def test_new
+ if defined?(Complex::Unify)
+ assert_instance_of(Fixnum, Complex.__send__(:new, 2,0))
+ else
+ assert_instance_of(Complex, Complex.__send__(:new, 2,0))
+ assert_equal([2,0], Complex.__send__(:new, 2,0). instance_eval{[real, image]})
+ end
+ assert_equal([2,4], Complex.__send__(:new, 2,4).instance_eval{[real, image]})
+ assert_equal([-2,4], Complex.__send__(:new, -2,4).instance_eval{[real, image]})
+ assert_equal([2,-4], Complex.__send__(:new, 2,-4).instance_eval{[real, image]})
+ assert_equal([-2,-4], Complex.__send__(:new, -2,-4).instance_eval{[real, image]})
+
+ assert_raise(ArgumentError){Complex.__send__(:new, Complex(1,2),2)}
+ assert_raise(ArgumentError){Complex.__send__(:new, 2,Complex(1,2))}
+ assert_raise(ArgumentError){Complex.__send__(:new, Complex(1,2),Complex(1,2))}
+
+ assert_raise(ArgumentError){Complex.__send__(:new, '1')}
+ assert_raise(ArgumentError){Complex.__send__(:new, nil)}
+=begin
+ assert_raise(ArgumentError){Complex.__send__(:new, Complex(1))}
+=end
+ end
+
+ def test_conv
+ c = Complex(0,0)
+ assert_equal(Complex.__send__(:new, 0,0), c)
+
+ c = Complex(2**32, 2**32)
+ assert_equal(Complex.__send__(:new, 2**32,2**32), c)
+ assert_equal([2**32,2**32], [c.real,c.image])
+
+ c = Complex(-2**32, 2**32)
+ assert_equal(Complex.__send__(:new, -2**32,2**32), c)
+ assert_equal([-2**32,2**32], [c.real,c.image])
+
+ c = Complex(2**32, -2**32)
+ assert_equal(Complex.__send__(:new, 2**32,-2**32), c)
+ assert_equal([2**32,-2**32], [c.real,c.image])
+
+ c = Complex(-2**32, -2**32)
+ assert_equal(Complex.__send__(:new, -2**32,-2**32), c)
+ assert_equal([-2**32,-2**32], [c.real,c.image])
+
+ c = Complex(Complex(1),0)
+ assert_equal(Complex.__send__(:new, 1,0), c)
+
+ c = Complex(0,Complex(1))
+ assert_equal(Complex.__send__(:new, 0,1), c)
+
+ c = 5.re
+ assert_equal(Complex.__send__(:new, 5,0), c)
+
+ c = Complex(1,2).re
+ assert_equal(Complex.__send__(:new, 1,2), c)
+
+ c = 5.im
+ assert_equal(Complex.__send__(:new, 0,5), c)
+
+ c = Complex(2,0).im
+ assert_equal(Complex.__send__(:new, 0,2), c)
+ assert_raise(ArgumentError){Complex(1,2).im}
+
+ c = Complex::I
+ assert_equal(Complex.__send__(:new, 0,1), c)
+
+ assert_equal(Complex.__send__(:new, 1),Complex(1))
+ assert_equal(Complex.__send__(:new, 1),Complex('1'))
+ assert_raise(ArgumentError){Complex(nil)}
+ end
+
+ def test_attr
+ c = Complex(4)
+
+ assert_equal(4, c.real)
+ assert_equal(0, c.image)
+
+ c = Complex(4,5)
+
+ assert_equal(4, c.real)
+ assert_equal(5, c.image)
+
+ c = Complex(-0.0,-0.0)
+
+ assert_equal('-0.0', c.real.to_s)
+ assert_equal('-0.0', c.image.to_s)
+
+ c = Complex.__send__(:new, 4)
+
+ assert_equal(4, c.real)
+ assert_equal(0, c.image)
+ assert_equal(c.imag, c.image)
+
+ c = Complex.__send__(:new, 4,5)
+
+ assert_equal(4, c.real)
+ assert_equal(5, c.image)
+ assert_equal(c.imag, c.image)
+
+ c = Complex.__send__(:new, -0.0,-0.0)
+
+ assert_equal('-0.0', c.real.to_s)
+ assert_equal('-0.0', c.image.to_s)
+ assert_equal(c.imag.to_s, c.image.to_s)
+
+ c = Complex.__send__(:new!, 4)
+
+ assert_equal(4, c.real)
+ assert_equal(c.imag, c.image)
+ assert_equal(0, c.image)
+
+ c = Complex.__send__(:new!, 4,5)
+
+ assert_equal(4, c.real)
+ assert_equal(5, c.image)
+ assert_equal(c.imag, c.image)
+
+ c = Complex.__send__(:new!, -0.0,-0.0)
+
+ assert_equal('-0.0', c.real.to_s)
+ assert_equal('-0.0', c.image.to_s)
+ assert_equal(c.imag.to_s, c.image.to_s)
+ end
+
+ def test_attr2
+ c = Complex(1)
+
+ if defined?(Complex::Unify)
+ assert_equal(true, c.scalar?)
+=begin
+ assert_equal(true, c.finite?)
+ assert_equal(false, c.infinite?)
+ assert_equal(false, c.nan?)
+ assert_equal(true, c.integer?)
+ assert_equal(false, c.float?)
+ assert_equal(true, c.rational?)
+ assert_equal(true, c.real?)
+ assert_equal(false, c.complex?)
+ assert_equal(true, c.exact?)
+ assert_equal(false, c.inexact?)
+=end
+ else
+ assert_equal(false, c.scalar?)
+=begin
+ assert_equal(true, c.finite?)
+ assert_equal(false, c.infinite?)
+ assert_equal(false, c.nan?)
+ assert_equal(false, c.integer?)
+ assert_equal(false, c.float?)
+ assert_equal(false, c.rational?)
+ assert_equal(false, c.real?)
+ assert_equal(true, c.complex?)
+ assert_equal(true, c.exact?)
+ assert_equal(false, c.inexact?)
+=end
+ end
+
+=begin
+ assert_equal(0, Complex(0).sign)
+ assert_equal(1, Complex(2).sign)
+ assert_equal(-1, Complex(-2).sign)
+=end
+
+ assert_equal(true, Complex(0).zero?)
+ assert_equal(true, Complex(0,0).zero?)
+ assert_equal(false, Complex(1,0).zero?)
+ assert_equal(false, Complex(0,1).zero?)
+ assert_equal(false, Complex(1,1).zero?)
+
+ assert_equal(nil, Complex(0).nonzero?)
+ assert_equal(nil, Complex(0,0).nonzero?)
+ assert_equal(Complex(1,0), Complex(1,0).nonzero?)
+ assert_equal(Complex(0,1), Complex(0,1).nonzero?)
+ assert_equal(Complex(1,1), Complex(1,1).nonzero?)
+ end
+
+ def test_uplus
+ assert_equal(Complex(1), +Complex(1))
+ assert_equal(Complex(-1), +Complex(-1))
+ assert_equal(Complex(1,1), +Complex(1,1))
+ assert_equal(Complex(-1,1), +Complex(-1,1))
+ assert_equal(Complex(1,-1), +Complex(1,-1))
+ assert_equal(Complex(-1,-1), +Complex(-1,-1))
+ end
+
+ def test_negate
+ assert_equal(Complex(-1), -Complex(1))
+ assert_equal(Complex(1), -Complex(-1))
+ assert_equal(Complex(-1,-1), -Complex(1,1))
+ assert_equal(Complex(1,-1), -Complex(-1,1))
+ assert_equal(Complex(-1,1), -Complex(1,-1))
+ assert_equal(Complex(1,1), -Complex(-1,-1))
+
+=begin
+ assert_equal(0, Complex(0).negate)
+ assert_equal(-2, Complex(2).negate)
+ assert_equal(2, Complex(-2).negate)
+=end
+ end
+
+ def test_add
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ assert_equal(Complex(3,5), c + c2)
+
+ assert_equal(Complex(3,2), c + 2)
+ assert_equal(Complex(3.0,2), c + 2.0)
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(3,1),Rational(2)), c + Rational(2))
+ assert_equal(Complex(Rational(5,3),Rational(2)), c + Rational(2,3))
+ end
+ end
+
+ def test_sub
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ assert_equal(Complex(-1,-1), c - c2)
+
+ assert_equal(Complex(-1,2), c - 2)
+ assert_equal(Complex(-1.0,2), c - 2.0)
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(-1,1),Rational(2)), c - Rational(2))
+ assert_equal(Complex(Rational(1,3),Rational(2)), c - Rational(2,3))
+ end
+ end
+
+ def test_mul
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ assert_equal(Complex(-4,7), c * c2)
+
+ assert_equal(Complex(2,4), c * 2)
+ assert_equal(Complex(2.0,4.0), c * 2.0)
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(2,1),Rational(4)), c * Rational(2))
+ assert_equal(Complex(Rational(2,3),Rational(4,3)), c * Rational(2,3))
+ end
+
+ end
+
+ def test_div
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(8,13),Rational(1,13)), c / c2)
+ else
+ r = c / c2
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.image, 0.001)
+ end
+
+ c = Complex(1.0,2.0)
+ c2 = Complex(2.0,3.0)
+
+ r = c / c2
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.image, 0.001)
+
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(1,2),1), c / 2)
+ else
+ assert_equal(Complex(0.5,1.0), c / 2)
+ end
+ assert_equal(Complex(0.5,1.0), c / 2.0)
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
+ assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
+ end
+ end
+
+ def test_quo
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(8,13),Rational(1,13)), c.quo(c2))
+ else
+ r = c.quo(c2)
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.image, 0.001)
+ end
+
+ c = Complex(1.0,2.0)
+ c2 = Complex(2.0,3.0)
+
+ r = c.quo(c2)
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.image, 0.001)
+
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(1,2),1), c.quo(2))
+ else
+ assert_equal(Complex(0.5,1.0), c.quo(2))
+ end
+ assert_equal(Complex(0.5,1.0), c.quo(2.0))
+
+ if defined?(Rational)
+ assert_equal(Complex(Rational(1,2),Rational(1)), c / Rational(2))
+ assert_equal(Complex(Rational(3,2),Rational(3)), c / Rational(2,3))
+ end
+ end
+
+ def test_fdiv
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ r = c.fdiv(c2)
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.image, 0.001)
+
+ c = Complex(1.0,2.0)
+ c2 = Complex(2.0,3.0)
+
+ r = c.fdiv(c2)
+ assert_in_delta(0.615, r.real, 0.001)
+ assert_in_delta(0.076, r.image, 0.001)
+
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ assert_equal(Complex(0.5,1.0), c.fdiv(2))
+ assert_equal(Complex(0.5,1.0), c.fdiv(2.0))
+ end
+
+ def test_expt
+ c = Complex(1,2)
+ c2 = Complex(2,3)
+
+ r = c ** c2
+ assert_in_delta(-0.015, r.real, 0.001)
+ assert_in_delta(-0.179, r.image, 0.001)
+
+ assert_equal(Complex(-3,4), c ** 2)
+ if defined?(Rational) && !Rational.instance_variable_get('@RCS_ID')
+ assert_equal(Complex(Rational(-3,25),Rational(-4,25)), c ** -2)
+ else
+ r = c ** -2
+ assert_in_delta(-0.12, r.real, 0.001)
+ assert_in_delta(-0.16, r.image, 0.001)
+ end
+ r = c ** 2.0
+ assert_in_delta(-3.0, r.real, 0.001)
+ assert_in_delta(4.0, r.image, 0.001)
+
+ r = c ** -2.0
+ assert_in_delta(-0.12, r.real, 0.001)
+ assert_in_delta(-0.16, r.image, 0.001)
+
+ if defined?(Rational) && !Rational.instance_variable_get('@RCS_ID')
+ assert_equal(Complex(-3,4), c ** Rational(2))
+#=begin
+ assert_equal(Complex(Rational(-3,25),Rational(-4,25)),
+ c ** Rational(-2)) # why failed?
+#=end
+
+ r = c ** Rational(2,3)
+ assert_in_delta(1.264, r.real, 0.001)
+ assert_in_delta(1.150, r.image, 0.001)
+
+ r = c ** Rational(-2,3)
+ assert_in_delta(0.432, r.real, 0.001)
+ assert_in_delta(-0.393, r.image, 0.001)
+ end
+ end
+
+ def test_cmp
+ assert_raise(NoMethodError){1 <=> Complex(1,1)}
+ assert_raise(NoMethodError){Complex(1,1) <=> 1}
+ assert_raise(NoMethodError){Complex(1,1) <=> Complex(1,1)}
+ end
+
+ def test_equal
+ assert(Complex(1,0) == Complex(1))
+ assert(Complex(1,0) == Complex.__send__(:new, 1))
+ assert(Complex(1,0) == Complex.__send__(:new, 1,0))
+ assert(Complex(1,0) == Complex.__send__(:new!, 1))
+ assert(Complex(1,0) == Complex.__send__(:new!, 1,0))
+
+ assert(Complex(-1,0) == Complex(-1))
+ assert(Complex(-1,0) == Complex.__send__(:new, -1))
+ assert(Complex(-1,0) == Complex.__send__(:new, -1,0))
+ assert(Complex(-1,0) == Complex.__send__(:new!, -1))
+ assert(Complex(-1,0) == Complex.__send__(:new!, -1,0))
+
+ assert_equal(false, Complex(2,1) == Complex(1))
+ assert_equal(true, Complex(2,1) != Complex(1))
+ assert_equal(false, Complex(1) == nil)
+ assert_equal(false, Complex(1) == '')
+ end
+
+ def test_math
+ c = Complex(1,2)
+
+ assert_in_delta(2.236, c.abs, 0.001)
+ assert_equal(5, c.abs2)
+
+ assert_equal(c.abs, Math.sqrt(c * c.conj))
+ assert_equal(c.abs, Math.sqrt(c.real**2 + c.image**2))
+ assert_equal(c.abs2, c * c.conj)
+ assert_equal(c.abs2, c.real**2 + c.image**2)
+
+ assert_in_delta(1.107, c.arg, 0.001)
+ assert_in_delta(1.107, c.angle, 0.001)
+
+ r = c.polar
+ assert_in_delta(2.236, r[0], 0.001)
+ assert_in_delta(1.107, r[1], 0.001)
+ assert_equal(Complex(1,-2), c.conjugate)
+ assert_equal(Complex(1,-2), c.conj)
+# assert_equal(Complex(1,-2), ~c)
+# assert_equal(5, c * ~c)
+
+ assert_equal(Complex(1,2), c.numerator)
+ assert_equal(1, c.denominator)
+ end
+
+ def test_to_s
+ c = Complex(1,2)
+
+ assert_instance_of(String, c.to_s)
+ assert_equal('1+2i', c.to_s)
+
+ assert_equal('0+2i', Complex(0,2).to_s)
+ assert_equal('0-2i', Complex(0,-2).to_s)
+ assert_equal('1+2i', Complex(1,2).to_s)
+ assert_equal('-1+2i', Complex(-1,2).to_s)
+ assert_equal('-1-2i', Complex(-1,-2).to_s)
+ assert_equal('1-2i', Complex(1,-2).to_s)
+ assert_equal('-1-2i', Complex(-1,-2).to_s)
+
+ assert_equal('0+2.0i', Complex(0,2.0).to_s)
+ assert_equal('0-2.0i', Complex(0,-2.0).to_s)
+ assert_equal('1.0+2.0i', Complex(1.0,2.0).to_s)
+ assert_equal('-1.0+2.0i', Complex(-1.0,2.0).to_s)
+ assert_equal('-1.0-2.0i', Complex(-1.0,-2.0).to_s)
+ assert_equal('1.0-2.0i', Complex(1.0,-2.0).to_s)
+ assert_equal('-1.0-2.0i', Complex(-1.0,-2.0).to_s)
+
+ if defined?(Rational) && !defined?(Complex::Unify) && !Rational.instance_variable_get('@RCS_ID')
+ assert_equal('0+2/1i', Complex(0,Rational(2)).to_s)
+ assert_equal('0-2/1i', Complex(0,Rational(-2)).to_s)
+ assert_equal('1+2/1i', Complex(1,Rational(2)).to_s)
+ assert_equal('-1+2/1i', Complex(-1,Rational(2)).to_s)
+ assert_equal('-1-2/1i', Complex(-1,Rational(-2)).to_s)
+ assert_equal('1-2/1i', Complex(1,Rational(-2)).to_s)
+ assert_equal('-1-2/1i', Complex(-1,Rational(-2)).to_s)
+
+ assert_equal('0+2/3i', Complex(0,Rational(2,3)).to_s)
+ assert_equal('0-2/3i', Complex(0,Rational(-2,3)).to_s)
+ assert_equal('1+2/3i', Complex(1,Rational(2,3)).to_s)
+ assert_equal('-1+2/3i', Complex(-1,Rational(2,3)).to_s)
+ assert_equal('-1-2/3i', Complex(-1,Rational(-2,3)).to_s)
+ assert_equal('1-2/3i', Complex(1,Rational(-2,3)).to_s)
+ assert_equal('-1-2/3i', Complex(-1,Rational(-2,3)).to_s)
+ end
+ end
+
+ def test_inspect
+ c = Complex(1,2)
+
+ assert_instance_of(String, c.inspect)
+ assert_equal('(1+2i)', c.inspect)
+ end
+
+ def test_marshal
+ c = Complex(1,2)
+
+ s = Marshal.dump(c)
+ c2 = Marshal.load(s)
+ assert_equal(c, c2)
+ assert_instance_of(Complex, c2)
+
+ if defined?(Rational)
+ c = Complex(Rational(1,2),Rational(2,3))
+
+ s = Marshal.dump(c)
+ c2 = Marshal.load(s)
+ assert_equal(c, c2)
+ assert_instance_of(Complex, c2)
+ end
+ end
+
+ def test_parse
+ assert_equal(Complex(0), ''.to_c)
+ assert_equal(Complex(0), ' '.to_c)
+ assert_equal(Complex(5), '5'.to_c)
+ assert_equal(Complex(-5), '-5'.to_c)
+ assert_equal(Complex(5,3), '5+3i'.to_c)
+ assert_equal(Complex(-5,3), '-5+3i'.to_c)
+ assert_equal(Complex(5,-3), '5-3i'.to_c)
+ assert_equal(Complex(-5,-3), '-5-3i'.to_c)
+ assert_equal(Complex(0,3), '3i'.to_c)
+ assert_equal(Complex(0,-3), '-3i'.to_c)
+ assert_equal(Complex(5,1), '5+i'.to_c)
+ assert_equal(Complex(0,1), 'i'.to_c)
+ assert_equal(Complex(0,1), '+i'.to_c)
+ assert_equal(Complex(0,-1), '-i'.to_c)
+
+ assert_equal(Complex(5,3), '5+3I'.to_c)
+ assert_equal(Complex(5,3), '5+3j'.to_c)
+ assert_equal(Complex(5,3), '5+3J'.to_c)
+ assert_equal(Complex(0,3), '3I'.to_c)
+ assert_equal(Complex(0,3), '3j'.to_c)
+ assert_equal(Complex(0,3), '3J'.to_c)
+ assert_equal(Complex(0,1), 'I'.to_c)
+ assert_equal(Complex(0,1), 'J'.to_c)
+
+ assert_equal(Complex(5.0), '5.0'.to_c)
+ assert_equal(Complex(-5.0), '-5.0'.to_c)
+ assert_equal(Complex(5.0,3.0), '5.0+3.0i'.to_c)
+ assert_equal(Complex(-5.0,3.0), '-5.0+3.0i'.to_c)
+ assert_equal(Complex(5.0,-3.0), '5.0-3.0i'.to_c)
+ assert_equal(Complex(-5.0,-3.0), '-5.0-3.0i'.to_c)
+ assert_equal(Complex(0.0,3.0), '3.0i'.to_c)
+ assert_equal(Complex(0.0,-3.0), '-3.0i'.to_c)
+
+ assert_equal(Complex(5.0), '5e0'.to_c)
+ assert_equal(Complex(-5.0), '-5e0'.to_c)
+ assert_equal(Complex(5.0,3.0), '5e0+3e0i'.to_c)
+ assert_equal(Complex(-5.0,3.0), '-5e0+3e0i'.to_c)
+ assert_equal(Complex(5.0,-3.0), '5e0-3e0i'.to_c)
+ assert_equal(Complex(-5.0,-3.0), '-5e0-3e0i'.to_c)
+ assert_equal(Complex(0.0,3.0), '3e0i'.to_c)
+ assert_equal(Complex(0.0,-3.0), '-3e0i'.to_c)
+
+ assert_equal(Complex.polar(10,10), '10@10'.to_c)
+ assert_equal(Complex.polar(-10,-10), '-10@-10'.to_c)
+ assert_equal(Complex.polar(10.5,10.5), '10.5@10.5'.to_c)
+ assert_equal(Complex.polar(-10.5,-10.5), '-10.5@-10.5'.to_c)
+
+ assert_equal(Complex(5), Complex('5'))
+ assert_equal(Complex(-5), Complex('-5'))
+ assert_equal(Complex(5,3), Complex('5+3i'))
+ assert_equal(Complex(-5,3), Complex('-5+3i'))
+ assert_equal(Complex(5,-3), Complex('5-3i'))
+ assert_equal(Complex(-5,-3), Complex('-5-3i'))
+ assert_equal(Complex(0,3), Complex('3i'))
+ assert_equal(Complex(0,-3), Complex('-3i'))
+ assert_equal(Complex(5,1), Complex('5+i'))
+ assert_equal(Complex(0,1), Complex('i'))
+ assert_equal(Complex(0,1), Complex('+i'))
+ assert_equal(Complex(0,-1), Complex('-i'))
+
+ assert_equal(Complex(5,3), Complex('5+3I'))
+ assert_equal(Complex(5,3), Complex('5+3j'))
+ assert_equal(Complex(5,3), Complex('5+3J'))
+ assert_equal(Complex(0,3), Complex('3I'))
+ assert_equal(Complex(0,3), Complex('3j'))
+ assert_equal(Complex(0,3), Complex('3J'))
+ assert_equal(Complex(0,1), Complex('I'))
+ assert_equal(Complex(0,1), Complex('J'))
+
+ assert_equal(Complex(5.0), Complex('5.0'))
+ assert_equal(Complex(-5.0), Complex('-5.0'))
+ assert_equal(Complex(5.0,3.0), Complex('5.0+3.0i'))
+ assert_equal(Complex(-5.0,3.0), Complex('-5.0+3.0i'))
+ assert_equal(Complex(5.0,-3.0), Complex('5.0-3.0i'))
+ assert_equal(Complex(-5.0,-3.0), Complex('-5.0-3.0i'))
+ assert_equal(Complex(0.0,3.0), Complex('3.0i'))
+ assert_equal(Complex(0.0,-3.0), Complex('-3.0i'))
+
+ assert_equal(Complex(5.0), Complex('5e0'))
+ assert_equal(Complex(-5.0), Complex('-5e0'))
+ assert_equal(Complex(5.0,3.0), Complex('5e0+3e0i'))
+ assert_equal(Complex(-5.0,3.0), Complex('-5e0+3e0i'))
+ assert_equal(Complex(5.0,-3.0), Complex('5e0-3e0i'))
+ assert_equal(Complex(-5.0,-3.0), Complex('-5e0-3e0i'))
+ assert_equal(Complex(0.0,3.0), Complex('3e0i'))
+ assert_equal(Complex(0.0,-3.0), Complex('-3e0i'))
+
+ assert_equal(Complex.polar(10,10), Complex('10@10'))
+ assert_equal(Complex.polar(-10,-10), Complex('-10@-10'))
+ assert_equal(Complex.polar(10.5,10.5), Complex('10.5@10.5'))
+ assert_equal(Complex.polar(-10.5,-10.5), Complex('-10.5@-10.5'))
+
+ assert_equal(Complex(0), '_'.to_c)
+ assert_equal(Complex(0), '_5'.to_c)
+ assert_equal(Complex(5), '5_'.to_c)
+ assert_equal(Complex(5), '5x'.to_c)
+ assert_equal(Complex(5), '5+_3i'.to_c)
+ assert_equal(Complex(5), '5+3_i'.to_c)
+ assert_equal(Complex(5,3), '5+3i_'.to_c)
+ assert_equal(Complex(5,3), '5+3ix'.to_c)
+ assert_raise(ArgumentError){ Complex('')}
+ assert_raise(ArgumentError){ Complex('_')}
+ assert_raise(ArgumentError){ Complex('_5')}
+ assert_raise(ArgumentError){ Complex('5_')}
+ assert_raise(ArgumentError){ Complex('5x')}
+ assert_raise(ArgumentError){ Complex('5+_3i')}
+ assert_raise(ArgumentError){ Complex('5+3_i')}
+ assert_raise(ArgumentError){ Complex('5+3i_')}
+ assert_raise(ArgumentError){ Complex('5+3ix')}
+
+ if defined?(Rational) && defined?(''.to_r)
+ assert_equal(Complex(Rational(1,5)), '1/5'.to_c)
+ assert_equal(Complex(Rational(-1,5)), '-1/5'.to_c)
+ assert_equal(Complex(Rational(1,5),3), '1/5+3i'.to_c)
+ assert_equal(Complex(Rational(1,5),-3), '1/5-3i'.to_c)
+ assert_equal(Complex(Rational(-1,5),3), '-1/5+3i'.to_c)
+ assert_equal(Complex(Rational(-1,5),-3), '-1/5-3i'.to_c)
+ assert_equal(Complex(Rational(1,5),Rational(3,2)), '1/5+3/2i'.to_c)
+ assert_equal(Complex(Rational(1,5),Rational(-3,2)), '1/5-3/2i'.to_c)
+ assert_equal(Complex(Rational(-1,5),Rational(3,2)), '-1/5+3/2i'.to_c)
+ assert_equal(Complex(Rational(-1,5),Rational(-3,2)), '-1/5-3/2i'.to_c)
+ assert_equal(Complex(Rational(1,5),Rational(3,2)), '1/5+3/2i'.to_c)
+ assert_equal(Complex(Rational(1,5),Rational(-3,2)), '1/5-3/2i'.to_c)
+ assert_equal(Complex(Rational(-1,5),Rational(3,2)), '-1/5+3/2i'.to_c)
+ assert_equal(Complex(Rational(-1,5),Rational(-3,2)), '-1/5-3/2i'.to_c)
+ assert_equal(Complex.polar(Rational(1,5),Rational(3,2)), Complex('1/5@3/2'))
+ assert_equal(Complex.polar(Rational(-1,5),Rational(-3,2)), Complex('-1/5@-3/2'))
+ end
+
+ end
+
+ def test_respond
+ c = Complex(1,1)
+ assert_equal(false, c.respond_to?(:<))
+ assert_equal(false, c.respond_to?(:<=))
+ assert_equal(false, c.respond_to?(:<=>))
+ assert_equal(false, c.respond_to?(:>))
+ assert_equal(false, c.respond_to?(:>=))
+ assert_equal(false, c.respond_to?(:between?))
+# assert_equal(false, c.respond_to?(:div)) # ?
+ assert_equal(false, c.respond_to?(:divmod))
+ assert_equal(false, c.respond_to?(:floor))
+ assert_equal(false, c.respond_to?(:ceil))
+ assert_equal(false, c.respond_to?(:modulo))
+ assert_equal(false, c.respond_to?(:round))
+ assert_equal(false, c.respond_to?(:step))
+ assert_equal(false, c.respond_to?(:tunrcate))
+
+ assert_equal(false, c.respond_to?(:positive?))
+ assert_equal(false, c.respond_to?(:negative?))
+# assert_equal(false, c.respond_to?(:sign))
+
+ assert_equal(false, c.respond_to?(:quotient))
+ assert_equal(false, c.respond_to?(:quot))
+ assert_equal(false, c.respond_to?(:quotrem))
+
+ assert_equal(false, c.respond_to?(:gcd))
+ assert_equal(false, c.respond_to?(:lcm))
+ assert_equal(false, c.respond_to?(:gcdlcm))
+ end
+
+ def test_to_i
+ assert_equal(3, Complex(3).to_i)
+ assert_equal(3, Integer(Complex(3)))
+ assert_raise(RangeError){Complex(3,2).to_i}
+ assert_raise(RangeError){Integer(Complex(3,2))}
+ end
+
+ def test_to_f
+ assert_equal(3.0, Complex(3).to_f)
+ assert_equal(3.0, Float(Complex(3)))
+ assert_raise(RangeError){Complex(3,2).to_f}
+ assert_raise(RangeError){Float(Complex(3,2))}
+ end
+
+ def test_to_r
+ if defined?(Rational) && !Rational.instance_variable_get('@RCS_ID')
+ assert_equal(Rational(3), Complex(3).to_r)
+ assert_equal(Rational(3), Rational(Complex(3)))
+ assert_raise(RangeError){Complex(3,2).to_r}
+ assert_raise(RangeError){Rational(Complex(3,2))}
+ end
+ end
+
+ def test_to_c
+ c = nil.to_c
+ assert_equal([0,0] , [c.real, c.image])
+
+ c = 0.to_c
+ assert_equal([0,0] , [c.real, c.image])
+
+ c = 1.to_c
+ assert_equal([1,0] , [c.real, c.image])
+
+ c = 1.1.to_c
+ assert_equal([1.1, 0], [c.real, c.image])
+
+ if defined?(Rational)
+ c = Rational(1,2).to_c
+ assert_equal([Rational(1,2), 0], [c.real, c.image])
+ end
+
+ c = Complex(1,2).to_c
+ assert_equal([1, 2], [c.real, c.image])
+ end
+
+ def test_prec
+ assert_equal(nil, Complex < Precision)
+ end
+
+ def test_supp
+ assert_equal(true, 1.scalar?)
+ assert_equal(true, 1.1.scalar?)
+
+ assert_equal(1, 1.real)
+ assert_equal(0, 1.image)
+ assert_equal(0, 1.imag)
+
+ assert_equal(1.1, 1.1.real)
+ assert_equal(0, 1.1.image)
+ assert_equal(0, 1.1.imag)
+
+ assert_equal(0, 1.arg)
+ assert_equal(0, 1.angle)
+
+ assert_equal(0, 1.0.arg)
+ assert_equal(0, 1.0.angle)
+
+ assert_equal(Math::PI, -1.arg)
+ assert_equal(Math::PI, -1.angle)
+
+ assert_equal(Math::PI, -1.0.arg)
+ assert_equal(Math::PI, -1.0.angle)
+
+ assert_equal([1,0], 1.polar)
+ assert_equal([1, Math::PI], -1.polar)
+
+ assert_equal([1.0,0], 1.0.polar)
+ assert_equal([1.0, Math::PI], -1.0.polar)
+
+ assert_equal(1, 1.conjugate)
+ assert_equal(-1, -1.conjugate)
+ assert_equal(1, 1.conj)
+ assert_equal(-1, -1.conj)
+
+ assert_equal(1.1, 1.1.conjugate)
+ assert_equal(-1.1, -1.1.conjugate)
+ assert_equal(1.1, 1.1.conj)
+ assert_equal(-1.1, -1.1.conj)
+
+ assert_equal(1, 1.numerator)
+ assert_equal(9, 9.numerator)
+ assert_equal(1, 1.denominator)
+ assert_equal(1, 9.denominator)
+
+ if defined?(Rational) && !Rational.instance_variable_get('@RCS_ID')
+ assert_equal(1.0, 1.0.numerator)
+ assert_equal(9.0, 9.0.numerator)
+ assert_equal(1.0, 1.0.denominator)
+ assert_equal(1.0, 9.0.denominator)
+ end
+
+=begin
+ if defined?(Rational) && !Rational.instance_variable_get('@RCS_ID')
+ assert_equal(Rational(1,9), 9.reciprocal)
+ assert_equal(Rational(1,9), 9.0.reciprocal)
+ assert_equal(Rational(1,9), 9.inverse)
+ assert_equal(Rational(1,9), 9.0.inverse)
+ end
+=end
+
+ if defined?(Rational)
+ assert_equal(Rational(1,2), 1.quo(2))
+ assert_equal(Rational(5000000000), 10000000000.quo(2))
+ assert_equal(0.5, 1.0.quo(2))
+ assert_equal(Rational(1,4), Rational(1,2).quo(2))
+ assert_equal(Complex(Rational(1,2),Rational(1)), Complex(1,2).quo(2))
+ else
+ assert_equal(0.5, 1.quo(2))
+ assert_equal(5000000000.0, 10000000000.quo(2))
+ assert_equal(0.5, 1.0.quo(2))
+ assert_equal(Complex(0.5,1.0), Complex(1,2).quo(2))
+ end
+
+=begin
+ if defined?(Rational) && !Rational.instance_variable_get('@RCS_ID')
+ assert_equal(Rational(1,2), 1.rdiv(2))
+ assert_equal(Rational(5000000000), 10000000000.rdiv(2))
+ assert_equal(Rational(1,2), 1.0.rdiv(2))
+ assert_equal(Rational(1,4), Rational(1,2).rdiv(2))
+ assert_equal(Complex(Rational(1,2),Rational(1)), Complex(1,2).quo(2))
+ end
+=end
+
+ assert_equal(0.5, 1.fdiv(2))
+ assert_equal(5000000000.0, 10000000000.fdiv(2))
+ assert_equal(0.5, 1.0.fdiv(2))
+ if defined?(Rational)
+ assert_equal(0.25, Rational(1,2).fdiv(2))
+ end
+ assert_equal(Complex(0.5,1.0), Complex(1,2).quo(2))
+
+ unless $".grep(/(\A|\/)complex/).empty?
+ assert_equal(Complex(0,2), Math.sqrt(-4.0))
+# assert_equal(true, Math.sqrt(-4.0).inexact?)
+ assert_equal(Complex(0,2), Math.sqrt(-4))
+# assert_equal(true, Math.sqrt(-4).exact?)
+ if defined?(Rational)
+ assert_equal(Complex(0,2), Math.sqrt(Rational(-4)))
+# assert_equal(true, Math.sqrt(Rational(-4)).exact?)
+ end
+
+ assert_equal(Complex(0,3), Math.sqrt(-9.0))
+# assert_equal(true, Math.sqrt(-9.0).inexact?)
+ assert_equal(Complex(0,3), Math.sqrt(-9))
+# assert_equal(true, Math.sqrt(-9).exact?)
+ if defined?(Rational)
+ assert_equal(Complex(0,3), Math.sqrt(Rational(-9)))
+# assert_equal(true, Math.sqrt(Rational(-9)).exact?)
+ end
+
+ c = Math.sqrt(Complex(1, 2))
+ assert_in_delta(1.272, c.real, 0.001)
+ assert_in_delta(0.786, c.image, 0.001)
+
+ c = Math.sqrt(-9)
+ assert_in_delta(0.0, c.real, 0.001)
+ assert_in_delta(3.0, c.image, 0.001)
+
+ c = Math.exp(Complex(1, 2))
+ assert_in_delta(-1.131, c.real, 0.001)
+ assert_in_delta(2.471, c.image, 0.001)
+
+ c = Math.sin(Complex(1, 2))
+ assert_in_delta(3.165, c.real, 0.001)
+ assert_in_delta(1.959, c.image, 0.001)
+
+ c = Math.cos(Complex(1, 2))
+ assert_in_delta(2.032, c.real, 0.001)
+ assert_in_delta(-3.051, c.image, 0.001)
+
+ c = Math.tan(Complex(1, 2))
+ assert_in_delta(0.033, c.real, 0.001)
+ assert_in_delta(1.014, c.image, 0.001)
+
+ c = Math.sinh(Complex(1, 2))
+ assert_in_delta(-0.489, c.real, 0.001)
+ assert_in_delta(1.403, c.image, 0.001)
+
+ c = Math.cosh(Complex(1, 2))
+ assert_in_delta(-0.642, c.real, 0.001)
+ assert_in_delta(1.068, c.image, 0.001)
+
+ c = Math.tanh(Complex(1, 2))
+ assert_in_delta(1.166, c.real, 0.001)
+ assert_in_delta(-0.243, c.image, 0.001)
+
+ c = Math.log(Complex(1, 2))
+ assert_in_delta(0.804, c.real, 0.001)
+ assert_in_delta(1.107, c.image, 0.001)
+
+ c = Math.log(Complex(1, 2), Math::E)
+ assert_in_delta(0.804, c.real, 0.001)
+ assert_in_delta(1.107, c.image, 0.001)
+
+ c = Math.log(-1)
+ assert_in_delta(0.0, c.real, 0.001)
+ assert_in_delta(Math::PI, c.image, 0.001)
+
+ c = Math.log(8, 2)
+ assert_in_delta(3.0, c.real, 0.001)
+ assert_in_delta(0.0, c.image, 0.001)
+
+ c = Math.log(-8, -2)
+ assert_in_delta(1.092, c.real, 0.001)
+ assert_in_delta(-0.420, c.image, 0.001)
+
+ c = Math.log10(Complex(1, 2))
+ assert_in_delta(0.349, c.real, 0.001)
+ assert_in_delta(0.480, c.image, 0.001)
+
+ c = Math.asin(Complex(1, 2))
+ assert_in_delta(0.427, c.real, 0.001)
+ assert_in_delta(1.528, c.image, 0.001)
+
+ c = Math.acos(Complex(1, 2))
+ assert_in_delta(1.143, c.real, 0.001)
+ assert_in_delta(-1.528, c.image, 0.001)
+
+ c = Math.atan(Complex(1, 2))
+ assert_in_delta(1.338, c.real, 0.001)
+ assert_in_delta(0.402, c.image, 0.001)
+
+ c = Math.atan2(Complex(1, 2), 1)
+ assert_in_delta(1.338, c.real, 0.001)
+ assert_in_delta(0.402, c.image, 0.001)
+
+ c = Math.asinh(Complex(1, 2))
+ assert_in_delta(1.469, c.real, 0.001)
+ assert_in_delta(1.063, c.image, 0.001)
+
+ c = Math.acosh(Complex(1, 2))
+ assert_in_delta(1.528, c.real, 0.001)
+ assert_in_delta(1.143, c.image, 0.001)
+
+ c = Math.atanh(Complex(1, 2))
+ assert_in_delta(0.173, c.real, 0.001)
+ assert_in_delta(1.178, c.image, 0.001)
+ end
+
+ end
+
+=begin
+ def test_canonicalize
+ f = defined?(Complex::Unify)
+ Complex.const_set(:Unify, true) unless f
+
+ assert_same(1, Complex.instance_eval { new(1, 0) })
+ assert_not_same(1.0, Complex.instance_eval { new(1.0, 0) })
+ assert_equal(Complex(1.0, 0), Complex.instance_eval { new(1.0, 0) })
+
+ Complex.instance_eval { remove_const(:Unify) } unless f
+ end
+
+ def test_polar
+ c = Complex.polar(2, 2)
+ assert_in_delta(2*Math.cos(2), c.real , 0.001)
+ assert_in_delta(2*Math.sin(2), c.image, 0.001)
+
+ c = Complex.polar(1, Complex(0, 1))
+ assert_in_delta(1/Math::E, c.real , 0.001)
+ assert_in_delta( 0, c.image, 0.001)
+ end
+
+ def test_generic?
+ assert_equal(true, Complex.generic?(1))
+ assert_equal(true, Complex.generic?(2**100))
+ assert_equal(true, Complex.generic?(Rational(1, 2)))
+ assert_equal(true, Complex.generic?(1.0))
+ assert_equal(false, Complex.generic?(Complex(1, 1)))
+ end
+
+ def test_new_bang2
+ o = Object.new
+ def o.to_i; 1; end
+ assert_equal(Complex(1, 1), Complex.instance_eval { new!(o, o) })
+ end
+
+ def test_denominator
+ f = defined?(Complex::Unify)
+ unify_val = f && Complex::Unify
+ Complex.instance_eval { remove_const(:Unify) } if f
+
+ dummy_rational = Class.new(Rational)
+ o1 = dummy_rational.instance_eval { new(1, 1) }
+ o2 = dummy_rational.instance_eval { new(1, 1) }
+ d1 = d2 = nil
+ class << o1; self; end.instance_eval { define_method(:denominator) { d1 } rescue nil }
+ class << o2; self; end.instance_eval { define_method(:denominator) { d2 } rescue nil }
+ # o1.denominator returns d1 and o1.denominator returns d2
+
+ c = Complex(o1, o2)
+
+ d1 = d2 = 0
+ assert_equal(0, c.denominator)
+
+ d1 = d2 = -1
+ assert_equal(1, c.denominator)
+
+ d1 = d2 = 256
+ assert_equal(256, c.denominator)
+
+ d1, d2 = 512, 256
+ assert_equal(512, c.denominator)
+
+ d1, d2 = 256, 512
+ assert_equal(512, c.denominator)
+
+ d1, d2 = -(2**100), -(3**100)
+ assert_equal(6**100, c.denominator)
+
+ d1, d2 = 1, 2**100
+ assert_equal(2**100, c.denominator)
+
+ Complex.const_set(:Unify, unify_val) if f
+ end
+
+ def test_abs
+ b = 2**100
+ def b.*(x); self; end rescue nil
+ def b.+(x); -1; end rescue nil
+ assert_equal(Complex(0, 1), Complex(b, 1).abs)
+
+ def b.+(x); Complex(0, 1); end rescue nil
+ c = Complex(b, 1).abs
+ assert_in_delta(1/Math.sqrt(2), c.real , 0.001)
+ assert_in_delta(1/Math.sqrt(2), c.image, 0.001)
+
+ def b.+(x); Complex(0, -1); end rescue nil
+ c = Complex(b, 1).abs
+ assert_in_delta( 1/Math.sqrt(2), c.real , 0.001)
+ assert_in_delta(-1/Math.sqrt(2), c.image, 0.001)
+
+ inf = 1.0/0.0
+ nan = inf/inf
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Complex(1, nan).abs }
+ end
+
+ def test_coerce
+ c = Complex(6, 3)
+ assert_equal(Complex(42, 0), c.coerce(42).first)
+ assert_raise(TypeError) { c.coerce(Object.new) }
+
+ o = Object.new
+ def o.coerce(x); [x.real, x.image]; end
+ assert_equal(9, c + o)
+ assert_equal(3, c - o)
+ assert_equal(18, c * o)
+ assert_equal(2, c / o)
+ assert_equal(216, c ** o)
+ end
+
+ def test_add2
+ assert_equal(Complex(2**100, 1), Complex(0, 1) + 2**100)
+ end
+
+ def test_mul2
+ assert_equal(Complex(0.0, 0.0), Complex(1.0, 1.0) * 0)
+ assert_equal(Complex(0, 0), Complex(0, 0) * (2**100))
+ end
+
+ def test_expt2
+ assert_equal(Complex(1, 0), Complex(2, 2) ** 0)
+ assert_equal(Complex(0, -1), Complex(0, 1) ** (2**100-1))
+ assert_equal(Complex(1, 0), Complex(1, 0) ** Rational(1, 2**100))
+ end
+=end
+
+ def test_fixed_bug
+ if defined?(Rational) && !Rational.instance_variable_get('@RCS_ID')
+ assert_equal(Complex(1), 1 ** Complex(1))
+ end
+ assert_equal('-1.0-0.0i', Complex(-1.0, -0.0).to_s)
+ end
+
+ def test_known_bug
+ end
+
+end
diff --git a/trunk/test/ruby/test_condition.rb b/trunk/test/ruby/test_condition.rb
new file mode 100644
index 0000000000..ba2e0688f3
--- /dev/null
+++ b/trunk/test/ruby/test_condition.rb
@@ -0,0 +1,16 @@
+require 'test/unit'
+
+class TestCondition < Test::Unit::TestCase
+
+ # [should] first test to see if we can run the tests.
+
+ def test_condition
+ $x = '0';
+
+ $x == $x && assert(true)
+ $x != $x && assert(false)
+ $x == $x || assert(false)
+ $x != $x || assert(true)
+
+ end
+end
diff --git a/trunk/test/ruby/test_const.rb b/trunk/test/ruby/test_const.rb
new file mode 100644
index 0000000000..3708a5a0ca
--- /dev/null
+++ b/trunk/test/ruby/test_const.rb
@@ -0,0 +1,48 @@
+require 'test/unit'
+
+class TestConst < Test::Unit::TestCase
+ TEST1 = 1
+ TEST2 = 2
+
+ module Const
+ TEST3 = 3
+ TEST4 = 4
+ end
+
+ module Const2
+ TEST3 = 6
+ TEST4 = 8
+ end
+
+ def test_const
+ assert defined?(TEST1)
+ assert_equal 1, TEST1
+ assert defined?(TEST2)
+ assert_equal 2, TEST2
+
+ self.class.class_eval {
+ include Const
+ }
+ assert defined?(TEST1)
+ assert_equal 1, TEST1
+ assert defined?(TEST2)
+ assert_equal 2, TEST2
+ assert defined?(TEST3)
+ assert_equal 3, TEST3
+ assert defined?(TEST4)
+ assert_equal 4, TEST4
+
+ self.class.class_eval {
+ include Const2
+ }
+ STDERR.print "intentionally redefines TEST3, TEST4\n" if $VERBOSE
+ assert defined?(TEST1)
+ assert_equal 1, TEST1
+ assert defined?(TEST2)
+ assert_equal 2, TEST2
+ assert defined?(TEST3)
+ assert_equal 6, TEST3
+ assert defined?(TEST4)
+ assert_equal 8, TEST4
+ end
+end
diff --git a/trunk/test/ruby/test_continuation.rb b/trunk/test/ruby/test_continuation.rb
new file mode 100644
index 0000000000..c719db8c35
--- /dev/null
+++ b/trunk/test/ruby/test_continuation.rb
@@ -0,0 +1,81 @@
+require 'test/unit'
+require 'continuation'
+require 'fiber'
+require_relative 'envutil'
+
+class TestContinuation < Test::Unit::TestCase
+ def test_create
+ assert_equal(:ok, callcc{:ok})
+ assert_equal(:ok, callcc{|c| c.call :ok})
+ end
+
+ def test_call
+ assert_equal(:ok, callcc{|c| c.call :ok})
+
+ ary = []
+ ary << callcc{|c|
+ @cont = c
+ :a
+ }
+ @cont.call :b if ary.length < 3
+ assert_equal([:a, :b, :b], ary)
+ end
+
+ def test_check_localvars
+ vv = 0
+ @v = 0
+ @ary = []
+ [1, 2, 3].each{|i|
+ callcc {|k| @k = k}
+ @v += 1
+ vv += 1
+ }
+ @ary << [vv, @v]
+ @k.call if @v < 10
+ assert_equal((3..10).map{|e| [e, e]}, @ary)
+ end
+
+ def test_error
+ cont = callcc{|c| c}
+ assert_raise(RuntimeError){
+ Thread.new{cont.call}.join
+ }
+ assert_raise(LocalJumpError){
+ callcc
+ }
+ assert_raise(RuntimeError){
+ c = nil
+ Fiber.new do
+ callcc {|c2| c = c2 }
+ end.resume
+ c.call
+ }
+ end
+
+ def test_ary_flatten
+ assert_normal_exit %q{
+ require 'continuation'
+ n = 0
+ o = Object.new
+ def o.to_ary() callcc {|k| $k = k; [1,2,3]} end
+ [10,20,o,30,o,40].flatten.inspect
+ n += 1
+ $k.call if n < 100
+ }, '[ruby-dev:34798]'
+ end
+
+ def test_marshal_dump
+ assert_normal_exit %q{
+ require 'continuation'
+ n = 0
+ o = Object.new
+ def o.marshal_dump() callcc {|k| $k = k }; "fofof" end
+ a = [1,2,3,o,4,5,6]
+ Marshal.dump(a).inspect
+ n += 1
+ $k.call if n < 100
+ }, '[ruby-dev:34802]'
+ end
+
+end
+
diff --git a/trunk/test/ruby/test_defined.rb b/trunk/test/ruby/test_defined.rb
new file mode 100644
index 0000000000..bfcd7fb667
--- /dev/null
+++ b/trunk/test/ruby/test_defined.rb
@@ -0,0 +1,81 @@
+require 'test/unit'
+
+class TestDefined < Test::Unit::TestCase
+ class Foo
+ def foo
+ p :foo
+ end
+ protected :foo
+ def bar(f)
+ yield(defined?(self.foo))
+ yield(defined?(f.foo))
+ end
+ def baz(f)
+ end
+ end
+
+ def defined_test
+ return !defined?(yield)
+ end
+
+ def test_defined
+ $x = nil
+
+ assert(defined?($x)) # global variable
+ assert_equal('global-variable', defined?($x))# returns description
+
+ assert_nil(defined?(foo)) # undefined
+ foo=5
+ assert(defined?(foo)) # local variable
+
+ assert(defined?(Array)) # constant
+ assert(defined?(::Array)) # toplevel constant
+ assert(defined?(File::Constants)) # nested constant
+ assert(defined?(Object.new)) # method
+ assert(!defined?(Object.print)) # private method
+ assert(defined?(1 == 2)) # operator expression
+
+ f = Foo.new
+ assert_nil(defined?(f.foo)) # protected method
+ f.bar(f) { |v| assert(v) }
+ assert_nil(defined?(f.quux)) # undefined method
+ assert_nil(defined?(f.baz(x))) # undefined argument
+ x = 0
+ assert(defined?(f.baz(x)))
+ assert_nil(defined?(f.quux(x)))
+ assert(defined?(print(x)))
+ assert_nil(defined?(quux(x)))
+
+ assert(defined_test) # not iterator
+ assert(!defined_test{}) # called as iterator
+
+ /a/ =~ ''
+ assert_equal nil, defined?($&)
+ assert_equal nil, defined?($`)
+ assert_equal nil, defined?($')
+ assert_equal nil, defined?($+)
+ assert_equal nil, defined?($1)
+ assert_equal nil, defined?($2)
+ /a/ =~ 'a'
+ assert_equal 'global-variable', defined?($&)
+ assert_equal 'global-variable', defined?($`)
+ assert_equal 'global-variable', defined?($')
+ assert_equal nil, defined?($+)
+ assert_equal nil, defined?($1)
+ assert_equal nil, defined?($2)
+ /(a)/ =~ 'a'
+ assert_equal 'global-variable', defined?($&)
+ assert_equal 'global-variable', defined?($`)
+ assert_equal 'global-variable', defined?($')
+ assert_equal 'global-variable', defined?($+)
+ assert_equal 'global-variable', defined?($1)
+ assert_equal nil, defined?($2)
+ /(a)b/ =~ 'ab'
+ assert_equal 'global-variable', defined?($&)
+ assert_equal 'global-variable', defined?($`)
+ assert_equal 'global-variable', defined?($')
+ assert_equal 'global-variable', defined?($+)
+ assert_equal 'global-variable', defined?($1)
+ assert_equal nil, defined?($2)
+ end
+end
diff --git a/trunk/test/ruby/test_dir.rb b/trunk/test/ruby/test_dir.rb
new file mode 100644
index 0000000000..0ea28f55d8
--- /dev/null
+++ b/trunk/test/ruby/test_dir.rb
@@ -0,0 +1,170 @@
+require 'test/unit'
+
+require 'tmpdir'
+require 'fileutils'
+require 'pathname'
+
+class TestDir < Test::Unit::TestCase
+
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ @root = Pathname.new(Dir.mktmpdir('__test_dir__')).realpath.to_s
+ @nodir = File.join(@root, "dummy")
+ for i in ?a..?z
+ if i.ord % 2 == 0
+ FileUtils.touch(File.join(@root, i))
+ else
+ FileUtils.mkdir(File.join(@root, i))
+ end
+ end
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ FileUtils.remove_entry_secure @root if File.directory?(@root)
+ end
+
+ def test_seek
+ dir = Dir.open(@root)
+ begin
+ cache = []
+ loop do
+ pos = dir.tell
+ break unless name = dir.read
+ cache << [pos, name]
+ end
+ for x,y in cache.sort_by {|z| z[0] % 3 } # shuffle
+ dir.seek(x)
+ assert_equal(y, dir.read)
+ end
+ ensure
+ dir.close
+ end
+ end
+
+ def test_JVN_13947696
+ b = lambda {
+ d = Dir.open('.')
+ $SAFE = 4
+ d.close
+ }
+ assert_raise(SecurityError) { b.call }
+ end
+
+ def test_nodir
+ assert_raise(Errno::ENOENT) { Dir.open(@nodir) }
+ end
+
+ def test_inspect
+ d = Dir.open(@root)
+ assert_match(/^#<Dir:#{ Regexp.quote(@root) }>$/, d.inspect)
+ assert_match(/^#<Dir:.*>$/, Dir.allocate.inspect)
+ ensure
+ d.close
+ end
+
+ def test_path
+ d = Dir.open(@root)
+ assert_equal(@root, d.path)
+ assert_nil(Dir.allocate.path)
+ ensure
+ d.close
+ end
+
+ def test_set_pos
+ d = Dir.open(@root)
+ loop do
+ i = d.pos
+ break unless x = d.read
+ d.pos = i
+ assert_equal(x, d.read)
+ end
+ ensure
+ d.close
+ end
+
+ def test_rewind
+ d = Dir.open(@root)
+ a = (0..5).map { d.read }
+ d.rewind
+ b = (0..5).map { d.read }
+ assert_equal(a, b)
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ d.rewind
+ end.join
+ end
+ ensure
+ d.close
+ end
+
+ def test_chdir
+ @pwd = Dir.pwd
+ @env_home = ENV["HOME"]
+ @env_logdir = ENV["LOGDIR"]
+ ENV.delete("HOME")
+ ENV.delete("LOGDIR")
+
+ assert_raise(Errno::ENOENT) { Dir.chdir(@nodir) }
+ assert_raise(ArgumentError) { Dir.chdir }
+ ENV["HOME"] = @pwd
+ Dir.chdir do
+ assert_equal(@pwd, Dir.pwd)
+ Dir.chdir(@root)
+ assert_equal(@root, Dir.pwd)
+ end
+
+ ensure
+ begin
+ Dir.chdir(@pwd)
+ rescue
+ abort("cannot return the original directory: #{ @pwd }")
+ end
+ if @env_home
+ ENV["HOME"] = @env_home
+ else
+ ENV.delete("HOME")
+ end
+ if @env_logdir
+ ENV["LOGDIR"] = @env_logdir
+ else
+ ENV.delete("LOGDIR")
+ end
+ end
+
+ def test_chroot_nodir
+ assert_raise(NotImplementedError, Errno::ENOENT, Errno::EPERM
+ ) { Dir.chroot(File.join(@nodir, "")) }
+ end
+
+ def test_close
+ d = Dir.open(@root)
+ d.close
+ assert_raise(IOError) { d.read }
+ end
+
+ def test_glob
+ assert_equal((%w(. ..) + (?a..?z).to_a).map{|f| File.join(@root, f) },
+ Dir.glob(File.join(@root, "*"), File::FNM_DOTMATCH).sort)
+ assert_equal([@root] + (?a..?z).map {|f| File.join(@root, f) }.sort,
+ Dir.glob([@root, File.join(@root, "*")]).sort)
+ assert_equal([@root] + (?a..?z).map {|f| File.join(@root, f) }.sort,
+ Dir.glob(@root + "\0\0\0" + File.join(@root, "*")).sort)
+
+ assert_equal((?a..?z).step(2).map {|f| File.join(File.join(@root, f), "") }.sort,
+ Dir.glob(File.join(@root, "*/")).sort)
+
+ FileUtils.touch(File.join(@root, "{}"))
+ assert_equal(%w({} a).map{|f| File.join(@root, f) },
+ Dir.glob(File.join(@root, '{\{\},a}')))
+ assert_equal([], Dir.glob(File.join(@root, '[')))
+ assert_equal([], Dir.glob(File.join(@root, '[a-\\')))
+ end
+
+ def test_foreach
+ assert_equal(Dir.foreach(@root).to_a.sort, %w(. ..) + (?a..?z).to_a)
+ end
+
+end
diff --git a/trunk/test/ruby/test_econv.rb b/trunk/test/ruby/test_econv.rb
new file mode 100644
index 0000000000..32ac4ca935
--- /dev/null
+++ b/trunk/test/ruby/test_econv.rb
@@ -0,0 +1,524 @@
+require 'test/unit'
+
+class TestEncodingConverter < Test::Unit::TestCase
+ def check_ec(edst, esrc, eres, dst, src, ec, off, len, flags=0)
+ res = ec.primitive_convert(src, dst, off, len, flags)
+ assert_equal([edst.dup.force_encoding("ASCII-8BIT"),
+ esrc.dup.force_encoding("ASCII-8BIT"),
+ eres],
+ [dst.dup.force_encoding("ASCII-8BIT"),
+ src.dup.force_encoding("ASCII-8BIT"),
+ res])
+ end
+
+ def assert_econv(converted, eres, obuf_bytesize, ec, consumed, rest, flags=0)
+ ec = Encoding::Converter.new(*ec) if Array === ec
+ i = consumed + rest
+ o = ""
+ ret = ec.primitive_convert(i, o, 0, obuf_bytesize, flags)
+ assert_equal([converted, eres, rest],
+ [o, ret, i])
+ end
+
+ def assert_errinfo(e_res, e_enc1, e_enc2, e_error_bytes, e_readagain_bytes, e_partial_input, ec)
+ assert_equal([e_res, e_enc1, e_enc2,
+ e_error_bytes && e_error_bytes.dup.force_encoding("ASCII-8BIT"),
+ e_readagain_bytes && e_readagain_bytes.dup.force_encoding("ASCII-8BIT"),
+ e_partial_input],
+ ec.primitive_errinfo)
+ end
+
+ def test_new
+ assert_kind_of(Encoding::Converter, Encoding::Converter.new("UTF-8", "EUC-JP"))
+ assert_kind_of(Encoding::Converter, Encoding::Converter.new(Encoding::UTF_8, Encoding::EUC_JP))
+ end
+
+ def test_new_fail
+ name1 = "encoding-which-is-not-exist-1"
+ name2 = "encoding-which-is-not-exist-2"
+
+ assert_raise(Encoding::NoConverter) {
+ Encoding::Converter.new(name1, name2)
+ }
+
+ encoding_list = Encoding.list.map {|e| e.name }
+ assert(!encoding_list.include?(name1))
+ assert(!encoding_list.include?(name2))
+ end
+
+ def test_get_encoding
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ assert_equal(Encoding::UTF_8, ec.source_encoding)
+ assert_equal(Encoding::EUC_JP, ec.destination_encoding)
+ end
+
+ def test_result_encoding
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ dst = "".force_encoding("ASCII-8BIT")
+ assert_equal(Encoding::ASCII_8BIT, dst.encoding)
+ ec.primitive_convert("\u{3042}", dst, nil, 10)
+ assert_equal(Encoding::EUC_JP, dst.encoding)
+ end
+
+ def test_output_region
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ ec.primitive_convert(src="a", dst="b", nil, 1, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("ba", dst)
+ ec.primitive_convert(src="a", dst="b", 0, 1, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("a", dst)
+ ec.primitive_convert(src="a", dst="b", 1, 1, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("ba", dst)
+ assert_raise(ArgumentError) {
+ ec.primitive_convert(src="a", dst="b", 2, 1, Encoding::Converter::PARTIAL_INPUT)
+ }
+ assert_raise(ArgumentError) {
+ ec.primitive_convert(src="a", dst="b", -1, 1, Encoding::Converter::PARTIAL_INPUT)
+ }
+ assert_raise(ArgumentError) {
+ ec.primitive_convert(src="a", dst="b", 1, -1, Encoding::Converter::PARTIAL_INPUT)
+ }
+ end
+
+ def test_partial_input
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ ret = ec.primitive_convert(src="", dst="", nil, 10, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal(:source_buffer_empty, ret)
+ ret = ec.primitive_convert(src="", dst="", nil, 10)
+ assert_equal(:finished, ret)
+ end
+
+ def test_accumulate_dst1
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ a = ["", "abc\u{3042}def", ec, nil, 1]
+ check_ec("a", "c\u{3042}def", :destination_buffer_full, *a)
+ check_ec("ab", "\u{3042}def", :destination_buffer_full, *a)
+ check_ec("abc", "def", :destination_buffer_full, *a)
+ check_ec("abc\xA4", "def", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2", "ef", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2d", "f", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2de", "", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2def", "", :finished, *a)
+ end
+
+ def test_accumulate_dst2
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ a = ["", "abc\u{3042}def", ec, nil, 2]
+ check_ec("ab", "\u{3042}def", :destination_buffer_full, *a)
+ check_ec("abc\xA4", "def", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2d", "f", :destination_buffer_full, *a)
+ check_ec("abc\xA4\xA2def", "", :finished, *a)
+ end
+
+ def test_eucjp_to_utf8
+ assert_econv("", :finished, 100, ["UTF-8", "EUC-JP"], "", "")
+ assert_econv("a", :finished, 100, ["UTF-8", "EUC-JP"], "a", "")
+ end
+
+ def test_iso2022jp
+ assert_econv("", :finished, 100, ["Shift_JIS", "ISO-2022-JP"], "", "")
+ end
+
+ def test_iso2022jp_encode
+ ec = Encoding::Converter.new("EUC-JP", "ISO-2022-JP")
+ a = ["", src="", ec, nil, 50, Encoding::Converter::PARTIAL_INPUT]
+ src << "a"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\xA2"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\xA4"; check_ec("a\e$B\"$", "", :source_buffer_empty, *a)
+ src << "\xA1"; check_ec("a\e$B\"$", "", :source_buffer_empty, *a)
+ src << "\xA2"; check_ec("a\e$B\"$!\"", "", :source_buffer_empty, *a)
+ src << "b"; check_ec("a\e$B\"$!\"\e(Bb", "", :source_buffer_empty, *a)
+ src << "\xA2\xA6"; check_ec("a\e$B\"$!\"\e(Bb\e$B\"&", "", :source_buffer_empty, *a)
+ a[-1] = 0; check_ec("a\e$B\"$!\"\e(Bb\e$B\"&\e(B", "", :finished, *a)
+ end
+
+ def test_iso2022jp_decode
+ ec = Encoding::Converter.new("ISO-2022-JP", "EUC-JP")
+ a = ["", src="", ec, nil, 50, Encoding::Converter::PARTIAL_INPUT]
+ src << "a"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\e"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "$"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "B"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\x21"; check_ec("a", "", :source_buffer_empty, *a)
+ src << "\x22"; check_ec("a\xA1\xA2", "", :source_buffer_empty, *a)
+ src << "\n"; check_ec("a\xA1\xA2", "", :invalid_byte_sequence, *a)
+ src << "\x23"; check_ec("a\xA1\xA2", "", :source_buffer_empty, *a)
+ src << "\x24"; check_ec("a\xA1\xA2\xA3\xA4", "", :source_buffer_empty, *a)
+ src << "\e"; check_ec("a\xA1\xA2\xA3\xA4", "", :source_buffer_empty, *a)
+ src << "("; check_ec("a\xA1\xA2\xA3\xA4", "", :source_buffer_empty, *a)
+ src << "B"; check_ec("a\xA1\xA2\xA3\xA4", "", :source_buffer_empty, *a)
+ src << "c"; check_ec("a\xA1\xA2\xA3\xA4c", "", :source_buffer_empty, *a)
+ src << "\n"; check_ec("a\xA1\xA2\xA3\xA4c\n","", :source_buffer_empty, *a)
+ end
+
+ def test_invalid
+ assert_econv("", :invalid_byte_sequence, 100, ["UTF-8", "EUC-JP"], "\x80", "")
+ assert_econv("a", :invalid_byte_sequence, 100, ["UTF-8", "EUC-JP"], "a\x80", "")
+ assert_econv("a", :invalid_byte_sequence, 100, ["UTF-8", "EUC-JP"], "a\x80", "\x80")
+ assert_econv("abc", :invalid_byte_sequence, 100, ["UTF-8", "EUC-JP"], "abc\xFF", "def")
+ assert_econv("abc", :invalid_byte_sequence, 100, ["Shift_JIS", "EUC-JP"], "abc\xFF", "def")
+ assert_econv("abc", :invalid_byte_sequence, 100, ["ISO-2022-JP", "EUC-JP"], "abc\xFF", "def")
+ end
+
+ def test_invalid2
+ ec = Encoding::Converter.new("Shift_JIS", "EUC-JP")
+ a = ["", "abc\xFFdef", ec, nil, 1]
+ check_ec("a", "c\xFFdef", :destination_buffer_full, *a)
+ check_ec("ab", "\xFFdef", :destination_buffer_full, *a)
+ check_ec("abc", "def", :invalid_byte_sequence, *a)
+ check_ec("abcd", "f", :destination_buffer_full, *a)
+ check_ec("abcde", "", :destination_buffer_full, *a)
+ check_ec("abcdef", "", :finished, *a)
+ end
+
+ def test_invalid3
+ ec = Encoding::Converter.new("Shift_JIS", "EUC-JP")
+ a = ["", "abc\xFFdef", ec, nil, 10]
+ check_ec("abc", "def", :invalid_byte_sequence, *a)
+ check_ec("abcdef", "", :finished, *a)
+ end
+
+ def test_invalid4
+ ec = Encoding::Converter.new("Shift_JIS", "EUC-JP")
+ a = ["", "abc\xFFdef", ec, nil, 10, Encoding::Converter::OUTPUT_FOLLOWED_BY_INPUT]
+ check_ec("a", "bc\xFFdef", :output_followed_by_input, *a)
+ check_ec("ab", "c\xFFdef", :output_followed_by_input, *a)
+ check_ec("abc", "\xFFdef", :output_followed_by_input, *a)
+ check_ec("abc", "def", :invalid_byte_sequence, *a)
+ check_ec("abcd", "ef", :output_followed_by_input, *a)
+ check_ec("abcde", "f", :output_followed_by_input, *a)
+ check_ec("abcdef", "", :output_followed_by_input, *a)
+ check_ec("abcdef", "", :finished, *a)
+ end
+
+ def test_invalid_utf16le
+ ec = Encoding::Converter.new("UTF-16LE", "UTF-8")
+ a = ["", src="", ec, nil, 50, Encoding::Converter::PARTIAL_INPUT]
+ src << "A"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x01"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x02"; check_ec("A", "", :invalid_byte_sequence, *a)
+ src << "\x03"; check_ec("A\u{0201}", "", :source_buffer_empty, *a)
+ src << "\x04"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A\u{0201}\u{0403}", "", :invalid_byte_sequence, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xdc"; check_ec("A\u{0201}\u{0403}\u{10000}", "", :source_buffer_empty, *a)
+ end
+
+ def test_invalid_utf16be
+ ec = Encoding::Converter.new("UTF-16BE", "UTF-8")
+ a = ["", src="", ec, nil, 50, Encoding::Converter::PARTIAL_INPUT]
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "A"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x02"; check_ec("A", "", :invalid_byte_sequence, *a)
+ src << "\x01"; check_ec("A\u{0201}", "", :source_buffer_empty, *a)
+ src << "\x04"; check_ec("A\u{0201}", "", :source_buffer_empty, *a)
+ src << "\x03"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xd8"; check_ec("A\u{0201}\u{0403}", "", :invalid_byte_sequence, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\xdc"; check_ec("A\u{0201}\u{0403}", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A\u{0201}\u{0403}\u{10000}", "", :source_buffer_empty, *a)
+ end
+
+ def test_invalid_utf32be
+ ec = Encoding::Converter.new("UTF-32BE", "UTF-8")
+ a = ["", src="", ec, nil, 50, Encoding::Converter::PARTIAL_INPUT]
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "A"; check_ec("A", "", :source_buffer_empty, *a)
+
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\xdc"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :invalid_byte_sequence, *a)
+
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "B"; check_ec("AB", "", :source_buffer_empty, *a)
+
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "C"; check_ec("ABC", "", :source_buffer_empty, *a)
+ end
+
+ def test_invalid_utf32le
+ ec = Encoding::Converter.new("UTF-32LE", "UTF-8")
+ a = ["", src="", ec, nil, 50, Encoding::Converter::PARTIAL_INPUT]
+ src << "A"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\xdc"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :invalid_byte_sequence, *a)
+
+ src << "B"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("A", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+
+ src << "C"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("AB", "", :source_buffer_empty, *a)
+ src << "\x00"; check_ec("ABC", "", :source_buffer_empty, *a)
+ end
+
+ def test_errors
+ ec = Encoding::Converter.new("UTF-16BE", "EUC-JP")
+ a = ["", "\xFF\xFE\x00A\xDC\x00\x00B", ec, nil, 10]
+ check_ec("", "\x00A\xDC\x00\x00B", :undefined_conversion, *a)
+ check_ec("A", "\x00B", :invalid_byte_sequence, *a) # \xDC\x00 is invalid as UTF-16BE
+ check_ec("AB", "", :finished, *a)
+ end
+
+ def test_errors2
+ ec = Encoding::Converter.new("UTF-16BE", "EUC-JP")
+ a = ["", "\xFF\xFE\x00A\xDC\x00\x00B", ec, nil, 10, Encoding::Converter::OUTPUT_FOLLOWED_BY_INPUT]
+ check_ec("", "\x00A\xDC\x00\x00B", :undefined_conversion, *a)
+ check_ec("A", "\xDC\x00\x00B", :output_followed_by_input, *a)
+ check_ec("A", "\x00B", :invalid_byte_sequence, *a)
+ check_ec("AB", "", :output_followed_by_input, *a)
+ check_ec("AB", "", :finished, *a)
+ end
+
+ def test_universal_newline
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", Encoding::Converter::UNIVERSAL_NEWLINE_DECODER)
+ a = ["", src="", ec, nil, 50, Encoding::Converter::PARTIAL_INPUT]
+ src << "abc\r\ndef"; check_ec("abc\ndef", "", :source_buffer_empty, *a)
+ src << "ghi\njkl"; check_ec("abc\ndefghi\njkl", "", :source_buffer_empty, *a)
+ src << "mno\rpqr"; check_ec("abc\ndefghi\njklmno\npqr", "", :source_buffer_empty, *a)
+ src << "stu\r"; check_ec("abc\ndefghi\njklmno\npqrstu\n", "", :source_buffer_empty, *a)
+ src << "\nvwx"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx", "", :source_buffer_empty, *a)
+ src << "\nyz"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx\nyz", "", :source_buffer_empty, *a)
+ end
+
+ def test_universal_newline2
+ ec = Encoding::Converter.new("", "", Encoding::Converter::UNIVERSAL_NEWLINE_DECODER)
+ a = ["", src="", ec, nil, 50, Encoding::Converter::PARTIAL_INPUT]
+ src << "abc\r\ndef"; check_ec("abc\ndef", "", :source_buffer_empty, *a)
+ src << "ghi\njkl"; check_ec("abc\ndefghi\njkl", "", :source_buffer_empty, *a)
+ src << "mno\rpqr"; check_ec("abc\ndefghi\njklmno\npqr", "", :source_buffer_empty, *a)
+ src << "stu\r"; check_ec("abc\ndefghi\njklmno\npqrstu\n", "", :source_buffer_empty, *a)
+ src << "\nvwx"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx", "", :source_buffer_empty, *a)
+ src << "\nyz"; check_ec("abc\ndefghi\njklmno\npqrstu\nvwx\nyz", "", :source_buffer_empty, *a)
+ end
+
+ def test_crlf_newline
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", Encoding::Converter::CRLF_NEWLINE_ENCODER)
+ assert_econv("abc\r\ndef", :finished, 50, ec, "abc\ndef", "")
+ end
+
+ def test_crlf_newline2
+ ec = Encoding::Converter.new("", "", Encoding::Converter::CRLF_NEWLINE_ENCODER)
+ assert_econv("abc\r\ndef", :finished, 50, ec, "abc\ndef", "")
+ end
+
+ def test_cr_newline
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", Encoding::Converter::CR_NEWLINE_ENCODER)
+ assert_econv("abc\rdef", :finished, 50, ec, "abc\ndef", "")
+ end
+
+ def test_cr_newline2
+ ec = Encoding::Converter.new("", "", Encoding::Converter::CR_NEWLINE_ENCODER)
+ assert_econv("abc\rdef", :finished, 50, ec, "abc\ndef", "")
+ end
+
+ def test_output_followed_by_input
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP")
+ a = ["", "abc\u{3042}def", ec, nil, 100, Encoding::Converter::OUTPUT_FOLLOWED_BY_INPUT]
+ check_ec("a", "bc\u{3042}def", :output_followed_by_input, *a)
+ check_ec("ab", "c\u{3042}def", :output_followed_by_input, *a)
+ check_ec("abc", "\u{3042}def", :output_followed_by_input, *a)
+ check_ec("abc\xA4\xA2", "def", :output_followed_by_input, *a)
+ check_ec("abc\xA4\xA2d", "ef", :output_followed_by_input, *a)
+ check_ec("abc\xA4\xA2de", "f", :output_followed_by_input, *a)
+ check_ec("abc\xA4\xA2def", "", :output_followed_by_input, *a)
+ check_ec("abc\xA4\xA2def", "", :finished, *a)
+ end
+
+ def test_errinfo_invalid_euc_jp
+ ec = Encoding::Converter.new("EUC-JP", "Shift_JIS")
+ ec.primitive_convert(src="\xff", dst="", nil, 10)
+ assert_errinfo(:invalid_byte_sequence, "EUC-JP", "UTF-8", "\xFF", "", nil, ec)
+ end
+
+ def test_errinfo_undefined_hiragana
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert(src="\xa4\xa2", dst="", nil, 10)
+ assert_errinfo(:undefined_conversion, "UTF-8", "ISO-8859-1", "\xE3\x81\x82", "", nil, ec)
+ end
+
+ def test_errinfo_invalid_partial_character
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert(src="\xa4", dst="", nil, 10)
+ assert_errinfo(:invalid_byte_sequence, "EUC-JP", "UTF-8", "\xA4", "", nil, ec)
+ end
+
+ def test_errinfo_valid_partial_character
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ec.primitive_convert(src="\xa4", dst="", nil, 10, Encoding::Converter::PARTIAL_INPUT)
+ assert_errinfo(:source_buffer_empty, nil, nil, nil, nil, :partial_input, ec)
+ end
+
+ def test_errinfo_invalid_utf16be
+ ec = Encoding::Converter.new("UTF-16BE", "UTF-8")
+ ec.primitive_convert(src="\xd8\x00\x00@", dst="", nil, 10)
+ assert_errinfo(:invalid_byte_sequence, "UTF-16BE", "UTF-8", "\xD8\x00", "\x00", nil, ec)
+ assert_equal("@", src)
+ end
+
+ def test_errinfo_invalid_utf16le
+ ec = Encoding::Converter.new("UTF-16LE", "UTF-8")
+ ec.primitive_convert(src="\x00\xd8@\x00", dst="", nil, 10)
+ assert_errinfo(:invalid_byte_sequence, "UTF-16LE", "UTF-8", "\x00\xD8", "@\x00", nil, ec)
+ assert_equal("", src)
+ end
+
+ def test_output_iso2022jp
+ ec = Encoding::Converter.new("EUC-JP", "ISO-2022-JP")
+ ec.primitive_convert(src="\xa1\xa1", dst="", nil, 10, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("\e$B!!".force_encoding("ISO-2022-JP"), dst)
+ assert_equal(true, ec.primitive_insert_output("???"))
+ ec.primitive_convert("", dst, nil, 10, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("\e$B!!\e(B???".force_encoding("ISO-2022-JP"), dst)
+ ec.primitive_convert(src="\xa1\xa2", dst, nil, 10, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("\e$B!!\e(B???\e$B!\"".force_encoding("ISO-2022-JP"), dst)
+
+ assert_equal(true, ec.primitive_insert_output("\xA1\xA1".force_encoding("EUC-JP")))
+ ec.primitive_convert("", dst, nil, 10, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("\e$B!!\e(B???\e$B!\"!!".force_encoding("ISO-2022-JP"), dst)
+
+ ec.primitive_convert(src="\xa1\xa3", dst, nil, 10, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("\e$B!!\e(B???\e$B!\"!!!\#".force_encoding("ISO-2022-JP"), dst)
+
+ assert_equal(true, ec.primitive_insert_output("\u3042"))
+ ec.primitive_convert("", dst, nil, 10, Encoding::Converter::PARTIAL_INPUT)
+ assert_equal("\e$B!!\e(B???\e$B!\"!!!\#$\"".force_encoding("ISO-2022-JP"), dst)
+
+ assert_raise(Encoding::ConversionUndefined) {
+ ec.primitive_insert_output("\uFFFD")
+ }
+
+ assert_equal("\e$B!!\e(B???\e$B!\"!!!\#$\"".force_encoding("ISO-2022-JP"), dst)
+
+ ec.primitive_convert("", dst, nil, 10)
+ assert_equal("\e$B!!\e(B???\e$B!\"!!!\#$\"\e(B".force_encoding("ISO-2022-JP"), dst)
+ end
+
+ def test_exc_invalid
+ err = assert_raise(Encoding::InvalidByteSequence) {
+ "abc\xa4def".encode("ISO-8859-1", "EUC-JP")
+ }
+ assert_equal("EUC-JP", err.source_encoding)
+ assert_equal("UTF-8", err.destination_encoding)
+ assert_equal("\xA4".force_encoding("ASCII-8BIT"), err.error_bytes)
+ end
+
+ def test_exc_undef
+ err = assert_raise(Encoding::ConversionUndefined) {
+ "abc\xa4\xa2def".encode("ISO-8859-1", "EUC-JP")
+ }
+ assert_equal("UTF-8", err.source_encoding)
+ assert_equal("ISO-8859-1", err.destination_encoding)
+ assert_equal("\u{3042}", err.error_char)
+ end
+
+ def test_putback
+ ec = Encoding::Converter.new("EUC-JP", "ISO-8859-1")
+ ret = ec.primitive_convert(src="abc\xa1def", dst="", nil, 10)
+ assert_equal(:invalid_byte_sequence, ret)
+ assert_equal(["abc", "ef"], [dst, src])
+ src = ec.primitive_putback(nil) + src
+ assert_equal(["abc", "def"], [dst, src])
+ ret = ec.primitive_convert(src, dst, nil, 10)
+ assert_equal(:finished, ret)
+ assert_equal(["abcdef", ""], [dst, src])
+ end
+
+ def test_invalid_replace
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", Encoding::Converter::INVALID_REPLACE)
+ ret = ec.primitive_convert(src="abc\x80def", dst="", nil, 100)
+ assert_equal(:finished, ret)
+ assert_equal("", src)
+ assert_equal("abc?def", dst)
+ end
+
+ def test_invalid_ignore
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", Encoding::Converter::INVALID_IGNORE)
+ ret = ec.primitive_convert(src="abc\x80def", dst="", nil, 100)
+ assert_equal(:finished, ret)
+ assert_equal("", src)
+ assert_equal("abcdef", dst)
+ end
+
+ def test_undef_replace
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", Encoding::Converter::UNDEF_REPLACE)
+ ret = ec.primitive_convert(src="abc\u{fffd}def", dst="", nil, 100)
+ assert_equal(:finished, ret)
+ assert_equal("", src)
+ assert_equal("abc?def", dst)
+ end
+
+ def test_undef_ignore
+ ec = Encoding::Converter.new("UTF-8", "EUC-JP", Encoding::Converter::UNDEF_IGNORE)
+ ret = ec.primitive_convert(src="abc\u{fffd}def", dst="", nil, 100)
+ assert_equal(:finished, ret)
+ assert_equal("", src)
+ assert_equal("abcdef", dst)
+ end
+
+ def test_noconv
+ ec = Encoding::Converter.new("", "")
+ assert_equal(nil, ec.source_encoding)
+ assert_equal(nil, ec.destination_encoding)
+ assert_equal([:source_buffer_empty, nil, nil, nil, nil, nil], ec.primitive_errinfo)
+ a = ["", "abcdefg", ec, nil, 2]
+ check_ec("ab", "cdefg", :destination_buffer_full, *a)
+ check_ec("abcd", "efg", :destination_buffer_full, *a)
+ check_ec("abcdef", "g", :destination_buffer_full, *a)
+ check_ec("abcdefg", "", :finished, *a)
+ end
+
+ def test_noconv_partial
+ ec = Encoding::Converter.new("", "")
+ a = ["", "abcdefg", ec, nil, 2, Encoding::Converter::PARTIAL_INPUT]
+ check_ec("ab", "cdefg", :destination_buffer_full, *a)
+ check_ec("abcd", "efg", :destination_buffer_full, *a)
+ check_ec("abcdef", "g", :destination_buffer_full, *a)
+ check_ec("abcdefg", "", :source_buffer_empty, *a)
+ end
+
+ def test_noconv_output_followed_by_input
+ ec = Encoding::Converter.new("", "")
+ a = ["", "abcdefg", ec, nil, 2, Encoding::Converter::OUTPUT_FOLLOWED_BY_INPUT]
+ check_ec("a", "bcdefg", :output_followed_by_input, *a)
+ check_ec("ab", "cdefg", :output_followed_by_input, *a)
+ check_ec("abc", "defg", :output_followed_by_input, *a)
+ check_ec("abcd", "efg", :output_followed_by_input, *a)
+ check_ec("abcde", "fg", :output_followed_by_input, *a)
+ check_ec("abcdef", "g", :output_followed_by_input, *a)
+ check_ec("abcdefg", "", :output_followed_by_input, *a)
+ check_ec("abcdefg", "", :finished, *a)
+ end
+
+ def test_noconv_insert_output
+ ec = Encoding::Converter.new("", "")
+ ec.primitive_insert_output("xyz")
+ ret = ec.primitive_convert(src="abc", dst="", nil, 20)
+ assert_equal(:finished, ret)
+ assert_equal(["xyzabc", ""], [dst, src])
+ end
+end
diff --git a/trunk/test/ruby/test_encoding.rb b/trunk/test/ruby/test_encoding.rb
new file mode 100644
index 0000000000..24000796fa
--- /dev/null
+++ b/trunk/test/ruby/test_encoding.rb
@@ -0,0 +1,54 @@
+require 'test/unit'
+
+class TestEncoding < Test::Unit::TestCase
+
+ # Test basic encoding methods: list, find, name
+ def test_encoding
+ encodings = Encoding.list
+ assert_equal(encodings.empty?, false)
+
+ encodings.each do |e|
+ assert_equal(e, Encoding.find(e.name))
+ assert_equal(e, Encoding.find(e.name.upcase))
+ assert_equal(e, Encoding.find(e.name.capitalize))
+ assert_equal(e, Encoding.find(e.name.downcase))
+ end
+ end
+
+ # Test that Encoding objects can't be copied
+ # And that they can be compared by object_id
+ def test_singleton
+ encodings = Encoding.list
+ encodings.each do |e|
+ assert_raise(TypeError) { e.dup }
+ assert_raise(TypeError) { e.clone }
+ assert_equal(e.object_id, Marshal.load(Marshal.dump(e)).object_id)
+ end
+ end
+
+ def test_find
+ assert_raise(ArgumentError) { Encoding.find("foobarbazqux") }
+ end
+
+ def test_dummy_p
+ assert_equal(true, Encoding::ISO_2022_JP.dummy?)
+ assert_equal(false, Encoding::UTF_8.dummy?)
+ end
+
+ def test_name_list
+ assert_instance_of(Array, Encoding.name_list)
+ Encoding.name_list.each do |x|
+ assert_instance_of(String, x)
+ end
+ end
+
+ def test_aliases
+ assert_instance_of(Hash, Encoding.aliases)
+ Encoding.aliases.each do |k, v|
+ assert(Encoding.name_list.include?(k))
+ assert(Encoding.name_list.include?(v))
+ assert_instance_of(String, k)
+ assert_instance_of(String, v)
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_enum.rb b/trunk/test/ruby/test_enum.rb
new file mode 100644
index 0000000000..a739982963
--- /dev/null
+++ b/trunk/test/ruby/test_enum.rb
@@ -0,0 +1,259 @@
+require 'test/unit'
+require 'continuation'
+
+class TestEnumerable < Test::Unit::TestCase
+ def setup
+ @obj = Object.new
+ class << @obj
+ include Enumerable
+ def each
+ yield 1
+ yield 2
+ yield 3
+ yield 1
+ yield 2
+ end
+ end
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_grep
+ assert_equal([1, 2, 1, 2], @obj.grep(1..2))
+ a = []
+ @obj.grep(2) {|x| a << x }
+ assert_equal([2, 2], a)
+ end
+
+ def test_count
+ assert_equal(5, @obj.count)
+ assert_equal(2, @obj.count(1))
+ assert_equal(3, @obj.count {|x| x % 2 == 1 })
+ assert_equal(2, @obj.count(1) {|x| x % 2 == 1 })
+ assert_raise(ArgumentError) { @obj.count(0, 1) }
+ end
+
+ def test_find
+ assert_equal(2, @obj.find {|x| x % 2 == 0 })
+ assert_equal(nil, @obj.find {|x| false })
+ assert_equal(:foo, @obj.find(proc { :foo }) {|x| false })
+ end
+
+ def test_find_index
+ assert_equal(1, @obj.find_index(2))
+ assert_equal(1, @obj.find_index {|x| x % 2 == 0 })
+ assert_equal(nil, @obj.find_index {|x| false })
+ assert_raise(ArgumentError) { @obj.find_index(0, 1) }
+ end
+
+ def test_find_all
+ assert_equal([1, 3, 1], @obj.find_all {|x| x % 2 == 1 })
+ end
+
+ def test_reject
+ assert_equal([2, 3, 2], @obj.reject {|x| x < 2 })
+ end
+
+ def test_to_a
+ assert_equal([1, 2, 3, 1, 2], @obj.to_a)
+ end
+
+ def test_inject
+ assert_equal(12, @obj.inject {|z, x| z * x })
+ assert_equal(48, @obj.inject {|z, x| z * 2 + x })
+ assert_equal(12, @obj.inject(:*))
+ assert_equal(24, @obj.inject(2) {|z, x| z * x })
+ assert_equal(24, @obj.inject(2, :*) {|z, x| z * x })
+ end
+
+ def test_partition
+ assert_equal([[1, 3, 1], [2, 2]], @obj.partition {|x| x % 2 == 1 })
+ end
+
+ def test_group_by
+ h = { 1 => [1, 1], 2 => [2, 2], 3 => [3] }
+ assert_equal(h, @obj.group_by {|x| x })
+ end
+
+ def test_first
+ assert_equal(1, @obj.first)
+ assert_equal([1, 2, 3], @obj.first(3))
+ end
+
+ def test_sort
+ assert_equal([1, 1, 2, 2, 3], @obj.sort)
+ end
+
+ def test_sort_by
+ assert_equal([3, 2, 2, 1, 1], @obj.sort_by {|x| -x })
+ end
+
+ def test_all
+ assert_equal(true, @obj.all? {|x| x <= 3 })
+ assert_equal(false, @obj.all? {|x| x < 3 })
+ assert_equal(true, @obj.all?)
+ assert_equal(false, [true, true, false].all?)
+ end
+
+ def test_any
+ assert_equal(true, @obj.any? {|x| x >= 3 })
+ assert_equal(false, @obj.any? {|x| x > 3 })
+ assert_equal(true, @obj.any?)
+ assert_equal(false, [false, false, false].any?)
+ end
+
+ def test_one
+ assert(@obj.one? {|x| x == 3 })
+ assert(!(@obj.one? {|x| x == 1 }))
+ assert(!(@obj.one? {|x| x == 4 }))
+ assert(%w{ant bear cat}.one? {|word| word.length == 4})
+ assert(!(%w{ant bear cat}.one? {|word| word.length > 4}))
+ assert(!(%w{ant bear cat}.one? {|word| word.length < 4}))
+ assert(!([ nil, true, 99 ].one?))
+ assert([ nil, true, false ].one?)
+ end
+
+ def test_none
+ assert(@obj.none? {|x| x == 4 })
+ assert(!(@obj.none? {|x| x == 1 }))
+ assert(!(@obj.none? {|x| x == 3 }))
+ assert(%w{ant bear cat}.none? {|word| word.length == 5})
+ assert(!(%w{ant bear cat}.none? {|word| word.length >= 4}))
+ assert([].none?)
+ assert([nil].none?)
+ assert([nil,false].none?)
+ end
+
+ def test_min
+ assert_equal(1, @obj.min)
+ assert_equal(3, @obj.min {|a,b| b <=> a })
+ a = %w(albatross dog horse)
+ assert_equal("albatross", a.min)
+ assert_equal("dog", a.min {|a,b| a.length <=> b.length })
+ assert_equal(1, [3,2,1].min)
+ end
+
+ def test_max
+ assert_equal(3, @obj.max)
+ assert_equal(1, @obj.max {|a,b| b <=> a })
+ a = %w(albatross dog horse)
+ assert_equal("horse", a.max)
+ assert_equal("albatross", a.max {|a,b| a.length <=> b.length })
+ assert_equal(1, [3,2,1].max{|a,b| b <=> a })
+ end
+
+ def test_minmax
+ assert_equal([1, 3], @obj.minmax)
+ assert_equal([3, 1], @obj.minmax {|a,b| b <=> a })
+ a = %w(albatross dog horse)
+ assert_equal(["albatross", "horse"], a.minmax)
+ assert_equal(["dog", "albatross"], a.minmax {|a,b| a.length <=> b.length })
+ assert_equal([1, 3], [2,3,1].minmax)
+ assert_equal([3, 1], [2,3,1].minmax {|a,b| b <=> a })
+ end
+
+ def test_min_by
+ assert_equal(3, @obj.min_by {|x| -x })
+ a = %w(albatross dog horse)
+ assert_equal("dog", a.min_by {|x| x.length })
+ assert_equal(3, [2,3,1].min_by {|x| -x })
+ end
+
+ def test_max_by
+ assert_equal(1, @obj.max_by {|x| -x })
+ a = %w(albatross dog horse)
+ assert_equal("albatross", a.max_by {|x| x.length })
+ assert_equal(1, [2,3,1].max_by {|x| -x })
+ end
+
+ def test_minmax_by
+ assert_equal([3, 1], @obj.minmax_by {|x| -x })
+ a = %w(albatross dog horse)
+ assert_equal(["dog", "albatross"], a.minmax_by {|x| x.length })
+ assert_equal([3, 1], [2,3,1].minmax_by {|x| -x })
+ end
+
+ def test_member
+ assert(@obj.member?(1))
+ assert(!(@obj.member?(4)))
+ assert([1,2,3].member?(1))
+ assert(!([1,2,3].member?(4)))
+ end
+
+ def test_each_with_index
+ a = []
+ @obj.each_with_index {|x, i| a << [x, i] }
+ assert_equal([[1,0],[2,1],[3,2],[1,3],[2,4]], a)
+
+ hash = Hash.new
+ %w(cat dog wombat).each_with_index do |item, index|
+ hash[item] = index
+ end
+ assert_equal({"cat"=>0, "wombat"=>2, "dog"=>1}, hash)
+ end
+
+ def test_zip
+ assert_equal([[1,1],[2,2],[3,3],[1,1],[2,2]], @obj.zip(@obj))
+ a = []
+ @obj.zip([:a, :b, :c]) {|x,y| a << [x, y] }
+ assert_equal([[1,:a],[2,:b],[3,:c],[1,nil],[2,nil]], a)
+ end
+
+ def test_take
+ assert_equal([1,2,3], @obj.take(3))
+ end
+
+ def test_take_while
+ assert_equal([1,2], @obj.take_while {|x| x <= 2})
+ end
+
+ def test_drop
+ assert_equal([3,1,2], @obj.drop(2))
+ end
+
+ def test_drop_while
+ assert_equal([3,1,2], @obj.drop_while {|x| x <= 2})
+ end
+
+ def test_cycle
+ assert_equal([1,2,3,1,2,1,2,3,1,2], @obj.cycle.take(10))
+ end
+
+ def test_callcc
+ assert_raise(RuntimeError) do
+ c = nil
+ @obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }
+ c.call
+ end
+
+ assert_raise(RuntimeError) do
+ c = nil
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:<=>) do |x|
+ callcc {|c2| c ||= c2 }
+ 0
+ end
+ end
+ [o, o].sort_by {|x| x }
+ c.call
+ end
+
+ assert_raise(RuntimeError) do
+ c = nil
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:<=>) do |x|
+ callcc {|c2| c ||= c2 }
+ 0
+ end
+ end
+ [o, o, o].sort_by {|x| x }
+ c.call
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_enumerator.rb b/trunk/test/ruby/test_enumerator.rb
new file mode 100644
index 0000000000..d1e75208f8
--- /dev/null
+++ b/trunk/test/ruby/test_enumerator.rb
@@ -0,0 +1,125 @@
+require 'test/unit'
+
+class TestEnumerator < Test::Unit::TestCase
+ def setup
+ @obj = Object.new
+ class << @obj
+ include Enumerable
+ def foo(*a)
+ a.each {|x| yield x }
+ end
+ end
+ end
+
+ def enum_test obj
+ i = 0
+ obj.map{|e|
+ e
+ }.sort
+ end
+
+ def test_iterators
+ assert_equal [0, 1, 2], enum_test(3.times)
+ assert_equal [:x, :y, :z], enum_test([:x, :y, :z].each)
+ assert_equal [[:x, 1], [:y, 2]], enum_test({:x=>1, :y=>2})
+ end
+
+ ## Enumerator as Iterator
+
+ def test_next
+ e = 3.times
+ 3.times{|i|
+ assert_equal i, e.next
+ }
+ assert_raise(StopIteration){e.next}
+ end
+
+ def test_loop
+ e = 3.times
+ i = 0
+ loop{
+ assert_equal(i, e.next)
+ i += 1
+ }
+ end
+
+ def test_nested_itaration
+ def (o = Object.new).each
+ yield :ok1
+ yield [:ok2, :x].each.next
+ end
+ e = o.to_enum
+ assert_equal :ok1, e.next
+ assert_equal :ok2, e.next
+ assert_raise(StopIteration){e.next}
+ end
+
+
+ def test_initialize
+ assert_equal([1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).to_a)
+ assert_equal([1, 2, 3], Enumerator.new(@obj, :foo, 1, 2, 3).to_a)
+ assert_raise(ArgumentError) { Enumerator.new }
+ end
+
+ def test_initialize_copy
+ assert_equal([1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).dup.to_a)
+ e = @obj.to_enum(:foo, 1, 2, 3)
+ assert_nothing_raised { assert_equal(1, e.next) }
+ assert_raise(TypeError) { e.dup }
+ end
+
+ def test_gc
+ assert_nothing_raised do
+ 1.times do
+ foo = [1,2,3].to_enum
+ GC.start
+ end
+ GC.start
+ end
+ end
+
+ def test_slice
+ assert_equal([[1,2,3],[4,5,6],[7,8,9],[10]], (1..10).each_slice(3).to_a)
+ end
+
+ def test_cons
+ a = [[1,2,3], [2,3,4], [3,4,5], [4,5,6], [5,6,7], [6,7,8], [7,8,9], [8,9,10]]
+ assert_equal(a, (1..10).each_cons(3).to_a)
+ end
+
+ def test_with_index
+ assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a)
+ end
+
+ def test_with_memo
+ r = 1..10
+ return unless r.each.respond_to? :with_memo
+ assert_equal([55, 3628800], (1..10).each.with_memo([0,1]) {|i, memo|
+ memo[0] += i
+ memo[1] *= i
+ })
+
+ a = [2,5,2,1,5,3,4,2,1,0]
+ a.delete_if.with_memo({}) {|i, seen|
+ if seen.key?(i)
+ true
+ else
+ seen[i] = true
+ false
+ end
+ }
+ assert_equal([2, 5, 1, 3, 4, 0], a)
+ end
+
+ def test_next_rewind
+ e = @obj.to_enum(:foo, 1, 2, 3)
+ assert_equal(1, e.next)
+ assert_equal(2, e.next)
+ e.rewind
+ assert_equal(1, e.next)
+ assert_equal(2, e.next)
+ assert_equal(3, e.next)
+ assert_raise(StopIteration) { e.next }
+ end
+end
+
diff --git a/trunk/test/ruby/test_env.rb b/trunk/test/ruby/test_env.rb
new file mode 100644
index 0000000000..28f0e87b59
--- /dev/null
+++ b/trunk/test/ruby/test_env.rb
@@ -0,0 +1,350 @@
+require 'test/unit'
+
+class TestEnv < Test::Unit::TestCase
+ IGNORE_CASE = /djgpp|bccwin|mswin|mingw/ =~ RUBY_PLATFORM
+ PATH_ENV = /human68k/ =~ RUBY_PLATFORM ? "path" : "PATH"
+
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ @backup = ENV.to_hash
+ ENV.delete('test')
+ ENV.delete('TEST')
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ ENV.clear
+ @backup.each {|k, v| ENV[k] = v }
+ end
+
+ def test_bracket
+ assert_nil(ENV['test'])
+ assert_nil(ENV['TEST'])
+ ENV['test'] = 'foo'
+ assert_equal('foo', ENV['test'])
+ if IGNORE_CASE
+ assert_equal('foo', ENV['TEST'])
+ else
+ assert_nil(ENV['TEST'])
+ end
+ ENV['TEST'] = 'bar'
+ assert_equal('bar', ENV['TEST'])
+ if IGNORE_CASE
+ assert_equal('bar', ENV['test'])
+ else
+ assert_equal('foo', ENV['test'])
+ end
+
+ assert_raises(TypeError) {
+ tmp = ENV[1]
+ }
+ assert_raises(TypeError) {
+ ENV[1] = 'foo'
+ }
+ assert_raises(TypeError) {
+ ENV['test'] = 0
+ }
+ end
+
+ def test_has_value
+ val = 'a'
+ val.succ! while ENV.has_value?(val) && ENV.has_value?(val.upcase)
+ ENV['test'] = val[0...-1]
+
+ assert_equal(false, ENV.has_value?(val))
+ assert_equal(false, ENV.has_value?(val.upcase))
+ ENV['test'] = val
+ assert_equal(true, ENV.has_value?(val))
+ assert_equal(false, ENV.has_value?(val.upcase))
+ ENV['test'] = val.upcase
+ assert_equal(false, ENV.has_value?(val))
+ assert_equal(true, ENV.has_value?(val.upcase))
+ end
+
+ def test_key
+ val = 'a'
+ val.succ! while ENV.has_value?(val) && ENV.has_value?(val.upcase)
+ ENV['test'] = val[0...-1]
+
+ assert_nil(ENV.key(val))
+ assert_nil(ENV.key(val.upcase))
+ ENV['test'] = val
+ if IGNORE_CASE
+ assert_equal('TEST', ENV.key(val).upcase)
+ else
+ assert_equal('test', ENV.key(val))
+ end
+ assert_nil(ENV.key(val.upcase))
+ ENV['test'] = val.upcase
+ assert_nil(ENV.key(val))
+ if IGNORE_CASE
+ assert_equal('TEST', ENV.key(val.upcase).upcase)
+ else
+ assert_equal('test', ENV.key(val.upcase))
+ end
+ end
+
+ def test_delete
+ assert_raise(ArgumentError) { ENV.delete("foo\0bar") }
+ assert_nil(ENV.delete("TEST"))
+ assert_nothing_raised { ENV.delete(PATH_ENV) }
+ end
+
+ def test_getenv
+ assert_raise(ArgumentError) { ENV["foo\0bar"] }
+ ENV[PATH_ENV] = ""
+ assert_equal("", ENV[PATH_ENV])
+ end
+
+ def test_fetch
+ ENV["test"] = "foo"
+ assert_equal("foo", ENV.fetch("test"))
+ ENV.delete("test")
+ assert_raise(KeyError) { ENV.fetch("test") }
+ assert_equal("foo", ENV.fetch("test", "foo"))
+ assert_equal("bar", ENV.fetch("test") { "bar" })
+ assert_equal("bar", ENV.fetch("test", "foo") { "bar" })
+ assert_raise(ArgumentError) { ENV.fetch("foo\0bar") }
+ assert_nothing_raised { ENV.fetch(PATH_ENV, "foo") }
+ ENV[PATH_ENV] = ""
+ assert_equal("", ENV.fetch(PATH_ENV))
+ end
+
+ def test_aset
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ ENV["test"] = "foo"
+ end.join
+ end
+ assert_raise(TypeError) { ENV["test"] = nil }
+ assert_raise(ArgumentError) { ENV["foo\0bar"] = "test" }
+ assert_raise(ArgumentError) { ENV["test"] = "foo\0bar" }
+ ENV[PATH_ENV] = "/tmp/".taint
+ assert_equal("/tmp/", ENV[PATH_ENV])
+ end
+
+ def test_keys
+ a = nil
+ assert_block { a = ENV.keys }
+ assert_kind_of(Array, a)
+ a.each {|k| assert_kind_of(String, k) }
+ end
+
+ def test_each_key
+ ENV.each_key {|k| assert_kind_of(String, k) }
+ end
+
+ def test_values
+ a = nil
+ assert_block { a = ENV.values }
+ assert_kind_of(Array, a)
+ a.each {|k| assert_kind_of(String, k) }
+ end
+
+ def test_each_value
+ ENV.each_value {|k| assert_kind_of(String, k) }
+ end
+
+ def test_each_pair
+ ENV.each_pair do |k, v|
+ assert_kind_of(String, k)
+ assert_kind_of(String, v)
+ end
+ end
+
+ def test_reject_bang
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.reject! {|k, v| IGNORE_CASE ? k.upcase == "TEST" : k == "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ assert_equal(h1, h2)
+
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ ENV.delete_if {|k, v| IGNORE_CASE ? k.upcase == "TEST" : k == "test" }
+ h2 = {}
+ ENV.each_pair {|k, v| h2[k] = v }
+ assert_equal(h1, h2)
+ end
+
+ def test_values_at
+ ENV["test"] = "foo"
+ assert_equal(["foo", "foo"], ENV.values_at("test", "test"))
+ end
+
+ def test_select
+ ENV["test"] = "foo"
+ h = ENV.select {|k| IGNORE_CASE ? k.upcase == "TEST" : k == "test" }
+ assert_equal(1, h.size)
+ k = h.keys.first
+ v = h.values.first
+ if IGNORE_CASE
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ end
+
+ def test_clear
+ ENV.clear
+ assert_equal(0, ENV.size)
+ end
+
+ def test_to_s
+ assert_equal("ENV", ENV.to_s)
+ end
+
+ def test_inspect
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ s = ENV.inspect
+ if IGNORE_CASE
+ s = s.upcase
+ assert(s == '{"FOO"=>"BAR", "BAZ"=>"QUX"}' || s == '{"BAZ"=>"QUX", "FOO"=>"BAR"}')
+ else
+ assert(s == '{"foo"=>"bar", "baz"=>"qux"}' || s == '{"baz"=>"qux", "foo"=>"bar"}')
+ end
+ end
+
+ def test_to_a
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ a = ENV.to_a
+ assert_equal(2, a.size)
+ if IGNORE_CASE
+ a = a.map {|x| x.map {|y| y.upcase } }
+ assert(a == [%w(FOO BAR), %w(BAZ QUX)] || a == [%w(BAZ QUX), %w(FOO BAR)])
+ else
+ assert(a == [%w(foo bar), %w(baz qux)] || a == [%w(baz qux), %w(foo bar)])
+ end
+ end
+
+ def test_rehash
+ assert_nil(ENV.rehash)
+ end
+
+ def test_size
+ s = ENV.size
+ ENV["test"] = "foo"
+ assert_equal(s + 1, ENV.size)
+ end
+
+ def test_empty_p
+ ENV.clear
+ assert(ENV.empty?)
+ ENV["test"] = "foo"
+ assert(!ENV.empty?)
+ end
+
+ def test_has_key
+ assert(!ENV.has_key?("test"))
+ ENV["test"] = "foo"
+ assert(ENV.has_key?("test"))
+ assert_raise(ArgumentError) { ENV.has_key?("foo\0bar") }
+ end
+
+ def test_assoc
+ assert_nil(ENV.assoc("test"))
+ ENV["test"] = "foo"
+ k, v = ENV.assoc("test")
+ if IGNORE_CASE
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ assert_raise(ArgumentError) { ENV.assoc("foo\0bar") }
+ end
+
+ def test_has_value2
+ ENV.clear
+ assert(!ENV.has_value?("foo"))
+ ENV["test"] = "foo"
+ assert(ENV.has_value?("foo"))
+ end
+
+ def test_rassoc
+ ENV.clear
+ assert_nil(ENV.rassoc("foo"))
+ ENV["foo"] = "bar"
+ ENV["test"] = "foo"
+ ENV["baz"] = "qux"
+ k, v = ENV.rassoc("foo")
+ if IGNORE_CASE
+ assert_equal("TEST", k.upcase)
+ assert_equal("FOO", v.upcase)
+ else
+ assert_equal("test", k)
+ assert_equal("foo", v)
+ end
+ end
+
+ def test_to_hash
+ h = {}
+ ENV.each {|k, v| h[k] = v }
+ assert_equal(h, ENV.to_hash)
+ end
+
+ def test_reject
+ h1 = {}
+ ENV.each_pair {|k, v| h1[k] = v }
+ ENV["test"] = "foo"
+ h2 = ENV.reject {|k, v| IGNORE_CASE ? k.upcase == "TEST" : k == "test" }
+ assert_equal(h1, h2)
+ end
+
+ def check(as, bs)
+ if IGNORE_CASE
+ as = as.map {|xs| xs.map {|x| x.upcase } }
+ bs = bs.map {|xs| xs.map {|x| x.upcase } }
+ end
+ assert_equal(as.sort, bs.sort)
+ end
+
+ def test_shift
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ a = ENV.shift
+ b = ENV.shift
+ check([a, b], [%w(foo bar), %w(baz qux)])
+ assert_nil(ENV.shift)
+ end
+
+ def test_invert
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ check(ENV.invert.to_a, [%w(bar foo), %w(qux baz)])
+ end
+
+ def test_replace
+ ENV["foo"] = "xxx"
+ ENV.replace({"foo"=>"bar", "baz"=>"qux"})
+ check(ENV.to_hash.to_a, [%w(foo bar), %w(baz qux)])
+ end
+
+ def test_update
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ ENV.update({"baz"=>"quux","a"=>"b"})
+ check(ENV.to_hash.to_a, [%w(foo bar), %w(baz quux), %w(a b)])
+
+ ENV.clear
+ ENV["foo"] = "bar"
+ ENV["baz"] = "qux"
+ ENV.update({"baz"=>"quux","a"=>"b"}) {|k, v1, v2| v1 ? k + "_" + v1 + "_" + v2 : v2 }
+ check(ENV.to_hash.to_a, [%w(foo bar), %w(baz baz_qux_quux), %w(a b)])
+ end
+end
diff --git a/trunk/test/ruby/test_eval.rb b/trunk/test/ruby/test_eval.rb
new file mode 100644
index 0000000000..23d34a5f81
--- /dev/null
+++ b/trunk/test/ruby/test_eval.rb
@@ -0,0 +1,394 @@
+require 'test/unit'
+
+class TestEval < Test::Unit::TestCase
+
+ @ivar = 12
+ @@cvar = 13
+ $gvar__eval = 14
+ Const = 15
+
+ def test_eval_basic
+ assert_equal nil, eval("nil")
+ assert_equal true, eval("true")
+ assert_equal false, eval("false")
+ assert_equal self, eval("self")
+ assert_equal 1, eval("1")
+ assert_equal :sym, eval(":sym")
+
+ assert_equal 11, eval("11")
+ @ivar = 12
+ assert_equal 12, eval("@ivar")
+ assert_equal 13, eval("@@cvar")
+ assert_equal 14, eval("$gvar__eval")
+ assert_equal 15, eval("Const")
+
+ assert_equal 16, eval("7 + 9")
+ assert_equal 17, eval("17.to_i")
+ assert_equal "18", eval(%q("18"))
+ assert_equal "19", eval(%q("1#{9}"))
+
+ 1.times {
+ assert_equal 12, eval("@ivar")
+ assert_equal 13, eval("@@cvar")
+ assert_equal 14, eval("$gvar__eval")
+ assert_equal 15, eval("Const")
+ }
+ end
+
+ def test_eval_binding_basic
+ assert_equal nil, eval("nil", binding())
+ assert_equal true, eval("true", binding())
+ assert_equal false, eval("false", binding())
+ assert_equal self, eval("self", binding())
+ assert_equal 1, eval("1", binding())
+ assert_equal :sym, eval(":sym", binding())
+
+ assert_equal 11, eval("11", binding())
+ @ivar = 12
+ assert_equal 12, eval("@ivar", binding())
+ assert_equal 13, eval("@@cvar", binding())
+ assert_equal 14, eval("$gvar__eval", binding())
+ assert_equal 15, eval("Const", binding())
+
+ assert_equal 16, eval("7 + 9", binding())
+ assert_equal 17, eval("17.to_i", binding())
+ assert_equal "18", eval(%q("18"), binding())
+ assert_equal "19", eval(%q("1#{9}"), binding())
+
+ 1.times {
+ assert_equal 12, eval("@ivar")
+ assert_equal 13, eval("@@cvar")
+ assert_equal 14, eval("$gvar__eval")
+ assert_equal 15, eval("Const")
+ }
+ end
+
+ def test_module_eval_string_basic
+ c = self.class
+ assert_equal nil, c.module_eval("nil")
+ assert_equal true, c.module_eval("true")
+ assert_equal false, c.module_eval("false")
+ assert_equal c, c.module_eval("self")
+ assert_equal :sym, c.module_eval(":sym")
+ assert_equal 11, c.module_eval("11")
+ @ivar = 12
+ assert_equal 12, c.module_eval("@ivar")
+ assert_equal 13, c.module_eval("@@cvar")
+ assert_equal 14, c.module_eval("$gvar__eval")
+ assert_equal 15, c.module_eval("Const")
+ assert_equal 16, c.module_eval("7 + 9")
+ assert_equal 17, c.module_eval("17.to_i")
+ assert_equal "18", c.module_eval(%q("18"))
+ assert_equal "19", c.module_eval(%q("1#{9}"))
+
+ @ivar = 12
+ 1.times {
+ assert_equal 12, c.module_eval("@ivar")
+ assert_equal 13, c.module_eval("@@cvar")
+ assert_equal 14, c.module_eval("$gvar__eval")
+ assert_equal 15, c.module_eval("Const")
+ }
+ end
+
+ def test_module_eval_block_basic
+ c = self.class
+ assert_equal nil, c.module_eval { nil }
+ assert_equal true, c.module_eval { true }
+ assert_equal false, c.module_eval { false }
+ assert_equal c, c.module_eval { self }
+ assert_equal :sym, c.module_eval { :sym }
+ assert_equal 11, c.module_eval { 11 }
+ @ivar = 12
+ assert_equal 12, c.module_eval { @ivar }
+ assert_equal 13, c.module_eval { @@cvar }
+ assert_equal 14, c.module_eval { $gvar__eval }
+ assert_equal 15, c.module_eval { Const }
+ assert_equal 16, c.module_eval { 7 + 9 }
+ assert_equal 17, c.module_eval { "17".to_i }
+ assert_equal "18", c.module_eval { "18" }
+ assert_equal "19", c.module_eval { "1#{9}" }
+
+ @ivar = 12
+ 1.times {
+ assert_equal 12, c.module_eval { @ivar }
+ assert_equal 13, c.module_eval { @@cvar }
+ assert_equal 14, c.module_eval { $gvar__eval }
+ assert_equal 15, c.module_eval { Const }
+ }
+ end
+
+ def forall_TYPE(mid)
+ objects = [Object.new, [], nil, true, false, 77, :sym] # TODO: check
+ objects.each do |obj|
+ obj.instance_variable_set :@ivar, 12
+ send mid, obj
+ end
+ end
+
+ def test_instance_eval_string_basic
+ forall_TYPE :instance_eval_string_basic_i
+ end
+
+ def instance_eval_string_basic_i(o)
+ assert_equal nil, o.instance_eval("nil")
+ assert_equal true, o.instance_eval("true")
+ assert_equal false, o.instance_eval("false")
+ assert_equal o, o.instance_eval("self")
+ assert_equal 1, o.instance_eval("1")
+ assert_equal :sym, o.instance_eval(":sym")
+
+ assert_equal 11, o.instance_eval("11")
+ assert_equal 12, o.instance_eval("@ivar")
+ assert_equal 13, o.instance_eval("@@cvar")
+ assert_equal 14, o.instance_eval("$gvar__eval")
+ assert_equal 15, o.instance_eval("Const")
+ assert_equal 16, o.instance_eval("7 + 9")
+ assert_equal 17, o.instance_eval("17.to_i")
+ assert_equal "18", o.instance_eval(%q("18"))
+ assert_equal "19", o.instance_eval(%q("1#{9}"))
+
+ 1.times {
+ assert_equal 12, o.instance_eval("@ivar")
+ assert_equal 13, o.instance_eval("@@cvar")
+ assert_equal 14, o.instance_eval("$gvar__eval")
+ assert_equal 15, o.instance_eval("Const")
+ }
+ end
+
+ def test_instance_eval_block_basic
+ forall_TYPE :instance_eval_block_basic_i
+ end
+
+ def instance_eval_block_basic_i(o)
+ assert_equal nil, o.instance_eval { nil }
+ assert_equal true, o.instance_eval { true }
+ assert_equal false, o.instance_eval { false }
+ assert_equal o, o.instance_eval { self }
+ assert_equal 1, o.instance_eval { 1 }
+ assert_equal :sym, o.instance_eval { :sym }
+
+ assert_equal 11, o.instance_eval { 11 }
+ assert_equal 12, o.instance_eval { @ivar }
+ assert_equal 13, o.instance_eval { @@cvar }
+ assert_equal 14, o.instance_eval { $gvar__eval }
+ assert_equal 15, o.instance_eval { Const }
+ assert_equal 16, o.instance_eval { 7 + 9 }
+ assert_equal 17, o.instance_eval { 17.to_i }
+ assert_equal "18", o.instance_eval { "18" }
+ assert_equal "19", o.instance_eval { "1#{9}" }
+
+ 1.times {
+ assert_equal 12, o.instance_eval { @ivar }
+ assert_equal 13, o.instance_eval { @@cvar }
+ assert_equal 14, o.instance_eval { $gvar__eval }
+ assert_equal 15, o.instance_eval { Const }
+ }
+ end
+
+ def test_instance_eval_cvar
+ [Object.new, [], 7, :sym, true, false, nil].each do |obj|
+ assert_equal(13, obj.instance_eval("@@cvar"))
+ assert_equal(13, obj.instance_eval{@@cvar})
+ # assert_raise(NameError){obj.instance_eval("@@cvar")}
+ # assert_raise(NameError){obj.instance_eval{@@cvar}}
+ end
+ end
+
+ #
+ # From ruby/test/ruby/test_eval.rb
+ #
+
+ def test_ev
+ local1 = "local1"
+ lambda {
+ local2 = "local2"
+ return binding
+ }.call
+ end
+
+ def test_eval_orig
+ assert_nil(eval(""))
+ $bad=false
+ eval 'while false; $bad = true; print "foo\n" end'
+ assert(!$bad)
+
+ assert(eval('TRUE'))
+ assert(eval('true'))
+ assert(!eval('NIL'))
+ assert(!eval('nil'))
+ assert(!eval('FALSE'))
+ assert(!eval('false'))
+
+ $foo = 'assert(true)'
+ begin
+ eval $foo
+ rescue
+ assert(false)
+ end
+
+ assert_equal('assert(true)', eval("$foo"))
+ assert_equal(true, eval("true"))
+ i = 5
+ assert(eval("i == 5"))
+ assert_equal(5, eval("i"))
+ assert(eval("defined? i"))
+
+ $x = test_ev
+ assert_equal("local1", eval("local1", $x)) # normal local var
+ assert_equal("local2", eval("local2", $x)) # nested local var
+ $bad = true
+ begin
+ p eval("local1")
+ rescue NameError # must raise error
+ $bad = false
+ end
+ assert(!$bad)
+
+ # !! use class_eval to avoid nested definition
+ self.class.class_eval %q(
+ module EvTest
+ EVTEST1 = 25
+ evtest2 = 125
+ $x = binding
+ end
+ )
+ assert_equal(25, eval("EVTEST1", $x)) # constant in module
+ assert_equal(125, eval("evtest2", $x)) # local var in module
+ $bad = true
+ begin
+ eval("EVTEST1")
+ rescue NameError # must raise error
+ $bad = false
+ end
+ assert(!$bad)
+
+ if false
+ # Ruby 2.0 doesn't see Proc as Binding
+ x = proc{}
+ eval "i4 = 1", x
+ assert_equal(1, eval("i4", x))
+ x = proc{proc{}}.call
+ eval "i4 = 22", x
+ assert_equal(22, eval("i4", x))
+ $x = []
+ x = proc{proc{}}.call
+ eval "(0..9).each{|i5| $x[i5] = proc{i5*2}}", x
+ assert_equal(8, $x[4].call)
+ end
+
+ x = binding
+ eval "i = 1", x
+ assert_equal(1, eval("i", x))
+ x = proc{binding}.call
+ eval "i = 22", x
+ assert_equal(22, eval("i", x))
+ $x = []
+ x = proc{binding}.call
+ eval "(0..9).each{|i5| $x[i5] = proc{i5*2}}", x
+ assert_equal(8, $x[4].call)
+ x = proc{binding}.call
+ eval "for i6 in 1..1; j6=i6; end", x
+ assert(eval("defined? i6", x))
+ assert(eval("defined? j6", x))
+
+ proc {
+ p = binding
+ eval "foo11 = 1", p
+ foo22 = 5
+ proc{foo11=22}.call
+ proc{foo22=55}.call
+ # assert_equal(eval("foo11"), eval("foo11", p))
+ # assert_equal(1, eval("foo11"))
+ assert_equal(eval("foo22"), eval("foo22", p))
+ assert_equal(55, eval("foo22"))
+ }.call
+
+ if false
+ # Ruby 2.0 doesn't see Proc as Binding
+ p1 = proc{i7 = 0; proc{i7}}.call
+ assert_equal(0, p1.call)
+ eval "i7=5", p1
+ assert_equal(5, p1.call)
+ assert(!defined?(i7))
+ end
+
+ if false
+ # Ruby 2.0 doesn't see Proc as Binding
+ p1 = proc{i7 = 0; proc{i7}}.call
+ i7 = nil
+ assert_equal(0, p1.call)
+ eval "i7=1", p1
+ assert_equal(1, p1.call)
+ eval "i7=5", p1
+ assert_equal(5, p1.call)
+ assert_nil(i7)
+ end
+ end
+
+ def test_nil_instance_eval_cvar
+ def nil.test_binding
+ binding
+ end
+ bb = eval("nil.instance_eval \"binding\"", nil.test_binding)
+ assert_raise(NameError, "[ruby-dev:24103]") { eval("@@a", bb) }
+ class << nil
+ remove_method :test_binding
+ end
+ end
+
+ def test_fixnum_instance_eval_cvar
+ assert_raise(NameError, "[ruby-dev:24213]") { 1.instance_eval "@@a" }
+ end
+
+ def test_cvar_scope_with_instance_eval
+ # TODO: check
+ Fixnum.class_eval "@@test_cvar_scope_with_instance_eval = 1" # depends on [ruby-dev:24229]
+ @@test_cvar_scope_with_instance_eval = 4
+ assert_equal(4, 1.instance_eval("@@test_cvar_scope_with_instance_eval"), "[ruby-dev:24223]")
+ Fixnum.__send__(:remove_class_variable, :@@test_cvar_scope_with_instance_eval)
+ end
+
+ def test_eval_and_define_method
+ assert_nothing_raised("[ruby-dev:24228]") {
+ def temporally_method_for_test_eval_and_define_method(&block)
+ lambda {
+ class << Object.new; self end.send(:define_method, :zzz, &block)
+ }
+ end
+ v = eval("temporally_method_for_test_eval_and_define_method {}")
+ {}[0] = {}
+ v.call
+ }
+ end
+
+ def test_define_method_block
+ cc = Class.new do
+ define_method(:foo) {|&block|
+ block.call if block
+ }
+ end
+
+ c = cc.new
+ x = "ng"
+ c.foo() {x = "ok"}
+ assert_equal("ok", x)
+ end
+
+ def test_eval_using_integer_as_binding
+ assert_raise(TypeError) { eval("", 1) }
+ end
+
+ def test_eval_raise
+ assert_raise(RuntimeError) { eval("raise ''") }
+ end
+
+ def test_eval_using_untainted_binding_under_safe4
+ assert_raise(SecurityError) do
+ Thread.new do
+ b = binding
+ $SAFE = 4
+ eval("", b)
+ end.join
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_exception.rb b/trunk/test/ruby/test_exception.rb
new file mode 100644
index 0000000000..3300fcdd74
--- /dev/null
+++ b/trunk/test/ruby/test_exception.rb
@@ -0,0 +1,226 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestException < Test::Unit::TestCase
+ def test_exception
+ begin
+ raise "this must be handled"
+ assert(false)
+ rescue
+ assert(true)
+ end
+
+ $bad = true
+ begin
+ raise "this must be handled no.2"
+ rescue
+ if $bad
+ $bad = false
+ retry
+ assert(false)
+ end
+ end
+ assert(true)
+
+ # exception in rescue clause
+ $string = "this must be handled no.3"
+ e = assert_raises(RuntimeError) do
+ begin
+ raise "exception in rescue clause"
+ rescue
+ raise $string
+ end
+ assert(false)
+ end
+ assert_equal($string, e.message)
+
+ # exception in ensure clause
+ $string = "exception in ensure clause"
+ e = assert_raises(RuntimeError) do
+ begin
+ raise "this must be handled no.4"
+ ensure
+ assert_instance_of(RuntimeError, $!)
+ assert_equal("this must be handled no.4", $!.message)
+ raise "exception in ensure clause"
+ end
+ assert(false)
+ end
+ assert_equal($string, e.message)
+
+ $bad = true
+ begin
+ begin
+ raise "this must be handled no.5"
+ ensure
+ $bad = false
+ end
+ rescue
+ end
+ assert(!$bad)
+
+ $bad = true
+ begin
+ begin
+ raise "this must be handled no.6"
+ ensure
+ $bad = false
+ end
+ rescue
+ end
+ assert(!$bad)
+
+ $bad = true
+ while true
+ begin
+ break
+ ensure
+ $bad = false
+ end
+ end
+ assert(!$bad)
+
+ assert(catch(:foo) {
+ loop do
+ loop do
+ throw :foo, true
+ break
+ end
+ break
+ assert(false) # should no reach here
+ end
+ false
+ })
+
+ end
+
+ def test_else
+ begin
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+
+ begin
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+
+ begin
+ assert(true)
+ begin
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+
+ begin
+ assert(true)
+ begin
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+
+ begin
+ assert(true)
+ begin
+ assert(true)
+ rescue
+ assert(false)
+ else
+ assert(true)
+ end
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+
+ begin
+ assert(true)
+ begin
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+ assert(true)
+ raise
+ assert(false)
+ rescue
+ assert(true)
+ else
+ assert(false)
+ end
+ end
+
+ def test_raise_with_wrong_number_of_arguments
+ assert_raise(TypeError) { raise nil }
+ assert_raise(TypeError) { raise 1, 1 }
+ assert_raise(ArgumentError) { raise 1, 1, 1, 1 }
+ end
+
+ def test_errat
+ assert_in_out_err([], "p $@", %w(nil), [])
+
+ assert_in_out_err([], "$@ = 1", [], /\$! not set \(ArgumentError\)$/)
+
+ assert_in_out_err([], <<-INPUT, [], /backtrace must be Array of String \(TypeError\)$/)
+ begin
+ raise
+ rescue
+ $@ = 1
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, [], /^foo: unhandled exception$/)
+ begin
+ raise
+ rescue
+ $@ = 'foo'
+ raise
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, [], /^foo: unhandled exception\s+from bar\s+from baz$/)
+ begin
+ raise
+ rescue
+ $@ = %w(foo bar baz)
+ raise
+ end
+ INPUT
+ end
+end
diff --git a/trunk/test/ruby/test_fiber.rb b/trunk/test/ruby/test_fiber.rb
new file mode 100644
index 0000000000..fc9a49919a
--- /dev/null
+++ b/trunk/test/ruby/test_fiber.rb
@@ -0,0 +1,164 @@
+require 'test/unit'
+require 'fiber'
+require 'continuation'
+
+class TestFiber < Test::Unit::TestCase
+ def test_normal
+ f = Fiber.current
+ assert_equal(:ok2,
+ Fiber.new{|e|
+ assert_equal(:ok1, e)
+ Fiber.yield :ok2
+ }.resume(:ok1)
+ )
+ assert_equal([:a, :b], Fiber.new{|a, b| [a, b]}.resume(:a, :b))
+ end
+
+ def test_term
+ assert_equal(:ok, Fiber.new{:ok}.resume)
+ assert_equal([:a, :b, :c, :d, :e],
+ Fiber.new{
+ Fiber.new{
+ Fiber.new{
+ Fiber.new{
+ [:a]
+ }.resume + [:b]
+ }.resume + [:c]
+ }.resume + [:d]
+ }.resume + [:e])
+ end
+
+ def test_many_fibers
+ max = 10000
+ assert_equal(max, max.times{
+ Fiber.new{}
+ })
+ assert_equal(max,
+ max.times{|i|
+ Fiber.new{
+ }.resume
+ }
+ )
+ end
+
+ def test_many_fibers_with_threads
+ max = 1000
+ @cnt = 0
+ (1..100).map{|ti|
+ Thread.new{
+ max.times{|i|
+ Fiber.new{
+ @cnt += 1
+ }.resume
+ }
+ }
+ }.each{|t|
+ t.join
+ }
+ assert_equal(:ok, :ok)
+ end
+
+ def test_error
+ assert_raise(ArgumentError){
+ Fiber.new # Fiber without block
+ }
+ assert_raise(FiberError){
+ f = Fiber.new{}
+ Thread.new{f.resume}.join # Fiber yielding across thread
+ }
+ assert_raise(FiberError){
+ f = Fiber.new{}
+ f.resume
+ f.resume
+ }
+ assert_raise(RuntimeError){
+ f = Fiber.new{
+ @c = callcc{|c| @c = c}
+ }.resume
+ @c.call # cross fiber callcc
+ }
+ assert_raise(RuntimeError){
+ Fiber.new{
+ raise
+ }.resume
+ }
+ assert_raise(FiberError){
+ Fiber.yield
+ }
+ assert_raise(FiberError){
+ fib = Fiber.new{
+ fib.resume
+ }
+ fib.resume
+ }
+ assert_raise(FiberError){
+ fib = Fiber.new{
+ Fiber.new{
+ fib.resume
+ }.resume
+ }
+ fib.resume
+ }
+ end
+
+ def test_return
+ assert_raise(LocalJumpError){
+ Fiber.new do
+ return
+ end.resume
+ }
+ end
+
+ def test_throw
+ assert_raise(ArgumentError){
+ Fiber.new do
+ throw :a
+ end.resume
+ }
+ end
+
+ def test_transfer
+ ary = []
+ f2 = nil
+ f1 = Fiber.new{
+ ary << f2.transfer(:foo)
+ :ok
+ }
+ f2 = Fiber.new{
+ ary << f1.transfer(:baz)
+ :ng
+ }
+ assert_equal(:ok, f1.transfer)
+ assert_equal([:baz], ary)
+ end
+
+ def test_tls
+ #
+ def tvar(var, val)
+ old = Thread.current[var]
+ begin
+ Thread.current[var] = val
+ yield
+ ensure
+ Thread.current[var] = old
+ end
+ end
+
+ fb = Fiber.new {
+ assert_equal(nil, Thread.current[:v]); tvar(:v, :x) {
+ assert_equal(:x, Thread.current[:v]); Fiber.yield
+ assert_equal(:x, Thread.current[:v]); }
+ assert_equal(nil, Thread.current[:v]); Fiber.yield
+ raise # unreachable
+ }
+
+ assert_equal(nil, Thread.current[:v]); tvar(:v,1) {
+ assert_equal(1, Thread.current[:v]); tvar(:v,3) {
+ assert_equal(3, Thread.current[:v]); fb.resume
+ assert_equal(3, Thread.current[:v]); }
+ assert_equal(1, Thread.current[:v]); }
+ assert_equal(nil, Thread.current[:v]); fb.resume
+ assert_equal(nil, Thread.current[:v]);
+ end
+end
+
diff --git a/trunk/test/ruby/test_file.rb b/trunk/test/ruby/test_file.rb
new file mode 100644
index 0000000000..f6fcf89a14
--- /dev/null
+++ b/trunk/test/ruby/test_file.rb
@@ -0,0 +1,122 @@
+require 'test/unit'
+require 'tempfile'
+require_relative 'ut_eof'
+
+class TestFile < Test::Unit::TestCase
+
+ # I don't know Ruby's spec about "unlink-before-close" exactly.
+ # This test asserts current behaviour.
+ def test_unlink_before_close
+ Dir.mktmpdir('rubytest-file') {|tmpdir|
+ filename = tmpdir + '/' + File.basename(__FILE__) + ".#{$$}"
+ w = File.open(filename, "w")
+ w << "foo"
+ w.close
+ r = File.open(filename, "r")
+ begin
+ if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM
+ assert_raise(Errno::EACCES) {File.unlink(filename)}
+ else
+ assert_nothing_raised {File.unlink(filename)}
+ end
+ ensure
+ r.close
+ File.unlink(filename) if File.exist?(filename)
+ end
+ }
+ end
+
+ include TestEOF
+ def open_file(content)
+ f = Tempfile.new("test-eof")
+ f << content
+ f.rewind
+ yield f
+ end
+ alias open_file_rw open_file
+
+ include TestEOF::Seek
+
+ def test_truncate_wbuf
+ f = Tempfile.new("test-truncate")
+ f.print "abc"
+ f.truncate(0)
+ f.print "def"
+ f.close
+ assert_equal("\0\0\0def", File.read(f.path), "[ruby-dev:24191]")
+ end
+
+ def test_truncate_rbuf
+ f = Tempfile.new("test-truncate")
+ f.puts "abc"
+ f.puts "def"
+ f.close
+ f.open
+ assert_equal("abc\n", f.gets)
+ f.truncate(3)
+ assert_equal(nil, f.gets, "[ruby-dev:24197]")
+ end
+
+ def test_truncate_beyond_eof
+ f = Tempfile.new("test-truncate")
+ f.print "abc"
+ f.truncate 10
+ assert_equal("\0" * 7, f.read(100), "[ruby-dev:24532]")
+ end
+
+ def test_read_all_extended_file
+ f = Tempfile.new("test-extended-file")
+ assert_nil(f.getc)
+ open(f.path, "w") {|g| g.print "a" }
+ assert_equal("a", f.read)
+ end
+
+ def test_gets_extended_file
+ f = Tempfile.new("test-extended-file")
+ assert_nil(f.getc)
+ open(f.path, "w") {|g| g.print "a" }
+ assert_equal("a", f.gets("a"))
+ end
+
+ def test_gets_para_extended_file
+ f = Tempfile.new("test-extended-file")
+ assert_nil(f.getc)
+ open(f.path, "w") {|g| g.print "\na" }
+ assert_equal("a", f.gets(""))
+ end
+
+ def test_each_byte_extended_file
+ f = Tempfile.new("test-extended-file")
+ assert_nil(f.getc)
+ open(f.path, "w") {|g| g.print "a" }
+ result = []
+ f.each_byte {|b| result << b.chr }
+ assert_equal([?a], result)
+ end
+
+ def test_getc_extended_file
+ f = Tempfile.new("test-extended-file")
+ assert_nil(f.getc)
+ open(f.path, "w") {|g| g.print "a" }
+ assert_equal(?a, f.getc)
+ end
+
+ def test_s_chown
+ assert_nothing_raised { File.chown -1, -1 }
+ assert_nothing_raised { File.chown nil, nil }
+ end
+
+ def test_chown
+ assert_nothing_raised {
+ File.open(__FILE__) {|f| f.chown -1, -1 }
+ }
+ assert_nothing_raised("[ruby-dev:27140]") {
+ File.open(__FILE__) {|f| f.chown nil, nil }
+ }
+ end
+
+ def test_uninitialized
+ assert_raise(TypeError) { File::Stat.allocate.readable? }
+ assert_nothing_raised { File::Stat.allocate.inspect }
+ end
+end
diff --git a/trunk/test/ruby/test_file_exhaustive.rb b/trunk/test/ruby/test_file_exhaustive.rb
new file mode 100644
index 0000000000..eda3669681
--- /dev/null
+++ b/trunk/test/ruby/test_file_exhaustive.rb
@@ -0,0 +1,726 @@
+require "test/unit"
+require "fileutils"
+require "tmpdir"
+
+class TestFileExhaustive < Test::Unit::TestCase
+ def setup
+ @dir = Dir.mktmpdir("rubytest-file")
+ File.chown(-1, Process.gid, @dir)
+ @file = make_tmp_filename("file")
+ @zerofile = make_tmp_filename("zerofile")
+ @nofile = make_tmp_filename("nofile")
+ @symlinkfile = make_tmp_filename("symlinkfile")
+ @hardlinkfile = make_tmp_filename("hardlinkfile")
+ make_file("foo", @file)
+ make_file("", @zerofile)
+ @time = Time.now
+ begin
+ File.symlink(@file, @symlinkfile)
+ rescue NotImplementedError
+ @symlinkfile = nil
+ end
+ begin
+ File.link(@file, @hardlinkfile)
+ rescue NotImplementedError, Errno::EINVAL # EINVAL for Windows Vista
+ @hardlinkfile = nil
+ end
+ end
+
+ def teardown
+ GC.start
+ FileUtils.remove_entry_secure @dir
+ end
+
+ def make_file(content, file = @file)
+ open(file, "w") {|fh| fh << content }
+ end
+
+ def make_tmp_filename(prefix)
+ @hardlinkfile = @dir + "/" + prefix + File.basename(__FILE__) + ".#{$$}.test"
+ end
+
+ def test_path
+ file = @file
+
+ assert_equal(file, File.new(file).path)
+ assert_equal(file, File.path(file))
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:to_path) { file }
+ end
+ assert_equal(file, File.path(o))
+ end
+
+ def assert_integer(n)
+ assert(n.is_a?(Integer), n.inspect + " is not Fixnum.")
+ end
+
+ def assert_integer_or_nil(n)
+ assert(n.is_a?(Integer) || n.equal?(nil), n.inspect + " is neither Fixnum nor nil.")
+ end
+
+ def test_stat
+ sleep(@time - Time.now + 1.1)
+ make_file("foo", @file + "2")
+ fs1, fs2 = File.stat(@file), File.stat(@file + "2")
+ assert_nothing_raised do
+ assert_equal(0, fs1 <=> fs1)
+ assert_equal(-1, fs1 <=> fs2)
+ assert_equal(1, fs2 <=> fs1)
+ assert_nil(fs1 <=> nil)
+ assert_integer(fs1.dev)
+ assert_integer_or_nil(fs1.rdev)
+ assert_integer_or_nil(fs1.dev_major)
+ assert_integer_or_nil(fs1.dev_minor)
+ assert_integer_or_nil(fs1.rdev_major)
+ assert_integer_or_nil(fs1.rdev_minor)
+ assert_integer(fs1.ino)
+ assert_integer(fs1.mode)
+ unless /emx/ =~ RUBY_PLATFORM
+ assert_equal(@hardlinkfile ? 2 : 1, fs1.nlink)
+ end
+ assert_integer(fs1.uid)
+ assert_integer(fs1.gid)
+ assert_equal(3, fs1.size)
+ assert_integer_or_nil(fs1.blksize)
+ assert_integer_or_nil(fs1.blocks)
+ assert_kind_of(Time, fs1.atime)
+ assert_kind_of(Time, fs1.mtime)
+ assert_kind_of(Time, fs1.ctime)
+ assert_kind_of(String, fs1.inspect)
+ end
+ assert_raise(Errno::ENOENT) { File.stat(@nofile) }
+ assert_kind_of(File::Stat, File.new(@file).stat)
+ assert_raise(Errno::ENOENT) { File.lstat(@nofile) }
+ assert_kind_of(File::Stat, File.new(@file).lstat)
+ end
+
+ def test_directory_p
+ assert(File.directory?(@dir))
+ assert(!(File.directory?(@file)))
+ assert(!(File.directory?(@nofile)))
+ end
+
+ def test_pipe_p ## xxx
+ assert(!(File.pipe?(@dir)))
+ assert(!(File.pipe?(@file)))
+ assert(!(File.pipe?(@nofile)))
+ end
+
+ def test_symlink_p
+ assert(!(File.symlink?(@dir)))
+ assert(!(File.symlink?(@file)))
+ assert(File.symlink?(@symlinkfile)) if @symlinkfile
+ assert(!(File.symlink?(@hardlinkfile))) if @hardlinkfile
+ assert(!(File.symlink?(@nofile)))
+ end
+
+ def test_socket_p ## xxx
+ assert(!(File.socket?(@dir)))
+ assert(!(File.socket?(@file)))
+ assert(!(File.socket?(@nofile)))
+ end
+
+ def test_blockdev_p ## xxx
+ assert(!(File.blockdev?(@dir)))
+ assert(!(File.blockdev?(@file)))
+ assert(!(File.blockdev?(@nofile)))
+ end
+
+ def test_chardev_p ## xxx
+ assert(!(File.chardev?(@dir)))
+ assert(!(File.chardev?(@file)))
+ assert(!(File.chardev?(@nofile)))
+ end
+
+ def test_exist_p
+ assert(File.exist?(@dir))
+ assert(File.exist?(@file))
+ assert(!(File.exist?(@nofile)))
+ end
+
+ def test_readable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0200, @file)
+ assert(!(File.readable?(@file)))
+ File.chmod(0600, @file)
+ assert(File.readable?(@file))
+ assert(!(File.readable?(@nofile)))
+ end
+
+ def test_readable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0200, @file)
+ assert(!(File.readable_real?(@file)))
+ File.chmod(0600, @file)
+ assert(File.readable_real?(@file))
+ assert(!(File.readable_real?(@nofile)))
+ end
+
+ def test_world_readable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0006, @file)
+ assert(File.world_readable?(@file))
+ File.chmod(0060, @file)
+ assert(!(File.world_readable?(@file)))
+ File.chmod(0600, @file)
+ assert(!(File.world_readable?(@file)))
+ assert(!(File.world_readable?(@nofile)))
+ end
+
+ def test_writable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0400, @file)
+ assert(!(File.writable?(@file)))
+ File.chmod(0600, @file)
+ assert(File.writable?(@file))
+ assert(!(File.writable?(@nofile)))
+ end
+
+ def test_writable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0400, @file)
+ assert(!(File.writable_real?(@file)))
+ File.chmod(0600, @file)
+ assert(File.writable_real?(@file))
+ assert(!(File.writable_real?(@nofile)))
+ end
+
+ def test_world_writable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0006, @file)
+ assert(File.world_writable?(@file))
+ File.chmod(0060, @file)
+ assert(!(File.world_writable?(@file)))
+ File.chmod(0600, @file)
+ assert(!(File.world_writable?(@file)))
+ assert(!(File.world_writable?(@nofile)))
+ end
+
+ def test_executable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0100, @file)
+ assert(File.executable?(@file))
+ File.chmod(0600, @file)
+ assert(!(File.executable?(@file)))
+ assert(!(File.executable?(@nofile)))
+ end
+
+ def test_executable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0100, @file)
+ assert(File.executable_real?(@file))
+ File.chmod(0600, @file)
+ assert(!(File.executable_real?(@file)))
+ assert(!(File.executable_real?(@nofile)))
+ end
+
+ def test_file_p
+ assert(!(File.file?(@dir)))
+ assert(File.file?(@file))
+ assert(!(File.file?(@nofile)))
+ end
+
+ def test_zero_p
+ assert_nothing_raised { File.zero?(@dir) }
+ assert(!(File.zero?(@file)))
+ assert(File.zero?(@zerofile))
+ assert(!(File.zero?(@nofile)))
+ end
+
+ def test_size_p
+ assert_nothing_raised { File.size?(@dir) }
+ assert_equal(3, File.size?(@file))
+ assert(!(File.size?(@zerofile)))
+ assert(!(File.size?(@nofile)))
+ end
+
+ def test_owned_p ## xxx
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ assert(File.owned?(@file))
+ assert(File.grpowned?(@file))
+ end
+
+ def test_suid_sgid_sticky ## xxx
+ assert(!(File.setuid?(@file)))
+ assert(!(File.setgid?(@file)))
+ assert(!(File.sticky?(@file)))
+ end
+
+ def test_identical_p
+ assert(File.identical?(@file, @file))
+ assert(!(File.identical?(@file, @zerofile)))
+ assert(!(File.identical?(@file, @nofile)))
+ assert(!(File.identical?(@nofile, @file)))
+ end
+
+ def test_size
+ assert_integer(File.size(@dir))
+ assert_equal(3, File.size(@file))
+ assert_equal(0, File.size(@zerofile))
+ assert_raise(Errno::ENOENT) { File.size(@nofile) }
+ end
+
+ def test_ftype
+ assert_equal("directory", File.ftype(@dir))
+ assert_equal("file", File.ftype(@file))
+ assert_equal("link", File.ftype(@symlinkfile)) if @symlinkfile
+ assert_equal("file", File.ftype(@hardlinkfile)) if @hardlinkfile
+ assert_raise(Errno::ENOENT) { File.ftype(@nofile) }
+ end
+
+ def test_atime
+ t1 = File.atime(@file)
+ t2 = File.new(@file).atime
+ assert_kind_of(Time, t1)
+ assert_kind_of(Time, t2)
+ assert_equal(t1, t2)
+ assert_raise(Errno::ENOENT) { File.atime(@nofile) }
+ end
+
+ def test_mtime
+ t1 = File.mtime(@file)
+ t2 = File.new(@file).mtime
+ assert_kind_of(Time, t1)
+ assert_kind_of(Time, t2)
+ assert_equal(t1, t2)
+ assert_raise(Errno::ENOENT) { File.mtime(@nofile) }
+ end
+
+ def test_ctime
+ t1 = File.ctime(@file)
+ t2 = File.new(@file).ctime
+ assert_kind_of(Time, t1)
+ assert_kind_of(Time, t2)
+ assert_equal(t1, t2)
+ assert_raise(Errno::ENOENT) { File.ctime(@nofile) }
+ end
+
+ def test_chmod
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ assert_equal(1, File.chmod(0444, @file))
+ assert_equal(0444, File.stat(@file).mode % 01000)
+ assert_equal(0, File.new(@file).chmod(0222))
+ assert_equal(0222, File.stat(@file).mode % 01000)
+ File.chmod(0600, @file)
+ assert_raise(Errno::ENOENT) { File.chmod(0600, @nofile) }
+ end
+
+ def test_lchmod
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ assert_equal(1, File.lchmod(0444, @file))
+ assert_equal(0444, File.stat(@file).mode % 01000)
+ File.lchmod(0600, @file)
+ assert_raise(Errno::ENOENT) { File.lchmod(0600, @nofile) }
+ rescue NotImplementedError
+ end
+
+ def test_chown ## xxx
+ end
+
+ def test_lchown ## xxx
+ end
+
+ def test_symlink
+ return unless @symlinkfile
+ assert_equal("link", File.ftype(@symlinkfile))
+ assert_raise(Errno::EEXIST) { File.symlink(@file, @file) }
+ end
+
+ def test_utime
+ t = Time.local(2000)
+ File.utime(t + 1, t + 2, @zerofile)
+ assert_equal(t + 1, File.atime(@zerofile))
+ assert_equal(t + 2, File.mtime(@zerofile))
+ end
+
+ def test_hardlink
+ return unless @hardlinkfile
+ assert_equal("file", File.ftype(@hardlinkfile))
+ assert_raise(Errno::EEXIST) { File.link(@file, @file) }
+ end
+
+ def test_symlink2
+ return unless @symlinkfile
+ assert_equal(@file, File.readlink(@symlinkfile))
+ assert_raise(Errno::EINVAL) { File.readlink(@file) }
+ assert_raise(Errno::ENOENT) { File.readlink(@nofile) }
+ rescue NotImplementedError
+ end
+
+ def test_unlink
+ assert_equal(1, File.unlink(@file))
+ make_file("foo", @file)
+ assert_raise(Errno::ENOENT) { File.unlink(@nofile) }
+ end
+
+ def test_rename
+ assert_equal(0, File.rename(@file, @nofile))
+ assert(!(File.exist?(@file)))
+ assert(File.exist?(@nofile))
+ assert_equal(0, File.rename(@nofile, @file))
+ assert_raise(Errno::ENOENT) { File.rename(@nofile, @file) }
+ end
+
+ def test_umask
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ prev = File.umask(0777)
+ assert_equal(0777, File.umask)
+ open(@nofile, "w") { }
+ assert_equal(0, File.stat(@nofile).mode % 01000)
+ File.unlink(@nofile)
+ assert_equal(0777, File.umask(prev))
+ assert_raise(ArgumentError) { File.umask(0, 1, 2) }
+ end
+
+ def test_expand_path
+ assert_equal(@file, File.expand_path(File.basename(@file), File.dirname(@file)))
+ if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM
+ assert_equal(@file, File.expand_path(@file + " "))
+ assert_equal(@file, File.expand_path(@file + "."))
+ assert_equal(@file, File.expand_path(@file + "::$DATA"))
+ end
+ end
+
+ def test_basename
+ assert_equal(File.basename(@file).sub(/\.test$/, ""), File.basename(@file, ".test"))
+ assert_equal("", File.basename(""))
+ assert_equal("foo", File.basename("foo"))
+ assert_equal("foo", File.basename("foo", ".ext"))
+ assert_equal("foo", File.basename("foo.ext", ".ext"))
+ assert_equal("foo", File.basename("foo.ext", ".*"))
+ if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM
+ basename = File.basename(@file)
+ assert_equal(basename, File.basename(@file + " "))
+ assert_equal(basename, File.basename(@file + "."))
+ assert_equal(basename, File.basename(@file + "::$DATA"))
+ basename.chomp!(".test")
+ assert_equal(basename, File.basename(@file + " ", ".test"))
+ assert_equal(basename, File.basename(@file + ".", ".test"))
+ assert_equal(basename, File.basename(@file + "::$DATA", ".test"))
+ assert_equal(basename, File.basename(@file + " ", ".*"))
+ assert_equal(basename, File.basename(@file + ".", ".*"))
+ assert_equal(basename, File.basename(@file + "::$DATA", ".*"))
+ end
+ end
+
+ def test_dirname
+ assert(@file.start_with?(File.dirname(@file)))
+ assert_equal(".", File.dirname(""))
+ end
+
+ def test_extname
+ assert(".test", File.extname(@file))
+ assert_equal("", File.extname("foo"))
+ assert_equal("", File.extname("/foo"))
+ assert_equal("", File.extname(".foo"))
+ assert_equal("", File.extname("/.foo"))
+ assert_equal("", File.extname("bar/.foo"))
+ assert_equal("", File.extname("/bar/.foo"))
+ assert_equal(".ext", File.extname("foo.ext"))
+ assert_equal(".ext", File.extname("/foo.ext"))
+ assert_equal(".ext", File.extname(".foo.ext"))
+ assert_equal(".ext", File.extname("/.foo.ext"))
+ assert_equal(".ext", File.extname("bar/.foo.ext"))
+ assert_equal(".ext", File.extname("/bar/.foo.ext"))
+ assert_equal("", File.extname(""))
+ if /cygwin|mingw|mswin|bccwin/ =~ RUBY_PLATFORM
+ assert_equal("", File.extname("foo "))
+ assert_equal(".ext", File.extname("foo.ext "))
+ assert_equal(".ext", File.extname("foo.ext."))
+ assert_equal(".ext", File.extname("foo.ext::$DATA"))
+ assert_equal("", File.extname("foo::$DATA.ext"))
+ end
+ end
+
+ def test_split
+ d, b = File.split(@file)
+ assert_equal(File.dirname(@file), d)
+ assert_equal(File.basename(@file), b)
+ end
+
+ def test_join
+ s = "foo" + File::SEPARATOR + "bar" + File::SEPARATOR + "baz"
+ assert_equal(s, File.join("foo", "bar", "baz"))
+ assert_equal(s, File.join(["foo", "bar", "baz"]))
+ o = Object.new
+ def o.to_path; "foo"; end
+ assert_equal(s, File.join(o, "bar", "baz"))
+ assert_equal(s, File.join("foo" + File::SEPARATOR, "bar", File::SEPARATOR + "baz"))
+ end
+
+ def test_truncate
+ assert_equal(0, File.truncate(@file, 1))
+ assert(File.exist?(@file))
+ assert_equal(1, File.size(@file))
+ assert_equal(0, File.truncate(@file, 0))
+ assert(File.exist?(@file))
+ assert(File.zero?(@file))
+ make_file("foo", @file)
+ assert_raise(Errno::ENOENT) { File.truncate(@nofile, 0) }
+
+ f = File.new(@file, "w")
+ assert_equal(0, f.truncate(2))
+ assert(File.exist?(@file))
+ assert_equal(2, File.size(@file))
+ assert_equal(0, f.truncate(0))
+ assert(File.exist?(@file))
+ assert(File.zero?(@file))
+ f.close
+ make_file("foo", @file)
+
+ assert_raise(IOError) { File.new(@file).truncate(0) }
+ rescue NotImplementedError
+ end
+
+ def test_flock ## xxx
+ f = File.new(@file, "r+")
+ f.flock(File::LOCK_EX)
+ f.flock(File::LOCK_SH)
+ f.flock(File::LOCK_UN)
+ f.close
+ rescue NotImplementedError
+ end
+
+ def test_test
+ sleep(@time - Time.now + 1.1)
+ make_file("foo", @file + "2")
+ [@dir, @file, @zerofile, @symlinkfile, @hardlinkfile].compact.each do |f|
+ assert_equal(File.atime(f), test(?A, f))
+ assert_equal(File.ctime(f), test(?C, f))
+ assert_equal(File.mtime(f), test(?M, f))
+ assert_equal(File.blockdev?(f), test(?b, f))
+ assert_equal(File.chardev?(f), test(?c, f))
+ assert_equal(File.directory?(f), test(?d, f))
+ assert_equal(File.exist?(f), test(?e, f))
+ assert_equal(File.file?(f), test(?f, f))
+ assert_equal(File.setgid?(f), test(?g, f))
+ assert_equal(File.grpowned?(f), test(?G, f))
+ assert_equal(File.sticky?(f), test(?k, f))
+ assert_equal(File.symlink?(f), test(?l, f))
+ assert_equal(File.owned?(f), test(?o, f))
+ assert_nothing_raised { test(?O, f) }
+ assert_equal(File.pipe?(f), test(?p, f))
+ assert_equal(File.readable?(f), test(?r, f))
+ assert_equal(File.readable_real?(f), test(?R, f))
+ assert_equal(File.size?(f), test(?s, f))
+ assert_equal(File.socket?(f), test(?S, f))
+ assert_equal(File.setuid?(f), test(?u, f))
+ assert_equal(File.writable?(f), test(?w, f))
+ assert_equal(File.world_writable?(f), test(?W, f))
+ assert_equal(File.executable?(f), test(?x, f))
+ assert_equal(File.executable_real?(f), test(?X, f))
+ assert_equal(File.zero?(f), test(?z, f))
+ end
+ assert_equal(false, test(?-, @dir, @file))
+ assert_equal(true, test(?-, @file, @file))
+ assert_equal(true, test(?=, @file, @file))
+ assert_equal(false, test(?>, @file, @file))
+ assert_equal(false, test(?<, @file, @file))
+ unless /cygwin/ =~ RUBY_PLATFORM
+ assert_equal(false, test(?=, @file, @file + "2"))
+ assert_equal(false, test(?>, @file, @file + "2"))
+ assert_equal(true, test(?>, @file + "2", @file))
+ assert_equal(true, test(?<, @file, @file + "2"))
+ assert_equal(false, test(?<, @file + "2", @file))
+ end
+ assert_raise(ArgumentError) { test }
+ assert_raise(Errno::ENOENT) { test(?A, @nofile) }
+ assert_raise(ArgumentError) { test(?a) }
+ assert_raise(ArgumentError) { test("\0".ord) }
+ end
+
+ def test_stat_init
+ sleep(@time - Time.now + 1.1)
+ make_file("foo", @file + "2")
+ fs1, fs2 = File::Stat.new(@file), File::Stat.new(@file + "2")
+ assert_nothing_raised do
+ assert_equal(0, fs1 <=> fs1)
+ assert_equal(-1, fs1 <=> fs2)
+ assert_equal(1, fs2 <=> fs1)
+ assert_nil(fs1 <=> nil)
+ assert_integer(fs1.dev)
+ assert_integer_or_nil(fs1.rdev)
+ assert_integer_or_nil(fs1.dev_major)
+ assert_integer_or_nil(fs1.dev_minor)
+ assert_integer_or_nil(fs1.rdev_major)
+ assert_integer_or_nil(fs1.rdev_minor)
+ assert_integer(fs1.ino)
+ assert_integer(fs1.mode)
+ unless /emx/ =~ RUBY_PLATFORM
+ assert_equal(@hardlinkfile ? 2 : 1, fs1.nlink)
+ end
+ assert_integer(fs1.uid)
+ assert_integer(fs1.gid)
+ assert_equal(3, fs1.size)
+ assert_integer_or_nil(fs1.blksize)
+ assert_integer_or_nil(fs1.blocks)
+ assert_kind_of(Time, fs1.atime)
+ assert_kind_of(Time, fs1.mtime)
+ assert_kind_of(Time, fs1.ctime)
+ assert_kind_of(String, fs1.inspect)
+ end
+ assert_raise(Errno::ENOENT) { File::Stat.new(@nofile) }
+ assert_kind_of(File::Stat, File::Stat.new(@file).dup)
+ assert_raise(TypeError) do
+ File::Stat.new(@file).instance_eval { initialize_copy(0) }
+ end
+ end
+
+ def test_stat_ftype
+ assert_equal("directory", File::Stat.new(@dir).ftype)
+ assert_equal("file", File::Stat.new(@file).ftype)
+ # File::Stat uses stat
+ assert_equal("file", File::Stat.new(@symlinkfile).ftype) if @symlinkfile
+ assert_equal("file", File::Stat.new(@hardlinkfile).ftype) if @hardlinkfile
+ end
+
+ def test_stat_directory_p
+ assert(File::Stat.new(@dir).directory?)
+ assert(!(File::Stat.new(@file).directory?))
+ end
+
+ def test_stat_pipe_p ## xxx
+ assert(!(File::Stat.new(@dir).pipe?))
+ assert(!(File::Stat.new(@file).pipe?))
+ end
+
+ def test_stat_symlink_p
+ assert(!(File::Stat.new(@dir).symlink?))
+ assert(!(File::Stat.new(@file).symlink?))
+ # File::Stat uses stat
+ assert(!(File::Stat.new(@symlinkfile).symlink?)) if @symlinkfile
+ assert(!(File::Stat.new(@hardlinkfile).symlink?)) if @hardlinkfile
+ end
+
+ def test_stat_socket_p ## xxx
+ assert(!(File::Stat.new(@dir).socket?))
+ assert(!(File::Stat.new(@file).socket?))
+ end
+
+ def test_stat_blockdev_p ## xxx
+ assert(!(File::Stat.new(@dir).blockdev?))
+ assert(!(File::Stat.new(@file).blockdev?))
+ end
+
+ def test_stat_chardev_p ## xxx
+ assert(!(File::Stat.new(@dir).chardev?))
+ assert(!(File::Stat.new(@file).chardev?))
+ end
+
+ def test_stat_readable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0200, @file)
+ assert(!(File::Stat.new(@file).readable?))
+ File.chmod(0600, @file)
+ assert(File::Stat.new(@file).readable?)
+ end
+
+ def test_stat_readable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0200, @file)
+ assert(!(File::Stat.new(@file).readable_real?))
+ File.chmod(0600, @file)
+ assert(File::Stat.new(@file).readable_real?)
+ end
+
+ def test_stat_world_readable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0006, @file)
+ assert(File::Stat.new(@file).world_readable?)
+ File.chmod(0060, @file)
+ assert(!(File::Stat.new(@file).world_readable?))
+ File.chmod(0600, @file)
+ assert(!(File::Stat.new(@file).world_readable?))
+ end
+
+ def test_stat_writable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0400, @file)
+ assert(!(File::Stat.new(@file).writable?))
+ File.chmod(0600, @file)
+ assert(File::Stat.new(@file).writable?)
+ end
+
+ def test_stat_writable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0400, @file)
+ assert(!(File::Stat.new(@file).writable_real?))
+ File.chmod(0600, @file)
+ assert(File::Stat.new(@file).writable_real?)
+ end
+
+ def test_stat_world_writable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0006, @file)
+ assert(File::Stat.new(@file).world_writable?)
+ File.chmod(0060, @file)
+ assert(!(File::Stat.new(@file).world_writable?))
+ File.chmod(0600, @file)
+ assert(!(File::Stat.new(@file).world_writable?))
+ end
+
+ def test_stat_executable_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0100, @file)
+ assert(File::Stat.new(@file).executable?)
+ File.chmod(0600, @file)
+ assert(!(File::Stat.new(@file).executable?))
+ end
+
+ def test_stat_executable_real_p
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ File.chmod(0100, @file)
+ assert(File::Stat.new(@file).executable_real?)
+ File.chmod(0600, @file)
+ assert(!(File::Stat.new(@file).executable_real?))
+ end
+
+ def test_stat_file_p
+ assert(!(File::Stat.new(@dir).file?))
+ assert(File::Stat.new(@file).file?)
+ end
+
+ def test_stat_zero_p
+ assert_nothing_raised { File::Stat.new(@dir).zero? }
+ assert(!(File::Stat.new(@file).zero?))
+ assert(File::Stat.new(@zerofile).zero?)
+ end
+
+ def test_stat_size_p
+ assert_nothing_raised { File::Stat.new(@dir).size? }
+ assert_equal(3, File::Stat.new(@file).size?)
+ assert(!(File::Stat.new(@zerofile).size?))
+ end
+
+ def test_stat_owned_p ## xxx
+ return if /cygwin|mswin|bccwin|mingw|emx/ =~ RUBY_PLATFORM
+ assert(File::Stat.new(@file).owned?)
+ assert(File::Stat.new(@file).grpowned?)
+ end
+
+ def test_stat_suid_sgid_sticky ## xxx
+ assert(!(File::Stat.new(@file).setuid?))
+ assert(!(File::Stat.new(@file).setgid?))
+ assert(!(File::Stat.new(@file).sticky?))
+ end
+
+ def test_stat_size
+ assert_integer(File::Stat.new(@dir).size)
+ assert_equal(3, File::Stat.new(@file).size)
+ assert_equal(0, File::Stat.new(@zerofile).size)
+ end
+
+ def test_path_check
+ assert_nothing_raised { ENV["PATH"] }
+ end
+
+ def test_find_file
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ load(@file)
+ end.join
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_fixnum.rb b/trunk/test/ruby/test_fixnum.rb
new file mode 100644
index 0000000000..8fa751ba98
--- /dev/null
+++ b/trunk/test/ruby/test_fixnum.rb
@@ -0,0 +1,241 @@
+require 'test/unit'
+
+class TestFixnum < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_pow
+ [1, 2, 2**64, 2**63*3, 2**64*3].each do |y|
+ [-1, 0, 1].each do |x|
+ z1 = x**y
+ z2 = (-x)**y
+ if y % 2 == 1
+ assert_equal(z2, -z1)
+ else
+ assert_equal(z2, z1)
+ end
+ end
+ end
+ end
+
+ def test_succ
+ assert_equal(0x40000000, 0x3fffffff.succ, "[ruby-dev:31189]")
+ assert_equal(0x4000000000000000, 0x3fffffffffffffff.succ, "[ruby-dev:31190]")
+ end
+
+ def test_pred
+ assert_equal(-0x40000001, (-0x40000000).pred)
+ assert_equal(-0x4000000000000001, (-0x4000000000000000).pred)
+ end
+
+ def test_plus
+ assert_equal(0x40000000, 0x3fffffff+1)
+ assert_equal(0x4000000000000000, 0x3fffffffffffffff+1)
+ assert_equal(-0x40000001, (-0x40000000)+(-1))
+ assert_equal(-0x4000000000000001, (-0x4000000000000000)+(-1))
+ assert_equal(-0x80000000, (-0x40000000)+(-0x40000000))
+ end
+
+ def test_sub
+ assert_equal(0x40000000, 0x3fffffff-(-1))
+ assert_equal(0x4000000000000000, 0x3fffffffffffffff-(-1))
+ assert_equal(-0x40000001, (-0x40000000)-1)
+ assert_equal(-0x4000000000000001, (-0x4000000000000000)-1)
+ assert_equal(-0x80000000, (-0x40000000)-0x40000000)
+ end
+
+ def test_mult
+ assert_equal(0x40000000, 0x20000000*2)
+ assert_equal(0x4000000000000000, 0x2000000000000000*2)
+ assert_equal(-0x40000001, 33025*(-32513))
+ assert_equal(-0x4000000000000001, 1380655685*(-3340214413))
+ assert_equal(0x40000000, (-0x40000000)*(-1))
+ end
+
+ def test_div
+ assert_equal(2, 5/2)
+ assert_equal(0, 1/2)
+ assert_equal(-1, -1/2)
+ assert_equal(0, -(1/2))
+ assert_equal(-1, (-1)/2)
+ assert_equal(0, (-1)/(-2))
+ assert_equal(-1, 1/(-2))
+ assert_equal(1, -(1/(-2)))
+ assert_equal(0x3fffffff, 0xbffffffd/3)
+ assert_equal(0x40000000, 0xc0000000/3)
+ assert_equal(0x4000000000000000, 0xc000000000000000/3)
+ assert_equal(-0x40000001, 0xc0000003/(-3))
+ assert_equal(-0x4000000000000001, 0xc000000000000003/(-3))
+ assert_equal(0x40000000, (-0x40000000)/(-1), "[ruby-dev:31210]")
+ assert_equal(0x4000000000000000, (-0x4000000000000000)/(-1))
+ end
+
+ def test_mod
+ assert_equal(2, (-0x40000000) % 3)
+ assert_equal(0, (-0x40000000) % (-1))
+ end
+
+ def test_divmod
+ (-5).upto(5) {|a|
+ (-5).upto(5) {|b|
+ next if b == 0
+ q, r = a.divmod(b)
+ assert_equal(a, b*q+r)
+ assert(r.abs < b.abs)
+ assert(0 < b ? (0 <= r && r < b) : (b < r && r <= 0))
+ assert_equal(q, a/b)
+ assert_equal(q, a.div(b))
+ assert_equal(r, a%b)
+ assert_equal(r, a.modulo(b))
+ }
+ }
+ end
+
+ def test_not
+ assert_equal(-0x40000000, ~0x3fffffff)
+ assert_equal(0x3fffffff, ~-0x40000000)
+ end
+
+ def test_lshift
+ assert_equal(0x40000000, 0x20000000<<1)
+ assert_equal(-0x40000000, (-0x20000000)<<1)
+ assert_equal(-0x80000000, (-0x40000000)<<1)
+ end
+
+ def test_rshift
+ assert_equal(0x20000000, 0x40000000>>1)
+ assert_equal(-0x20000000, (-0x40000000)>>1)
+ assert_equal(-0x40000000, (-0x80000000)>>1)
+ end
+
+ def test_abs
+ assert_equal(0x40000000, (-0x40000000).abs)
+ assert_equal(0x4000000000000000, (-0x4000000000000000).abs)
+ end
+
+ def test_induced_from
+ assert_equal(1, Fixnum.induced_from(1))
+ assert_raise(RangeError) do
+ Fixnum.induced_from(2**31-1)
+ Fixnum.induced_from(2**63-1)
+ end
+ assert_equal(1, Fixnum.induced_from((2**32).coerce(1).first))
+ end
+
+ def test_to_s
+ assert_equal("1010", 10.to_s(2))
+ assert_equal("a", 10.to_s(36))
+ assert_raise(ArgumentError) { 10.to_s(1) }
+ end
+
+ def test_plus2
+ assert_equal(2, 1 + 1)
+ assert_equal(4294967297, 1 + 2**32)
+ assert_equal(2.0, 1 + 1.0)
+ assert_raise(TypeError) { 1 + nil }
+ end
+
+ def test_minus
+ assert_equal(0, 1 - 1)
+ assert_equal(-4294967295, 1 - 2**32)
+ assert_equal(0.0, 1 - 1.0)
+ assert_raise(TypeError) { 1 - nil }
+ end
+
+ def test_mul
+ assert_equal(6, 2.send(:*, 3))
+ a = 2**30-1
+ assert_equal(1152921502459363329, a.send(:*, a))
+
+ assert_equal(6.0, 2 * 3.0)
+ assert_raise(TypeError) { 2 * nil }
+ end
+
+ def test_divide
+ assert_equal(2.0, 4.quo(2))
+ assert_equal(2.0, 4 / 2)
+ assert_equal(2.0, 4.div(2))
+
+ assert_equal(0.5**32, 1.quo(2**32))
+ assert_equal(0, 1 / (2**32))
+ assert_equal(0, 1.div(2**32))
+
+ assert_equal(0.5, 1.quo(2.0))
+ assert_equal(0.5, 1 / 2.0)
+ assert_equal(0, 1.div(2.0))
+
+ ### rational changes the behavior of Fixnum#quo
+ #assert_raise(TypeError) { 2.quo(nil) }
+ assert_raise(TypeError, NoMethodError) { 2.quo(nil) }
+ assert_raise(TypeError) { 2 / nil }
+ assert_raise(TypeError) { 2.div(nil) }
+
+ assert_equal(0, 4.modulo(2))
+ assert_equal(1, 1.modulo(2**32))
+ assert_equal(1, 1.modulo(2.0))
+ assert_raise(TypeError) { 2.modulo(nil) }
+
+ assert_equal([2, 0], 4.divmod(2))
+ assert_equal([0, 1], 1.divmod(2**32))
+ assert_equal([0, 1], 1.divmod(2.0))
+ assert_raise(TypeError) { 2.divmod(nil) }
+ end
+
+ def test_pow2
+ assert_equal(65536, 2**16)
+ assert_equal(4294967296, 2**32)
+ assert_equal(0.5**16, 2**-16)
+ assert_equal(1, (-1)**4294967296)
+ assert_equal(-1, (-1)**4294967295)
+ assert_equal(4, 2**((2**32).coerce(2).first))
+ assert_equal(2, 4**0.5)
+ assert_equal(0, 0**0.5)
+ assert((0**-1.0).infinite?)
+ ### rational changes the behavior of Fixnum#**
+ #assert_raise(TypeError) { 1 ** nil }
+ assert_raise(TypeError, NoMethodError) { 1 ** nil }
+ end
+
+ def test_cmp
+ assert(1 != nil)
+
+ assert_equal(0, 1 <=> 1)
+ assert_equal(-1, 1 <=> 4294967296)
+ assert_equal(0, 1 <=> 1.0)
+ assert_nil(1 <=> nil)
+
+ assert(1.send(:>, 0))
+ assert(!(1.send(:>, 1)))
+ assert(!(1.send(:>, 2)))
+ assert(!(1.send(:>, 4294967296)))
+ assert(1.send(:>, 0.0))
+ assert_raise(ArgumentError) { 1.send(:>, nil) }
+
+ assert(1.send(:>=, 0))
+ assert(1.send(:>=, 1))
+ assert(!(1.send(:>=, 2)))
+ assert(!(1.send(:>=, 4294967296)))
+ assert(1.send(:>=, 0.0))
+ assert_raise(ArgumentError) { 1.send(:>=, nil) }
+
+ assert(!(1.send(:<, 0)))
+ assert(!(1.send(:<, 1)))
+ assert(1.send(:<, 2))
+ assert(1.send(:<, 4294967296))
+ assert(!(1.send(:<, 0.0)))
+ assert_raise(ArgumentError) { 1.send(:<, nil) }
+
+ assert(!(1.send(:<=, 0)))
+ assert(1.send(:<=, 1))
+ assert(1.send(:<=, 2))
+ assert(1.send(:<=, 4294967296))
+ assert(!(1.send(:<=, 0.0)))
+ assert_raise(ArgumentError) { 1.send(:<=, nil) }
+ end
+end
diff --git a/trunk/test/ruby/test_float.rb b/trunk/test/ruby/test_float.rb
new file mode 100644
index 0000000000..d4bbd688d2
--- /dev/null
+++ b/trunk/test/ruby/test_float.rb
@@ -0,0 +1,433 @@
+require 'test/unit'
+
+class TestFloat < Test::Unit::TestCase
+ def test_float
+ assert_equal(2, 2.6.floor)
+ assert_equal(-3, (-2.6).floor)
+ assert_equal(3, 2.6.ceil)
+ assert_equal(-2, (-2.6).ceil)
+ assert_equal(2, 2.6.truncate)
+ assert_equal(-2, (-2.6).truncate)
+ assert_equal(3, 2.6.round)
+ assert_equal(-2, (-2.4).truncate)
+ assert((13.4 % 1 - 0.4).abs < 0.0001)
+ assert_equal(36893488147419111424,
+ 36893488147419107329.0.to_i)
+ end
+
+ def nan_test(x,y)
+ extend Test::Unit::Assertions
+ assert(x != y)
+ assert_equal(false, (x < y))
+ assert_equal(false, (x > y))
+ assert_equal(false, (x <= y))
+ assert_equal(false, (x >= y))
+ end
+ def test_nan
+ nan = 0.0/0
+ nan_test(nan, nan)
+ nan_test(nan, 0)
+ nan_test(nan, 1)
+ nan_test(nan, -1)
+ nan_test(nan, 1000)
+ nan_test(nan, -1000)
+ nan_test(nan, 1_000_000_000_000)
+ nan_test(nan, -1_000_000_000_000)
+ nan_test(nan, 100.0);
+ nan_test(nan, -100.0);
+ nan_test(nan, 0.001);
+ nan_test(nan, -0.001);
+ nan_test(nan, 1.0/0);
+ nan_test(nan, -1.0/0);
+ end
+
+ def test_precision
+ u = 3.7517675036461267e+17
+ v = sprintf("%.16e", u).to_f
+ assert_in_delta(u, v, u.abs * Float::EPSILON)
+ assert_in_delta(u, v, v.abs * Float::EPSILON)
+ end
+
+ def test_symmetry_bignum # [ruby-bugs-ja:118]
+ a = 100000000000000000000000
+ b = 100000000000000000000000.0
+ assert_equal(a == b, b == a)
+ end
+
+ def test_strtod
+ a = Float("0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("0.0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("+0.0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("-0.0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("0.0000000000000000001")
+ assert(a != 0.0)
+ a = Float("+0.0000000000000000001")
+ assert(a != 0.0)
+ a = Float("-0.0000000000000000001")
+ assert(a != 0.0)
+ a = Float(".0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("+.0")
+ assert(a.abs < Float::EPSILON)
+ a = Float("-.0")
+ assert(a.abs < Float::EPSILON)
+ assert_raise(ArgumentError){Float("0.")}
+ assert_raise(ArgumentError){Float("+0.")}
+ assert_raise(ArgumentError){Float("-0.")}
+ assert_raise(ArgumentError){Float(".")}
+ assert_raise(ArgumentError){Float("+")}
+ assert_raise(ArgumentError){Float("+.")}
+ assert_raise(ArgumentError){Float("-")}
+ assert_raise(ArgumentError){Float("-.")}
+ assert_raise(ArgumentError){Float("1e")}
+ assert_raise(ArgumentError){Float("1__1")}
+ # add expected behaviour here.
+ assert_equal(10, Float("1_0"))
+ end
+
+ def test_divmod
+ assert_equal([2, 3.5], 11.5.divmod(4))
+ assert_equal([-3, -0.5], 11.5.divmod(-4))
+ assert_equal([-3, 0.5], (-11.5).divmod(4))
+ assert_equal([2, -3.5], (-11.5).divmod(-4))
+ end
+
+ def test_div
+ assert_equal(2, 11.5.div(4))
+ assert_equal(-3, 11.5.div(-4))
+ assert_equal(-3, (-11.5).div(4))
+ assert_equal(2, (-11.5).div(-4))
+ end
+
+ def test_modulo
+ assert_equal(3.5, 11.5.modulo(4))
+ assert_equal(-0.5, 11.5.modulo(-4))
+ assert_equal(0.5, (-11.5).modulo(4))
+ assert_equal(-3.5, (-11.5).modulo(-4))
+ end
+
+ def test_remainder
+ assert_equal(3.5, 11.5.remainder(4))
+ assert_equal(3.5, 11.5.remainder(-4))
+ assert_equal(-3.5, (-11.5).remainder(4))
+ assert_equal(-3.5, (-11.5).remainder(-4))
+ end
+
+ def test_to_s
+ inf = 1.0 / 0.0
+ assert_equal("Infinity", inf.to_s)
+ assert_equal("-Infinity", (-inf).to_s)
+ assert_equal("NaN", (inf / inf).to_s)
+
+ assert_equal("1.0e+14", 10000_00000_00000.0.to_s)
+ end
+
+ def test_coerce
+ assert_equal(Float, 1.0.coerce(1).first.class)
+ end
+
+ def test_plus
+ assert_equal(4.0, 2.0.send(:+, 2))
+ assert_equal(4.0, 2.0.send(:+, (2**32).coerce(2).first))
+ assert_equal(4.0, 2.0.send(:+, 2.0))
+ assert_raise(TypeError) { 2.0.send(:+, nil) }
+ end
+
+ def test_minus
+ assert_equal(0.0, 2.0.send(:-, 2))
+ assert_equal(0.0, 2.0.send(:-, (2**32).coerce(2).first))
+ assert_equal(0.0, 2.0.send(:-, 2.0))
+ assert_raise(TypeError) { 2.0.send(:-, nil) }
+ end
+
+ def test_mul
+ assert_equal(4.0, 2.0.send(:*, 2))
+ assert_equal(4.0, 2.0.send(:*, (2**32).coerce(2).first))
+ assert_equal(4.0, 2.0.send(:*, 2.0))
+ assert_raise(TypeError) { 2.0.send(:*, nil) }
+ end
+
+ def test_div2
+ assert_equal(1.0, 2.0.send(:/, 2))
+ assert_equal(1.0, 2.0.send(:/, (2**32).coerce(2).first))
+ assert_equal(1.0, 2.0.send(:/, 2.0))
+ assert_raise(TypeError) { 2.0.send(:/, nil) }
+ end
+
+ def test_modulo2
+ assert_equal(0.0, 2.0.send(:%, 2))
+ assert_equal(0.0, 2.0.send(:%, (2**32).coerce(2).first))
+ assert_equal(0.0, 2.0.send(:%, 2.0))
+ assert_raise(TypeError) { 2.0.send(:%, nil) }
+ end
+
+ def test_divmod2
+ assert_equal([1.0, 0.0], 2.0.divmod(2))
+ assert_equal([1.0, 0.0], 2.0.divmod((2**32).coerce(2).first))
+ assert_equal([1.0, 0.0], 2.0.divmod(2.0))
+ assert_raise(TypeError) { 2.0.divmod(nil) }
+
+ inf = 1.0 / 0.0
+ a, b = inf.divmod(0)
+ assert(a.infinite?)
+ assert(b.nan?)
+
+ a, b = (2.0**32).divmod(1.0)
+ assert_equal(2**32, a)
+ assert_equal(0, b)
+ end
+
+ def test_pow
+ assert_equal(1.0, 1.0 ** (2**32))
+ assert_equal(1.0, 1.0 ** 1.0)
+ assert_raise(TypeError) { 1.0 ** nil }
+ end
+
+ def test_eql
+ inf = 1.0 / 0.0
+ nan = inf / inf
+ assert(1.0.eql?(1.0))
+ assert(inf.eql?(inf))
+ assert(!(nan.eql?(nan)))
+ assert(!(1.0.eql?(nil)))
+
+ assert(1.0 == 1)
+ assert(1.0 != 2**32)
+ assert(1.0 != nan)
+ assert(1.0 != nil)
+ end
+
+ def test_cmp
+ inf = 1.0 / 0.0
+ nan = inf / inf
+ assert_equal(0, 1.0 <=> 1.0)
+ assert_equal(1, 1.0 <=> 0.0)
+ assert_equal(-1, 1.0 <=> 2.0)
+ assert_nil(1.0 <=> nil)
+ assert_nil(1.0 <=> nan)
+ assert_nil(nan <=> 1.0)
+
+ assert_equal(0, 1.0 <=> 1)
+ assert_equal(1, 1.0 <=> 0)
+ assert_equal(-1, 1.0 <=> 2)
+
+ assert_equal(-1, 1.0 <=> 2**32)
+
+ assert_raise(ArgumentError) { 1.0 > nil }
+ assert_raise(ArgumentError) { 1.0 >= nil }
+ assert_raise(ArgumentError) { 1.0 < nil }
+ assert_raise(ArgumentError) { 1.0 <= nil }
+ end
+
+ def test_zero_p
+ assert(0.0.zero?)
+ assert(!(1.0.zero?))
+ end
+
+ def test_infinite_p
+ inf = 1.0 / 0.0
+ assert(1, inf.infinite?)
+ assert(1, (-inf).infinite?)
+ assert_nil(1.0.infinite?)
+ end
+
+ def test_finite_p
+ inf = 1.0 / 0.0
+ assert(!(inf.finite?))
+ assert(!((-inf).finite?))
+ assert(1.0.finite?)
+ end
+
+ def test_floor_ceil_round_truncate
+ assert_equal(1, 1.5.floor)
+ assert_equal(2, 1.5.ceil)
+ assert_equal(2, 1.5.round)
+ assert_equal(1, 1.5.truncate)
+
+ assert_equal(2, 2.0.floor)
+ assert_equal(2, 2.0.ceil)
+ assert_equal(2, 2.0.round)
+ assert_equal(2, 2.0.truncate)
+
+ assert_equal(-2, (-1.5).floor)
+ assert_equal(-1, (-1.5).ceil)
+ assert_equal(-2, (-1.5).round)
+ assert_equal(-1, (-1.5).truncate)
+
+ assert_equal(-2, (-2.0).floor)
+ assert_equal(-2, (-2.0).ceil)
+ assert_equal(-2, (-2.0).round)
+ assert_equal(-2, (-2.0).truncate)
+
+ inf = 1.0/0.0
+ assert_raise(FloatDomainError) { inf.floor }
+ assert_raise(FloatDomainError) { inf.ceil }
+ assert_raise(FloatDomainError) { inf.round }
+ assert_raise(FloatDomainError) { inf.truncate }
+
+ assert_equal(1.100, 1.111.round(1))
+ assert_equal(1.110, 1.111.round(2))
+ assert_equal(11110.0, 11111.1.round(-1))
+ assert_equal(11100.0, 11111.1.round(-2))
+ end
+
+ def test_induced_from
+ assert_equal(1.0, Float.induced_from(1))
+ assert_equal(1.0, Float.induced_from(1.0))
+ assert_raise(TypeError) { Float.induced_from(nil) }
+ end
+
+
+ VS = [
+ 18446744073709551617.0,
+ 18446744073709551616.0,
+ 18446744073709551615.8,
+ 18446744073709551615.5,
+ 18446744073709551615.2,
+ 18446744073709551615.0,
+ 18446744073709551614.0,
+
+ 4611686018427387905.0,
+ 4611686018427387904.0,
+ 4611686018427387903.8,
+ 4611686018427387903.5,
+ 4611686018427387903.2,
+ 4611686018427387903.0,
+ 4611686018427387902.0,
+
+ 4294967297.0,
+ 4294967296.0,
+ 4294967295.8,
+ 4294967295.5,
+ 4294967295.2,
+ 4294967295.0,
+ 4294967294.0,
+
+ 1073741825.0,
+ 1073741824.0,
+ 1073741823.8,
+ 1073741823.5,
+ 1073741823.2,
+ 1073741823.0,
+ 1073741822.0,
+
+ -1073741823.0,
+ -1073741824.0,
+ -1073741824.2,
+ -1073741824.5,
+ -1073741824.8,
+ -1073741825.0,
+ -1073741826.0,
+
+ -4294967295.0,
+ -4294967296.0,
+ -4294967296.2,
+ -4294967296.5,
+ -4294967296.8,
+ -4294967297.0,
+ -4294967298.0,
+
+ -4611686018427387903.0,
+ -4611686018427387904.0,
+ -4611686018427387904.2,
+ -4611686018427387904.5,
+ -4611686018427387904.8,
+ -4611686018427387905.0,
+ -4611686018427387906.0,
+
+ -18446744073709551615.0,
+ -18446744073709551616.0,
+ -18446744073709551616.2,
+ -18446744073709551616.5,
+ -18446744073709551616.8,
+ -18446744073709551617.0,
+ -18446744073709551618.0,
+ ]
+
+ def test_truncate
+ VS.each {|f|
+ i = f.truncate
+ assert_equal(i, f.to_i)
+ if f < 0
+ assert_operator(i, :<, 0)
+ else
+ assert_operator(i, :>, 0)
+ end
+ assert_operator(i.abs, :<=, f.abs)
+ d = f.abs - i.abs
+ assert_operator(0, :<=, d)
+ assert_operator(d, :<, 1)
+ }
+ end
+
+ def test_ceil
+ VS.each {|f|
+ i = f.ceil
+ if f < 0
+ assert_operator(i, :<, 0)
+ else
+ assert_operator(i, :>, 0)
+ end
+ assert_operator(i, :>=, f)
+ d = f - i
+ assert_operator(-1, :<, d)
+ assert_operator(d, :<=, 0)
+ }
+ end
+
+ def test_floor
+ VS.each {|f|
+ i = f.floor
+ if f < 0
+ assert_operator(i, :<, 0)
+ else
+ assert_operator(i, :>, 0)
+ end
+ assert_operator(i, :<=, f)
+ d = f - i
+ assert_operator(0, :<=, d)
+ assert_operator(d, :<, 1)
+ }
+ end
+
+ def test_round
+ VS.each {|f|
+ i = f.round
+ if f < 0
+ assert_operator(i, :<, 0)
+ else
+ assert_operator(i, :>, 0)
+ end
+ d = f - i
+ assert_operator(-0.5, :<=, d)
+ assert_operator(d, :<=, 0.5)
+ }
+ end
+
+ def test_Float
+ assert_in_delta(0.125, Float("0.1_2_5"), 0.00001)
+ assert_in_delta(0.125, "0.1_2_5__".to_f, 0.00001)
+ assert(Float(([1] * 10000).join).infinite?)
+ assert(!Float(([1] * 10000).join("_")).infinite?) # is it really OK?
+ assert_raise(ArgumentError) { Float("1.0\x001") }
+ assert(Float("1e10_00").infinite?)
+ assert_raise(TypeError) { Float(nil) }
+ o = Object.new
+ def o.to_f; inf = 1.0/0.0; inf/inf; end
+ assert(Float(o).nan?)
+ end
+
+ def test_num2dbl
+ assert_raise(TypeError) do
+ 1.0.step(2.0, "0.5") {}
+ end
+ assert_raise(TypeError) do
+ 1.0.step(2.0, nil) {}
+ end
+ end
+
+end
diff --git a/trunk/test/ruby/test_fnmatch.rb b/trunk/test/ruby/test_fnmatch.rb
new file mode 100644
index 0000000000..1c1a158477
--- /dev/null
+++ b/trunk/test/ruby/test_fnmatch.rb
@@ -0,0 +1,104 @@
+require 'test/unit'
+
+class TestFnmatch < Test::Unit::TestCase
+
+ def bracket_test(s, t) # `s' should start with neither '!' nor '^'
+ 0x21.upto(0x7E) do |i|
+ assert_equal(t.include?(i.chr), File.fnmatch("[#{s}]", i.chr, File::FNM_DOTMATCH))
+ assert_equal(t.include?(i.chr), !File.fnmatch("[^#{s}]", i.chr, File::FNM_DOTMATCH))
+ assert_equal(t.include?(i.chr), !File.fnmatch("[!#{s}]", i.chr, File::FNM_DOTMATCH))
+ end
+ end
+ def test_fnmatch
+ assert(File.fnmatch('\[1\]' , '[1]'), "[ruby-dev:22819]")
+ assert(File.fnmatch('*?', 'a'), "[ruby-dev:22815]")
+ assert(File.fnmatch('*/', 'a/'))
+ assert(File.fnmatch('\[1\]' , '[1]', File::FNM_PATHNAME))
+ assert(File.fnmatch('*?', 'a', File::FNM_PATHNAME))
+ assert(File.fnmatch('*/', 'a/', File::FNM_PATHNAME))
+ # text
+ assert(File.fnmatch('cat', 'cat'))
+ assert(!File.fnmatch('cat', 'category'))
+ assert(!File.fnmatch('cat', 'wildcat'))
+ # '?' matches any one character
+ assert(File.fnmatch('?at', 'cat'))
+ assert(File.fnmatch('c?t', 'cat'))
+ assert(File.fnmatch('ca?', 'cat'))
+ assert(File.fnmatch('?a?', 'cat'))
+ assert(!File.fnmatch('c??t', 'cat'))
+ assert(!File.fnmatch('??at', 'cat'))
+ assert(!File.fnmatch('ca??', 'cat'))
+ # '*' matches any number (including 0) of any characters
+ assert(File.fnmatch('c*', 'cats'))
+ assert(File.fnmatch('c*ts', 'cats'))
+ assert(File.fnmatch('*ts', 'cats'))
+ assert(File.fnmatch('*c*a*t*s*', 'cats'))
+ assert(!File.fnmatch('c*t', 'cats'))
+ assert(!File.fnmatch('*abc', 'abcabz'))
+ assert(File.fnmatch('*abz', 'abcabz'))
+ assert(!File.fnmatch('a*abc', 'abc'))
+ assert(File.fnmatch('a*bc', 'abc'))
+ assert(!File.fnmatch('a*bc', 'abcd'))
+ # [seq] : matches any character listed between bracket
+ # [!seq] or [^seq] : matches any character except those listed between bracket
+ bracket_test("bd-gikl-mosv-x", "bdefgiklmosvwx")
+ # escaping character
+ assert(File.fnmatch('\?', '?'))
+ assert(!File.fnmatch('\?', '\?'))
+ assert(!File.fnmatch('\?', 'a'))
+ assert(!File.fnmatch('\?', '\a'))
+ assert(File.fnmatch('\*', '*'))
+ assert(!File.fnmatch('\*', '\*'))
+ assert(!File.fnmatch('\*', 'cats'))
+ assert(!File.fnmatch('\*', '\cats'))
+ assert(File.fnmatch('\a', 'a'))
+ assert(!File.fnmatch('\a', '\a'))
+ assert(File.fnmatch('[a\-c]', 'a'))
+ assert(File.fnmatch('[a\-c]', '-'))
+ assert(File.fnmatch('[a\-c]', 'c'))
+ assert(!File.fnmatch('[a\-c]', 'b'))
+ assert(!File.fnmatch('[a\-c]', '\\'))
+ # escaping character loses its meaning if FNM_NOESCAPE is set
+ assert(!File.fnmatch('\?', '?', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\?', '\?', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('\?', 'a', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\?', '\a', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('\*', '*', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\*', '\*', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('\*', 'cats', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\*', '\cats', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('\a', 'a', File::FNM_NOESCAPE))
+ assert(File.fnmatch('\a', '\a', File::FNM_NOESCAPE))
+ assert(File.fnmatch('[a\-c]', 'a', File::FNM_NOESCAPE))
+ assert(!File.fnmatch('[a\-c]', '-', File::FNM_NOESCAPE))
+ assert(File.fnmatch('[a\-c]', 'c', File::FNM_NOESCAPE))
+ assert(File.fnmatch('[a\-c]', 'b', File::FNM_NOESCAPE)) # '\\' < 'b' < 'c'
+ assert(File.fnmatch('[a\-c]', '\\', File::FNM_NOESCAPE))
+ # case is ignored if FNM_CASEFOLD is set
+ assert(!File.fnmatch('cat', 'CAT'))
+ assert(File.fnmatch('cat', 'CAT', File::FNM_CASEFOLD))
+ assert(!File.fnmatch('[a-z]', 'D'))
+ assert(File.fnmatch('[a-z]', 'D', File::FNM_CASEFOLD))
+ # wildcard doesn't match '/' if FNM_PATHNAME is set
+ assert(File.fnmatch('foo?boo', 'foo/boo'))
+ assert(File.fnmatch('foo*', 'foo/boo'))
+ assert(!File.fnmatch('foo?boo', 'foo/boo', File::FNM_PATHNAME))
+ assert(!File.fnmatch('foo*', 'foo/boo', File::FNM_PATHNAME))
+ # wildcard matches leading period if FNM_DOTMATCH is set
+ assert(!File.fnmatch('*', '.profile'))
+ assert(File.fnmatch('*', '.profile', File::FNM_DOTMATCH))
+ assert(File.fnmatch('.*', '.profile'))
+ assert(File.fnmatch('*', 'dave/.profile'))
+ assert(File.fnmatch('*/*', 'dave/.profile'))
+ assert(!File.fnmatch('*/*', 'dave/.profile', File::FNM_PATHNAME))
+ assert(File.fnmatch('*/*', 'dave/.profile', File::FNM_PATHNAME | File::FNM_DOTMATCH))
+ # recursive matching
+ assert(File.fnmatch('**/foo', 'a/b/c/foo', File::FNM_PATHNAME))
+ assert(File.fnmatch('**/foo', '/foo', File::FNM_PATHNAME))
+ assert(!File.fnmatch('**/foo', 'a/.b/c/foo', File::FNM_PATHNAME))
+ assert(File.fnmatch('**/foo', 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH))
+ assert(File.fnmatch('**/foo', '/root/foo', File::FNM_PATHNAME))
+ assert(File.fnmatch('**/foo', 'c:/root/foo', File::FNM_PATHNAME))
+ end
+
+end
diff --git a/trunk/test/ruby/test_gc.rb b/trunk/test/ruby/test_gc.rb
new file mode 100644
index 0000000000..42b249d0dc
--- /dev/null
+++ b/trunk/test/ruby/test_gc.rb
@@ -0,0 +1,54 @@
+require 'test/unit'
+
+class TestGc < Test::Unit::TestCase
+ class S
+ def initialize(a)
+ @a = a
+ end
+ end
+
+ def test_gc
+ prev_stress = GC.stress
+ GC.stress = false
+
+ assert_nothing_raised do
+ 1.upto(10000) {
+ tmp = [0,1,2,3,4,5,6,7,8,9]
+ }
+ tmp = nil
+ end
+ l=nil
+ 100000.times {
+ l = S.new(l)
+ }
+ GC.start
+ assert true # reach here or dumps core
+ l = []
+ 100000.times {
+ l.push([l])
+ }
+ GC.start
+ assert true # reach here or dumps core
+
+ GC.stress = prev_stress
+ end
+
+ def test_enable_disable
+ GC.enable
+ assert_equal(false, GC.enable)
+ assert_equal(false, GC.disable)
+ assert_equal(true, GC.disable)
+ assert_equal(true, GC.disable)
+ assert_nil(GC.start)
+ assert_equal(true, GC.enable)
+ assert_equal(false, GC.enable)
+ ensure
+ GC.enable
+ end
+
+ def test_count
+ c = GC.count
+ GC.start
+ assert_operator(c, :<, GC.count)
+ end
+end
diff --git a/trunk/test/ruby/test_hash.rb b/trunk/test/ruby/test_hash.rb
new file mode 100644
index 0000000000..de0ba37fb7
--- /dev/null
+++ b/trunk/test/ruby/test_hash.rb
@@ -0,0 +1,851 @@
+require 'test/unit'
+require 'continuation'
+
+class TestHash < Test::Unit::TestCase
+
+ def test_hash
+ x = {1=>2, 2=>4, 3=>6}
+ y = {1=>2, 2=>4, 3=>6} # y = {1, 2, 2, 4, 3, 6} # 1.9 doesn't support
+
+ assert_equal(2, x[1])
+
+ assert(begin
+ for k,v in y
+ raise if k*2 != v
+ end
+ true
+ rescue
+ false
+ end)
+
+ assert_equal(3, x.length)
+ assert(x.has_key?(1))
+ assert(x.has_value?(4))
+ assert_equal([4,6], x.values_at(2,3))
+ assert_equal({1=>2, 2=>4, 3=>6}, x)
+
+ z = y.keys.join(":")
+ assert_equal("1:2:3", z)
+
+ z = y.values.join(":")
+ assert_equal("2:4:6", z)
+ assert_equal(x, y)
+
+ y.shift
+ assert_equal(2, y.length)
+
+ z = [1,2]
+ y[z] = 256
+ assert_equal(256, y[z])
+
+ x = Hash.new(0)
+ x[1] = 1
+ assert_equal(1, x[1])
+ assert_equal(0, x[2])
+
+ x = Hash.new([])
+ assert_equal([], x[22])
+ assert_same(x[22], x[22])
+
+ x = Hash.new{[]}
+ assert_equal([], x[22])
+ assert_not_same(x[22], x[22])
+
+ x = Hash.new{|h,k| z = k; h[k] = k*2}
+ z = 0
+ assert_equal(44, x[22])
+ assert_equal(22, z)
+ z = 0
+ assert_equal(44, x[22])
+ assert_equal(0, z)
+ x.default = 5
+ assert_equal(5, x[23])
+
+ x = Hash.new
+ def x.default(k)
+ $z = k
+ self[k] = k*2
+ end
+ $z = 0
+ assert_equal(44, x[22])
+ assert_equal(22, $z)
+ $z = 0
+ assert_equal(44, x[22])
+ assert_equal(0, $z)
+ end
+
+ # From rubicon
+
+ def setup
+ @cls = Hash
+ @h = @cls[
+ 1 => 'one', 2 => 'two', 3 => 'three',
+ self => 'self', true => 'true', nil => 'nil',
+ 'nil' => nil
+ ]
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_s_AREF
+ h = @cls["a" => 100, "b" => 200]
+ assert_equal(100, h['a'])
+ assert_equal(200, h['b'])
+ assert_nil(h['c'])
+
+ h = @cls.[]("a" => 100, "b" => 200)
+ assert_equal(100, h['a'])
+ assert_equal(200, h['b'])
+ assert_nil(h['c'])
+ end
+
+ def test_s_new
+ h = @cls.new
+ assert_instance_of(@cls, h)
+ assert_nil(h.default)
+ assert_nil(h['spurious'])
+
+ h = @cls.new('default')
+ assert_instance_of(@cls, h)
+ assert_equal('default', h.default)
+ assert_equal('default', h['spurious'])
+
+ end
+
+ def test_AREF # '[]'
+ t = Time.now
+ h = @cls[
+ 1 => 'one', 2 => 'two', 3 => 'three',
+ self => 'self', t => 'time', nil => 'nil',
+ 'nil' => nil
+ ]
+
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h1 = h.dup
+ h1.default = :default
+
+ assert_equal('one', h1[1])
+ assert_equal('two', h1[2])
+ assert_equal('three', h1[3])
+ assert_equal('self', h1[self])
+ assert_equal('time', h1[t])
+ assert_equal('nil', h1[nil])
+ assert_equal(nil, h1['nil'])
+ assert_equal(:default, h1['koala'])
+
+
+ end
+
+ def test_ASET # '[]='
+ t = Time.now
+ h = @cls.new
+ h[1] = 'one'
+ h[2] = 'two'
+ h[3] = 'three'
+ h[self] = 'self'
+ h[t] = 'time'
+ h[nil] = 'nil'
+ h['nil'] = nil
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h[1] = 1
+ h[nil] = 99
+ h['nil'] = nil
+ z = [1,2]
+ h[z] = 256
+ assert_equal(1, h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal(99, h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+ assert_equal(256, h[z])
+ end
+
+ def test_EQUAL # '=='
+ h1 = @cls[ "a" => 1, "c" => 2 ]
+ h2 = @cls[ "a" => 1, "c" => 2, 7 => 35 ]
+ h3 = @cls[ "a" => 1, "c" => 2, 7 => 35 ]
+ h4 = @cls[ ]
+ assert(h1 == h1)
+ assert(h2 == h2)
+ assert(h3 == h3)
+ assert(h4 == h4)
+ assert(!(h1 == h2))
+ assert(h2 == h3)
+ assert(!(h3 == h4))
+ end
+
+ def test_clear
+ assert(@h.size > 0)
+ @h.clear
+ assert_equal(0, @h.size)
+ assert_nil(@h[1])
+ end
+
+ def test_clone
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = @h.clone
+ a.taint if taint
+ a.untrust if untrust
+ a.freeze if frozen
+ b = a.clone
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(a.frozen?, b.frozen?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+ end
+
+ def test_default
+ assert_nil(@h.default)
+ h = @cls.new(:xyzzy)
+ assert_equal(:xyzzy, h.default)
+ end
+
+ def test_default=
+ assert_nil(@h.default)
+ @h.default = :xyzzy
+ assert_equal(:xyzzy, @h.default)
+ end
+
+ def test_delete
+ h1 = @cls[ 1 => 'one', 2 => 'two', true => 'true' ]
+ h2 = @cls[ 1 => 'one', 2 => 'two' ]
+ h3 = @cls[ 2 => 'two' ]
+
+ assert_equal('true', h1.delete(true))
+ assert_equal(h2, h1)
+
+ assert_equal('one', h1.delete(1))
+ assert_equal(h3, h1)
+
+ assert_equal('two', h1.delete(2))
+ assert_equal(@cls[], h1)
+
+ assert_nil(h1.delete(99))
+ assert_equal(@cls[], h1)
+
+ assert_equal('default 99', h1.delete(99) {|i| "default #{i}" })
+ end
+
+ def test_delete_if
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(h, h.delete_if { false })
+ assert_equal(@cls[], h.delete_if { true })
+
+ h = base.dup
+ assert_equal(h1, h.delete_if {|k,v| k.instance_of?(String) })
+ assert_equal(h1, h)
+
+ h = base.dup
+ assert_equal(h2, h.delete_if {|k,v| v.instance_of?(String) })
+ assert_equal(h2, h)
+
+ h = base.dup
+ assert_equal(h3, h.delete_if {|k,v| v })
+ assert_equal(h3, h)
+
+ h = base.dup
+ n = 0
+ h.delete_if {|*a|
+ n += 1
+ assert_equal(2, a.size)
+ assert_equal(base[a[0]], a[1])
+ h.shift
+ true
+ }
+ assert_equal(base.size, n)
+ end
+
+ def test_dup
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = @h.dup
+ a.taint if taint
+ a.freeze if frozen
+ b = a.dup
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(false, b.frozen?)
+ assert_equal(a.tainted?, b.tainted?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ end
+ end
+ end
+ end
+
+ def test_each
+ count = 0
+ @cls[].each { |k, v| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each do |k, v|
+ assert_equal(v, h.delete(k))
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_key
+ count = 0
+ @cls[].each_key { |k| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each_key do |k|
+ h.delete(k)
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_pair
+ count = 0
+ @cls[].each_pair { |k, v| count + 1 }
+ assert_equal(0, count)
+
+ h = @h
+ h.each_pair do |k, v|
+ assert_equal(v, h.delete(k))
+ end
+ assert_equal(@cls[], h)
+ end
+
+ def test_each_value
+ res = []
+ @cls[].each_value { |v| res << v }
+ assert_equal(0, [].length)
+
+ @h.each_value { |v| res << v }
+ assert_equal(0, [].length)
+
+ expected = []
+ @h.each { |k, v| expected << v }
+
+ assert_equal([], expected - res)
+ assert_equal([], res - expected)
+ end
+
+ def test_empty?
+ assert(@cls[].empty?)
+ assert(!@h.empty?)
+ end
+
+ def test_fetch
+ assert_raise(KeyError) { @cls[].fetch(1) }
+ assert_raise(KeyError) { @h.fetch('gumby') }
+ assert_equal('gumbygumby', @h.fetch('gumby') {|k| k * 2 })
+ assert_equal('pokey', @h.fetch('gumby', 'pokey'))
+
+ assert_equal('one', @h.fetch(1))
+ assert_equal(nil, @h.fetch('nil'))
+ assert_equal('nil', @h.fetch(nil))
+ end
+
+ def test_key?
+ assert(!@cls[].key?(1))
+ assert(!@cls[].key?(nil))
+ assert(@h.key?(nil))
+ assert(@h.key?(1))
+ assert(!@h.key?('gumby'))
+ end
+
+ def test_value?
+ assert(!@cls[].value?(1))
+ assert(!@cls[].value?(nil))
+ assert(@h.value?('one'))
+ assert(@h.value?(nil))
+ assert(!@h.value?('gumby'))
+ end
+
+ def test_include?
+ assert(!@cls[].include?(1))
+ assert(!@cls[].include?(nil))
+ assert(@h.include?(nil))
+ assert(@h.include?(1))
+ assert(!@h.include?('gumby'))
+ end
+
+ def test_key
+ assert_equal(1, @h.key('one'))
+ assert_equal(nil, @h.key('nil'))
+ assert_equal('nil', @h.key(nil))
+
+ assert_equal(nil, @h.key('gumby'))
+ assert_equal(nil, @cls[].key('gumby'))
+ end
+
+ def test_values_at
+ res = @h.values_at('dog', 'cat', 'horse')
+ assert(res.length == 3)
+ assert_equal([nil, nil, nil], res)
+
+ res = @h.values_at
+ assert(res.length == 0)
+
+ res = @h.values_at(3, 2, 1, nil)
+ assert_equal 4, res.length
+ assert_equal %w( three two one nil ), res
+
+ res = @h.values_at(3, 99, 1, nil)
+ assert_equal 4, res.length
+ assert_equal ['three', nil, 'one', 'nil'], res
+ end
+
+
+ def test_invert
+ h = @h.invert
+ assert_equal(1, h['one'])
+ assert_equal(true, h['true'])
+ assert_equal(nil, h['nil'])
+
+ h.each do |k, v|
+ assert(@h.key?(v)) # not true in general, but works here
+ end
+
+ h = @cls[ 'a' => 1, 'b' => 2, 'c' => 1].invert
+ assert_equal(2, h.length)
+ assert(h[1] == 'a' || h[1] == 'c')
+ assert_equal('b', h[2])
+ end
+
+ def test_key?
+ assert(!@cls[].key?(1))
+ assert(!@cls[].key?(nil))
+ assert(@h.key?(nil))
+ assert(@h.key?(1))
+ assert(!@h.key?('gumby'))
+ end
+
+ def test_keys
+ assert_equal([], @cls[].keys)
+
+ keys = @h.keys
+ expected = []
+ @h.each { |k, v| expected << k }
+ assert_equal([], keys - expected)
+ assert_equal([], expected - keys)
+ end
+
+ def test_length
+ assert_equal(0, @cls[].length)
+ assert_equal(7, @h.length)
+ end
+
+ def test_member?
+ assert(!@cls[].member?(1))
+ assert(!@cls[].member?(nil))
+ assert(@h.member?(nil))
+ assert(@h.member?(1))
+ assert(!@h.member?('gumby'))
+ end
+
+ def test_rehash
+ a = [ "a", "b" ]
+ c = [ "c", "d" ]
+ h = @cls[ a => 100, c => 300 ]
+ assert_equal(100, h[a])
+ a[0] = "z"
+ assert_nil(h[a])
+ h.rehash
+ assert_equal(100, h[a])
+ end
+
+ def test_reject
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(h, h.reject { false })
+ assert_equal(@cls[], h.reject { true })
+
+ h = base.dup
+ assert_equal(h1, h.reject {|k,v| k.instance_of?(String) })
+
+ assert_equal(h2, h.reject {|k,v| v.instance_of?(String) })
+
+ assert_equal(h3, h.reject {|k,v| v })
+ assert_equal(base, h)
+ end
+
+ def test_reject!
+ base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
+ h1 = @cls[ 1 => 'one', 2 => false, true => 'true' ]
+ h2 = @cls[ 2 => false, 'cat' => 99 ]
+ h3 = @cls[ 2 => false ]
+
+ h = base.dup
+ assert_equal(nil, h.reject! { false })
+ assert_equal(@cls[], h.reject! { true })
+
+ h = base.dup
+ assert_equal(h1, h.reject! {|k,v| k.instance_of?(String) })
+ assert_equal(h1, h)
+
+ h = base.dup
+ assert_equal(h2, h.reject! {|k,v| v.instance_of?(String) })
+ assert_equal(h2, h)
+
+ h = base.dup
+ assert_equal(h3, h.reject! {|k,v| v })
+ assert_equal(h3, h)
+ end
+
+ def test_replace
+ h = @cls[ 1 => 2, 3 => 4 ]
+ h1 = h.replace(@cls[ 9 => 8, 7 => 6 ])
+ assert_equal(h, h1)
+ assert_equal(8, h[9])
+ assert_equal(6, h[7])
+ assert_nil(h[1])
+ assert_nil(h[2])
+ end
+
+ def test_shift
+ h = @h.dup
+
+ @h.length.times {
+ k, v = h.shift
+ assert(@h.key?(k))
+ assert_equal(@h[k], v)
+ }
+
+ assert_equal(0, h.length)
+ end
+
+ def test_size
+ assert_equal(0, @cls[].length)
+ assert_equal(7, @h.length)
+ end
+
+ def test_sort
+ h = @cls[].sort
+ assert_equal([], h)
+
+ h = @cls[ 1 => 1, 2 => 1 ].sort
+ assert_equal([[1,1], [2,1]], h)
+
+ h = @cls[ 'cat' => 'feline', 'ass' => 'asinine', 'bee' => 'beeline' ]
+ h1 = h.sort
+ assert_equal([ %w(ass asinine), %w(bee beeline), %w(cat feline)], h1)
+ end
+
+ def test_store
+ t = Time.now
+ h = @cls.new
+ h.store(1, 'one')
+ h.store(2, 'two')
+ h.store(3, 'three')
+ h.store(self, 'self')
+ h.store(t, 'time')
+ h.store(nil, 'nil')
+ h.store('nil', nil)
+ assert_equal('one', h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal('nil', h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+
+ h.store(1, 1)
+ h.store(nil, 99)
+ h.store('nil', nil)
+ assert_equal(1, h[1])
+ assert_equal('two', h[2])
+ assert_equal('three', h[3])
+ assert_equal('self', h[self])
+ assert_equal('time', h[t])
+ assert_equal(99, h[nil])
+ assert_equal(nil, h['nil'])
+ assert_equal(nil, h['koala'])
+ end
+
+ def test_to_a
+ assert_equal([], @cls[].to_a)
+ assert_equal([[1,2]], @cls[ 1=>2 ].to_a)
+ a = @cls[ 1=>2, 3=>4, 5=>6 ].to_a
+ assert_equal([1,2], a.delete([1,2]))
+ assert_equal([3,4], a.delete([3,4]))
+ assert_equal([5,6], a.delete([5,6]))
+ assert_equal(0, a.length)
+
+ h = @cls[ 1=>2, 3=>4, 5=>6 ]
+ h.taint
+ h.untrust
+ a = h.to_a
+ assert_equal(true, a.tainted?)
+ assert_equal(true, a.untrusted?)
+ end
+
+ def test_to_hash
+ h = @h.to_hash
+ assert_equal(@h, h)
+ end
+
+ def test_to_s
+ h = @cls[ 1 => 2, "cat" => "dog", 1.5 => :fred ]
+ assert_equal(h.inspect, h.to_s)
+ $, = ":"
+ assert_equal(h.inspect, h.to_s)
+ h = @cls[]
+ assert_equal(h.inspect, h.to_s)
+ $, = nil
+ end
+
+ def test_update
+ h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]
+ h2 = @cls[ 2 => 'two', 4 => 'four' ]
+
+ ha = @cls[ 1 => 2, 2 => 'two', 3 => 4, 4 => 'four' ]
+ hb = @cls[ 1 => 2, 2 => 3, 3 => 4, 4 => 'four' ]
+
+ assert_equal(ha, h1.update(h2))
+ assert_equal(ha, h1)
+
+ h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]
+ h2 = @cls[ 2 => 'two', 4 => 'four' ]
+
+ assert_equal(hb, h2.update(h1))
+ assert_equal(hb, h2)
+ end
+
+ def test_value?
+ assert(!@cls[].value?(1))
+ assert(!@cls[].value?(nil))
+ assert(@h.value?(nil))
+ assert(@h.value?('one'))
+ assert(!@h.value?('gumby'))
+ end
+
+ def test_values
+ assert_equal([], @cls[].values)
+
+ vals = @h.values
+ expected = []
+ @h.each { |k, v| expected << v }
+ assert_equal([], vals - expected)
+ assert_equal([], expected - vals)
+ end
+
+ def test_security_check
+ h = {}
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ h[1] = 1
+ end.join
+ end
+ end
+
+ def test_intialize_wrong_arguments
+ assert_raise(ArgumentError) do
+ Hash.new(0) { }
+ end
+ end
+
+ def test_create
+ assert_equal({1=>2, 3=>4}, Hash[[[1,2],[3,4]]])
+ assert_raise(ArgumentError) { Hash[0, 1, 2] }
+ assert_equal({1=>2, 3=>4}, Hash[1,2,3,4])
+ o = Object.new
+ def o.to_hash() {1=>2} end
+ assert_equal({1=>2}, Hash[o], "[ruby-dev:34555]")
+ end
+
+ def test_rehash2
+ h = {1 => 2, 3 => 4}
+ assert_equal(h.dup, h.rehash)
+ assert_raise(RuntimeError) { h.each { h.rehash } }
+ assert_equal({}, {}.rehash)
+ end
+
+ def test_fetch2
+ assert_equal(:bar, @h.fetch(0, :foo) { :bar })
+ end
+
+ def test_default_proc
+ h = Hash.new {|h, k| h + k + "baz" }
+ assert_equal("foobarbaz", h.default_proc.call("foo", "bar"))
+ h = {}
+ assert_nil(h.default_proc)
+ end
+
+ def test_shift2
+ h = Hash.new {|h, k| :foo }
+ h[1] = 2
+ assert_equal([1, 2], h.shift)
+ assert_equal(:foo, h.shift)
+ assert_equal(:foo, h.shift)
+
+ h = Hash.new(:foo)
+ h[1] = 2
+ assert_equal([1, 2], h.shift)
+ assert_equal(:foo, h.shift)
+ assert_equal(:foo, h.shift)
+
+ h = {1=>2}
+ h.each { assert_equal([1, 2], h.shift) }
+ end
+
+ def test_reject_bang2
+ assert_equal({1=>2}, {1=>2,3=>4}.reject! {|k, v| k + v == 7 })
+ assert_nil({1=>2,3=>4}.reject! {|k, v| k == 5 })
+ assert_nil({}.reject! { })
+ end
+
+ def test_select
+ assert_equal({3=>4,5=>6}, {1=>2,3=>4,5=>6}.select {|k, v| k + v >= 7 })
+ end
+
+ def test_clear2
+ assert_equal({}, {1=>2,3=>4,5=>6}.clear)
+ h = {1=>2,3=>4,5=>6}
+ h.each { h.clear }
+ assert_equal({}, h)
+ end
+
+ def test_replace2
+ h1 = Hash.new { :foo }
+ h2 = {}
+ h2.replace h1
+ assert_equal(:foo, h2[0])
+ end
+
+ def test_size2
+ assert_equal(0, {}.size)
+ end
+
+ def test_equal2
+ assert({} != 0)
+ o = Object.new
+ def o.to_hash; {}; end
+ def o.==(x); true; end
+ assert({} == o)
+ def o.==(x); false; end
+ assert({} != o)
+
+ h1 = {1=>2}; h2 = {3=>4}
+ assert(h1 != h2)
+ h1 = {1=>2}; h2 = {1=>4}
+ assert(h1 != h2)
+
+ h1 = {}; h1[h1] = h1; h1.rehash
+ h2 = {}; h2[h2] = h2; h2.rehash
+ assert(h1 != h2)
+ end
+
+ def test_eql
+ assert(!({}.eql?(0)))
+ o = Object.new
+ def o.to_hash; {}; end
+ def o.eql?(x); true; end
+ assert({}.eql?(o))
+ def o.eql?(x); false; end
+ assert(!({}.eql?(o)))
+ end
+
+ def test_hash2
+ assert_kind_of(Integer, {}.hash)
+ end
+
+ def test_update2
+ h1 = {1=>2, 3=>4}
+ h2 = {1=>3, 5=>7}
+ h1.update(h2) {|k, v1, v2| k + v1 + v2 }
+ assert_equal({1=>6, 3=>4, 5=>7}, h1)
+ end
+
+ def test_merge
+ h1 = {1=>2, 3=>4}
+ h2 = {1=>3, 5=>7}
+ assert_equal({1=>3, 3=>4, 5=>7}, h1.merge(h2))
+ assert_equal({1=>6, 3=>4, 5=>7}, h1.merge(h2) {|k, v1, v2| k + v1 + v2 })
+ end
+
+ def test_assoc
+ assert_equal([3,4], {1=>2, 3=>4, 5=>6}.assoc(3))
+ assert_nil({1=>2, 3=>4, 5=>6}.assoc(4))
+ end
+
+ def test_rassoc
+ assert_equal([3,4], {1=>2, 3=>4, 5=>6}.rassoc(4))
+ assert_nil({1=>2, 3=>4, 5=>6}.rassoc(3))
+ end
+
+ def test_flatten
+ assert_equal([[1], [2]], {[1] => [2]}.flatten)
+ end
+
+ def test_callcc
+ h = {1=>2}
+ c = nil
+ f = false
+ h.each { callcc {|c2| c = c2 } }
+ unless f
+ f = true
+ c.call
+ end
+ assert_raise(RuntimeError) { h.each { h.rehash } }
+
+ h = {1=>2}
+ c = nil
+ assert_raise(RuntimeError) do
+ h.each { callcc {|c2| c = c2 } }
+ h.clear
+ c.call
+ end
+ end
+
+ def test_compare_by_identity
+ a = "foo"
+ assert(!{}.compare_by_identity?)
+ h = { a => "bar" }
+ assert(!h.compare_by_identity?)
+ h.compare_by_identity
+ assert(h.compare_by_identity?)
+ #assert_equal("bar", h[a])
+ assert_nil(h["foo"])
+ end
+
+ def test_hash_hash
+ assert_equal({0=>2,11=>1}.hash, {11=>1,0=>2}.hash)
+ end
+end
diff --git a/trunk/test/ruby/test_ifunless.rb b/trunk/test/ruby/test_ifunless.rb
new file mode 100644
index 0000000000..bffc794512
--- /dev/null
+++ b/trunk/test/ruby/test_ifunless.rb
@@ -0,0 +1,14 @@
+require 'test/unit'
+
+class TestIfunless < Test::Unit::TestCase
+ def test_if_unless
+ $x = 'test';
+ assert(if $x == $x then true else false end)
+ $bad = false
+ unless $x == $x
+ $bad = true
+ end
+ assert(!$bad)
+ assert(unless $x != $x then true else false end)
+ end
+end
diff --git a/trunk/test/ruby/test_integer.rb b/trunk/test/ruby/test_integer.rb
new file mode 100644
index 0000000000..e31fb1880d
--- /dev/null
+++ b/trunk/test/ruby/test_integer.rb
@@ -0,0 +1,193 @@
+require 'test/unit'
+
+class TestInteger < Test::Unit::TestCase
+ BDSIZE = 0x4000000000000000.coerce(0)[0].size
+ def self.bdsize(x)
+ ((x + 1) / 8 + BDSIZE) / BDSIZE * BDSIZE
+ end
+ def bdsize(x)
+ self.class.bdsize(x)
+ end
+
+ def test_aref
+ # assert_equal(1, (1 << 0x40000000)[0x40000000], "[ruby-dev:31271]")
+ # assert_equal(0, (-1 << 0x40000001)[0x40000000], "[ruby-dev:31271]")
+ big_zero = 0x40000000.coerce(0)[0]
+ assert_equal(0, (-0x40000002)[big_zero], "[ruby-dev:31271]")
+ assert_equal(1, 0x400000001[big_zero], "[ruby-dev:31271]")
+ end
+
+ def test_pow
+ assert_not_equal(0, begin
+ 0**-1
+ rescue
+ nil
+ end, "[ruby-dev:32084] [ruby-dev:34547]")
+ end
+
+ def test_lshift
+ assert_equal(0, 1 << -0x40000000)
+ assert_equal(0, 1 << -0x40000001)
+ assert_equal(0, 1 << -0x80000000)
+ assert_equal(0, 1 << -0x80000001)
+ # assert_equal(bdsize(0x80000000), (1 << 0x80000000).size)
+ end
+
+ def test_rshift
+ # assert_equal(bdsize(0x40000001), (1 >> -0x40000001).size)
+ assert((1 >> 0x80000000).zero?)
+ assert((1 >> 0xffffffff).zero?)
+ assert((1 >> 0x100000000).zero?)
+ # assert_equal((1 << 0x40000000), (1 >> -0x40000000))
+ # assert_equal((1 << 0x40000001), (1 >> -0x40000001))
+ end
+
+ def test_Integer
+ assert_raise(ArgumentError) {Integer("0x-1")}
+ assert_raise(ArgumentError) {Integer("-0x-1")}
+ assert_raise(ArgumentError) {Integer("0x 123")}
+ assert_raise(ArgumentError) {Integer("0x 123")}
+ assert_raise(ArgumentError) {Integer("0x0x5")}
+ assert_raise(ArgumentError) {Integer("0x0x000000005")}
+ assert_nothing_raised(ArgumentError) {
+ assert_equal(1540841, "0x0x5".to_i(36))
+ }
+ assert_raise(ArgumentError) { Integer("--0") }
+ assert_raise(ArgumentError) { Integer("-+0") }
+ assert_raise(ArgumentError) { Integer("++1") }
+ assert_raise(ArgumentError) { Integer("") }
+ assert_raise(ArgumentError) { Integer("10 x") }
+ assert_raise(ArgumentError) { Integer("1__2") }
+ assert_raise(ArgumentError) { Integer("1z") }
+ assert_raise(ArgumentError) { Integer("46116860184273__87904") }
+ assert_raise(ArgumentError) { Integer("4611686018427387904_") }
+ assert_raise(ArgumentError) { Integer("4611686018427387904 :") }
+ assert_equal(0x4000000000000000, Integer("46_11_686_0184273_87904"))
+ assert_raise(ArgumentError) { Integer("\0") }
+ assert_nothing_raised(ArgumentError, "[ruby-core:13873]") {
+ assert_equal(0, Integer("0 "))
+ }
+ assert_nothing_raised(ArgumentError, "[ruby-core:14139]") {
+ assert_equal(0377, Integer("0_3_7_7"))
+ }
+ assert_raise(ArgumentError, "[ruby-core:14139]") {Integer("0__3_7_7")}
+ end
+
+ def test_int_p
+ assert(!(1.0.integer?))
+ assert(1.integer?)
+ end
+
+ def test_odd_p_even_p
+ Fixnum.class_eval do
+ alias odd_bak odd?
+ alias even_bak even?
+ remove_method :odd?, :even?
+ end
+
+ assert(1.odd?)
+ assert(!(2.odd?))
+ assert(!(1.even?))
+ assert(2.even?)
+
+ ensure
+ Fixnum.class_eval do
+ alias odd? odd_bak
+ alias even? even_bak
+ remove_method :odd_bak, :even_bak
+ end
+ end
+
+ def test_succ
+ assert_equal(2, 1.send(:succ))
+
+ Fixnum.class_eval do
+ alias succ_bak succ
+ remove_method :succ
+ end
+
+ assert_equal(2, 1.succ)
+ assert_equal(4294967297, 4294967296.succ)
+
+ ensure
+ Fixnum.class_eval do
+ alias succ succ_bak
+ remove_method :succ_bak
+ end
+ end
+
+ def test_chr
+ assert_equal("a", "a".ord.chr)
+ assert_raise(RangeError) { (-1).chr }
+ assert_raise(RangeError) { 0x100.chr }
+ end
+
+ def test_induced_from
+ assert_equal(1, Integer.induced_from(1))
+ assert_equal(1, Integer.induced_from(1.0))
+ assert_raise(TypeError) { Integer.induced_from(nil) }
+ end
+
+ def test_upto
+ a = []
+ 1.upto(3) {|x| a << x }
+ assert_equal([1, 2, 3], a)
+
+ a = []
+ 1.upto(0) {|x| a << x }
+ assert_equal([], a)
+
+ x = 2**30 - 1
+ a = []
+ x.upto(x+2) {|x| a << x }
+ assert_equal([x, x+1, x+2], a)
+ end
+
+ def test_downto
+ a = []
+ -1.downto(-3) {|x| a << x }
+ assert_equal([-1, -2, -3], a)
+
+ a = []
+ 1.downto(2) {|x| a << x }
+ assert_equal([], a)
+
+ x = -(2**30)
+ a = []
+ x.downto(x-2) {|x| a << x }
+ assert_equal([x, x-1, x-2], a)
+ end
+
+ def test_times
+ (2**32).times do |i|
+ break if i == 2
+ end
+ end
+
+ def test_round
+ assert_equal(11111, 11111.round)
+ assert_equal(Fixnum, 11111.round.class)
+ assert_equal(11111, 11111.round(0))
+ assert_equal(Fixnum, 11111.round(0).class)
+
+ assert_equal(11111.0, 11111.round(1))
+ assert_equal(Float, 11111.round(1).class)
+ assert_equal(11111.0, 11111.round(2))
+ assert_equal(Float, 11111.round(2).class)
+
+ assert_equal(11110, 11111.round(-1))
+ assert_equal(Fixnum, 11111.round(-1).class)
+ assert_equal(11100, 11111.round(-2))
+ assert_equal(Fixnum, 11111.round(-2).class)
+
+ assert_equal(1111_1111_1111_1111_1111_1111_1111_1110, 1111_1111_1111_1111_1111_1111_1111_1111.round(-1))
+ assert_equal(Bignum, 1111_1111_1111_1111_1111_1111_1111_1111.round(-1).class)
+ assert_equal(-1111_1111_1111_1111_1111_1111_1111_1110, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1))
+ assert_equal(Bignum, (-1111_1111_1111_1111_1111_1111_1111_1111).round(-1).class)
+ end
+
+ def test_Integer2
+ assert_equal(2 ** 50, Integer(2.0 ** 50))
+ assert_raise(TypeError) { Integer(nil) }
+ end
+end
diff --git a/trunk/test/ruby/test_integer_comb.rb b/trunk/test/ruby/test_integer_comb.rb
new file mode 100644
index 0000000000..7cac5d6ad2
--- /dev/null
+++ b/trunk/test/ruby/test_integer_comb.rb
@@ -0,0 +1,620 @@
+require 'test/unit'
+
+class TestIntegerComb < Test::Unit::TestCase
+ VS = [
+ -0x1000000000000000000000000000000000000000000000002,
+ -0x1000000000000000000000000000000000000000000000001,
+ -0x1000000000000000000000000000000000000000000000000,
+ -0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ -0x1000000000000000000000002,
+ -0x1000000000000000000000001,
+ -0x1000000000000000000000000,
+ -0xffffffffffffffffffffffff,
+ -0x10000000000000002,
+ -0x10000000000000001,
+ -0x10000000000000000,
+ -0xffffffffffffffff,
+ -0x4000000000000002,
+ -0x4000000000000001,
+ -0x4000000000000000,
+ -0x3fffffffffffffff,
+ -0x100000002,
+ -0x100000001,
+ -0x100000000,
+ -0xffffffff,
+ -0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001
+ -0x80000002,
+ -0x80000001,
+ -0x80000000,
+ -0x7fffffff,
+ -0x524b2245,
+ -0x40000002,
+ -0x40000001,
+ -0x40000000,
+ -0x3fffffff,
+ -0x10002,
+ -0x10001,
+ -0x10000,
+ -0xffff,
+ -0x8101, # 0x8101 * 0x7f01 = 0x40000001
+ -0x8002,
+ -0x8001,
+ -0x8000,
+ -0x7fff,
+ -0x7f01,
+ -65,
+ -64,
+ -63,
+ -62,
+ -33,
+ -32,
+ -31,
+ -30,
+ -3,
+ -2,
+ -1,
+ 0,
+ 1,
+ 2,
+ 3,
+ 30,
+ 31,
+ 32,
+ 33,
+ 62,
+ 63,
+ 64,
+ 65,
+ 0x7f01,
+ 0x7ffe,
+ 0x7fff,
+ 0x8000,
+ 0x8001,
+ 0x8101,
+ 0xfffe,
+ 0xffff,
+ 0x10000,
+ 0x10001,
+ 0x3ffffffe,
+ 0x3fffffff,
+ 0x40000000,
+ 0x40000001,
+ 0x524b2245,
+ 0x7ffffffe,
+ 0x7fffffff,
+ 0x80000000,
+ 0x80000001,
+ 0xc717a08d,
+ 0xfffffffe,
+ 0xffffffff,
+ 0x100000000,
+ 0x100000001,
+ 0x3ffffffffffffffe,
+ 0x3fffffffffffffff,
+ 0x4000000000000000,
+ 0x4000000000000001,
+ 0xfffffffffffffffe,
+ 0xffffffffffffffff,
+ 0x10000000000000000,
+ 0x10000000000000001,
+ 0xffffffffffffffffffffffff,
+ 0x1000000000000000000000000,
+ 0x1000000000000000000000001,
+ 0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ 0x1000000000000000000000000000000000000000000000000,
+ 0x1000000000000000000000000000000000000000000000001
+ ]
+
+ #VS.map! {|v| 0x4000000000000000.coerce(v)[0] }
+
+ min = -1
+ min *= 2 while min.class == Fixnum
+ FIXNUM_MIN = min/2
+ max = 1
+ max *= 2 while (max-1).class == Fixnum
+ FIXNUM_MAX = max/2-1
+
+ def test_fixnum_range
+ assert_instance_of(Bignum, FIXNUM_MIN-1)
+ assert_instance_of(Fixnum, FIXNUM_MIN)
+ assert_instance_of(Fixnum, FIXNUM_MAX)
+ assert_instance_of(Bignum, FIXNUM_MAX+1)
+ end
+
+ def check_class(n)
+ if FIXNUM_MIN <= n && n <= FIXNUM_MAX
+ assert_instance_of(Fixnum, n)
+ else
+ assert_instance_of(Bignum, n)
+ end
+ end
+
+ def test_aref
+ VS.each {|a|
+ 100.times {|i|
+ assert_equal((a >> i).odd? ? 1 : 0, a[i], "(#{a})[#{i}]")
+ }
+ }
+ VS.each {|a|
+ VS.each {|b|
+ c = nil
+ assert_nothing_raised("(#{a})[#{b}]") { c = a[b] }
+ check_class(c)
+ if b < 0
+ assert_equal(0, c, "(#{a})[#{b}]")
+ else
+ assert_equal((a >> b).odd? ? 1 : 0, c, "(#{a})[#{b}]")
+ end
+ }
+ }
+ end
+
+ def test_plus
+ VS.each {|a|
+ VS.each {|b|
+ c = a + b
+ check_class(c)
+ assert_equal(b + a, c, "#{a} + #{b}")
+ assert_equal(a, c - b, "(#{a} + #{b}) - #{b}")
+ assert_equal(a-~b-1, c, "#{a} + #{b}") # Hacker's Delight
+ assert_equal((a^b)+2*(a&b), c, "#{a} + #{b}") # Hacker's Delight
+ assert_equal((a|b)+(a&b), c, "#{a} + #{b}") # Hacker's Delight
+ assert_equal(2*(a|b)-(a^b), c, "#{a} + #{b}") # Hacker's Delight
+ }
+ }
+ end
+
+ def test_minus
+ VS.each {|a|
+ VS.each {|b|
+ c = a - b
+ check_class(c)
+ assert_equal(a, c + b, "(#{a} - #{b}) + #{b}")
+ assert_equal(-b, c - a, "(#{a} - #{b}) - #{a}")
+ assert_equal(a+~b+1, c, "#{a} - #{b}") # Hacker's Delight
+ assert_equal((a^b)-2*(b&~a), c, "#{a} - #{b}") # Hacker's Delight
+ assert_equal((a&~b)-(b&~a), c, "#{a} - #{b}") # Hacker's Delight
+ assert_equal(2*(a&~b)-(a^b), c, "#{a} - #{b}") # Hacker's Delight
+ }
+ }
+ end
+
+ def test_mult
+ VS.each {|a|
+ VS.each {|b|
+ c = a * b
+ check_class(c)
+ assert_equal(b * a, c, "#{a} * #{b}")
+ assert_equal(b, c / a, "(#{a} * #{b}) / #{a}") if a != 0
+ assert_equal(a.abs * b.abs, (a * b).abs, "(#{a} * #{b}).abs")
+ assert_equal((a-100)*(b-100)+(a-100)*100+(b-100)*100+10000, c, "#{a} * #{b}")
+ assert_equal((a+100)*(b+100)-(a+100)*100-(b+100)*100+10000, c, "#{a} * #{b}")
+ }
+ }
+ end
+
+ def test_divmod
+ VS.each {|a|
+ VS.each {|b|
+ if b == 0
+ assert_raise(ZeroDivisionError) { a.divmod(b) }
+ else
+ q, r = a.divmod(b)
+ check_class(q)
+ check_class(r)
+ assert_equal(a, b*q+r)
+ assert(r.abs < b.abs)
+ assert(0 < b ? (0 <= r && r < b) : (b < r && r <= 0))
+ assert_equal(q, a/b)
+ assert_equal(q, a.div(b))
+ assert_equal(r, a%b)
+ assert_equal(r, a.modulo(b))
+ end
+ }
+ }
+ end
+
+ def test_pow
+ small_values = VS.find_all {|v| 0 <= v && v < 1000 }
+ VS.each {|a|
+ small_values.each {|b|
+ c = a ** b
+ check_class(c)
+ d = 1
+ b.times { d *= a }
+ assert_equal(d, c, "(#{a}) ** #{b}")
+ if a != 0
+ d = c
+ b.times { d /= a }
+ assert_equal(1, d, "((#{a}) ** #{b}) / #{a} / ...(#{b} times)...")
+ end
+ }
+ }
+ end
+
+ def test_not
+ VS.each {|a|
+ b = ~a
+ check_class(b)
+ assert_equal(-1 ^ a, b, "~#{a}")
+ assert_equal(-a-1, b, "~#{a}") # Hacker's Delight
+ assert_equal(0, a & b, "#{a} & ~#{a}")
+ assert_equal(-1, a | b, "#{a} | ~#{a}")
+ }
+ end
+
+ def test_or
+ VS.each {|a|
+ VS.each {|b|
+ c = a | b
+ check_class(c)
+ assert_equal(b | a, c, "#{a} | #{b}")
+ assert_equal(a + b - (a&b), c, "#{a} | #{b}")
+ assert_equal((a & ~b) + b, c, "#{a} | #{b}") # Hacker's Delight
+ assert_equal(-1, c | ~a, "(#{a} | #{b}) | ~#{a})")
+ }
+ }
+ end
+
+ def test_and
+ VS.each {|a|
+ VS.each {|b|
+ c = a & b
+ check_class(c)
+ assert_equal(b & a, c, "#{a} & #{b}")
+ assert_equal(a + b - (a|b), c, "#{a} & #{b}")
+ assert_equal((~a | b) - ~a, c, "#{a} & #{b}") # Hacker's Delight
+ assert_equal(0, c & ~a, "(#{a} & #{b}) & ~#{a}")
+ }
+ }
+ end
+
+ def test_xor
+ VS.each {|a|
+ VS.each {|b|
+ c = a ^ b
+ check_class(c)
+ assert_equal(b ^ a, c, "#{a} ^ #{b}")
+ assert_equal((a|b)-(a&b), c, "#{a} ^ #{b}") # Hacker's Delight
+ assert_equal(b, c ^ a, "(#{a} ^ #{b}) ^ #{a}")
+ }
+ }
+ end
+
+ def test_lshift
+ small_values = VS.find_all {|v| v < 8000 }
+ VS.each {|a|
+ small_values.each {|b|
+ c = a << b
+ check_class(c)
+ if 0 <= b
+ assert_equal(a, c >> b, "(#{a} << #{b}) >> #{b}")
+ assert_equal(a * 2**b, c, "#{a} << #{b}")
+ end
+ 0.upto(c.size*8+10) {|nth|
+ assert_equal(a[nth-b], c[nth], "(#{a} << #{b})[#{nth}]")
+ }
+ }
+ }
+ end
+
+ def test_rshift
+ small_values = VS.find_all {|v| -8000 < v }
+ VS.each {|a|
+ small_values.each {|b|
+ c = a >> b
+ check_class(c)
+ if b <= 0
+ assert_equal(a, c << b, "(#{a} >> #{b}) << #{b}")
+ assert_equal(a * 2**(-b), c, "#{a} >> #{b}")
+ end
+ 0.upto(c.size*8+10) {|nth|
+ assert_equal(a[nth+b], c[nth], "(#{a} >> #{b})[#{nth}]")
+ }
+ }
+ }
+ end
+
+ def test_succ
+ VS.each {|a|
+ b = a.succ
+ check_class(b)
+ assert_equal(a+1, b, "(#{a}).succ")
+ assert_equal(a, b.pred, "(#{a}).succ.pred")
+ assert_equal(a, b-1, "(#{a}).succ - 1")
+ }
+ end
+
+ def test_pred
+ VS.each {|a|
+ b = a.pred
+ check_class(b)
+ assert_equal(a-1, b, "(#{a}).pred")
+ assert_equal(a, b.succ, "(#{a}).pred.succ")
+ assert_equal(a, b + 1, "(#{a}).pred + 1")
+ }
+ end
+
+ def test_unary_plus
+ VS.each {|a|
+ b = +a
+ check_class(b)
+ assert_equal(a, b, "+(#{a})")
+ }
+ end
+
+ def test_unary_minus
+ VS.each {|a|
+ b = -a
+ check_class(b)
+ assert_equal(0-a, b, "-(#{a})")
+ assert_equal(~a+1, b, "-(#{a})")
+ assert_equal(0, a+b, "#{a}+(-(#{a}))")
+ }
+ end
+
+ def test_cmp
+ VS.each_with_index {|a, i|
+ VS.each_with_index {|b, j|
+ assert_equal(i <=> j, a <=> b, "#{a} <=> #{b}")
+ assert_equal(i < j, a < b, "#{a} < #{b}")
+ assert_equal(i <= j, a <= b, "#{a} <= #{b}")
+ assert_equal(i > j, a > b, "#{a} > #{b}")
+ assert_equal(i >= j, a >= b, "#{a} >= #{b}")
+ }
+ }
+ end
+
+ def test_eq
+ VS.each_with_index {|a, i|
+ VS.each_with_index {|b, j|
+ c = a == b
+ assert_equal(b == a, c, "#{a} == #{b}")
+ assert_equal(i == j, c, "#{a} == #{b}")
+ }
+ }
+ end
+
+ def test_abs
+ VS.each {|a|
+ b = a.abs
+ check_class(b)
+ if a < 0
+ assert_equal(-a, b, "(#{a}).abs")
+ else
+ assert_equal(a, b, "(#{a}).abs")
+ end
+ }
+ end
+
+ def test_ceil
+ VS.each {|a|
+ b = a.ceil
+ check_class(b)
+ assert_equal(a, b, "(#{a}).ceil")
+ }
+ end
+
+ def test_floor
+ VS.each {|a|
+ b = a.floor
+ check_class(b)
+ assert_equal(a, b, "(#{a}).floor")
+ }
+ end
+
+ def test_round
+ VS.each {|a|
+ b = a.round
+ check_class(b)
+ assert_equal(a, b, "(#{a}).round")
+ }
+ end
+
+ def test_truncate
+ VS.each {|a|
+ b = a.truncate
+ check_class(b)
+ assert_equal(a, b, "(#{a}).truncate")
+ }
+ end
+
+ def test_remainder
+ VS.each {|a|
+ VS.each {|b|
+ if b == 0
+ assert_raise(ZeroDivisionError) { a.divmod(b) }
+ else
+ r = a.remainder(b)
+ check_class(r)
+ if a < 0
+ assert_operator(-b.abs, :<, r, "#{a}.remainder(#{b})")
+ assert_operator(0, :>=, r, "#{a}.remainder(#{b})")
+ elsif 0 < a
+ assert_operator(0, :<=, r, "#{a}.remainder(#{b})")
+ assert_operator(b.abs, :>, r, "#{a}.remainder(#{b})")
+ else
+ assert_equal(0, r, "#{a}.remainder(#{b})")
+ end
+ end
+ }
+ }
+ end
+
+ def test_zero_nonzero
+ VS.each {|a|
+ z = a.zero?
+ n = a.nonzero?
+ if a == 0
+ assert_equal(true, z, "(#{a}).zero?")
+ assert_equal(nil, n, "(#{a}).nonzero?")
+ else
+ assert_equal(false, z, "(#{a}).zero?")
+ assert_equal(a, n, "(#{a}).nonzero?")
+ check_class(n)
+ end
+ assert(z ^ n, "(#{a}).zero? ^ (#{a}).nonzero?")
+ }
+ end
+
+ def test_even_odd
+ VS.each {|a|
+ e = a.even?
+ o = a.odd?
+ assert_equal((a % 2) == 0, e, "(#{a}).even?")
+ assert_equal((a % 2) == 1, o, "(#{a}).odd")
+ assert_equal((a & 1) == 0, e, "(#{a}).even?")
+ assert_equal((a & 1) == 1, o, "(#{a}).odd")
+ assert(e ^ o, "(#{a}).even? ^ (#{a}).odd?")
+ }
+ end
+
+ def test_to_s
+ 2.upto(36) {|radix|
+ VS.each {|a|
+ s = a.to_s(radix)
+ b = s.to_i(radix)
+ assert_equal(a, b, "(#{a}).to_s(#{radix}).to_i(#{radix})")
+ }
+ }
+ end
+
+ def test_printf_x
+ VS.reverse_each {|a|
+ s = sprintf("%x", a)
+ if /\A\.\./ =~ s
+ b = -($'.tr('0123456789abcdef', 'fedcba9876543210').to_i(16) + 1)
+ else
+ b = s.to_i(16)
+ end
+ assert_equal(a, b, "sprintf('%x', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_x_sign
+ VS.reverse_each {|a|
+ s = sprintf("%+x", a)
+ b = s.to_i(16)
+ assert_equal(a, b, "sprintf('%+x', #{a}) = #{s.inspect}")
+ s = sprintf("% x", a)
+ b = s.to_i(16)
+ assert_equal(a, b, "sprintf('% x', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_o
+ VS.reverse_each {|a|
+ s = sprintf("%o", a)
+ if /\A\.\./ =~ s
+ b = -($'.tr('01234567', '76543210').to_i(8) + 1)
+ else
+ b = s.to_i(8)
+ end
+ assert_equal(a, b, "sprintf('%o', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_o_sign
+ VS.reverse_each {|a|
+ s = sprintf("%+o", a)
+ b = s.to_i(8)
+ assert_equal(a, b, "sprintf('%+o', #{a}) = #{s.inspect}")
+ s = sprintf("% o", a)
+ b = s.to_i(8)
+ assert_equal(a, b, "sprintf('% o', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_b
+ VS.reverse_each {|a|
+ s = sprintf("%b", a)
+ if /\A\.\./ =~ s
+ b = -($'.tr('01', '10').to_i(2) + 1)
+ else
+ b = s.to_i(2)
+ end
+ assert_equal(a, b, "sprintf('%b', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_b_sign
+ VS.reverse_each {|a|
+ s = sprintf("%+b", a)
+ b = s.to_i(2)
+ assert_equal(a, b, "sprintf('%+b', #{a}) = #{s.inspect}")
+ s = sprintf("% b", a)
+ b = s.to_i(2)
+ assert_equal(a, b, "sprintf('% b', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_printf_diu
+ VS.reverse_each {|a|
+ s = sprintf("%d", a)
+ b = s.to_i
+ assert_equal(a, b, "sprintf('%d', #{a}) = #{s.inspect}")
+ s = sprintf("%i", a)
+ b = s.to_i
+ assert_equal(a, b, "sprintf('%i', #{a}) = #{s.inspect}")
+ s = sprintf("%u", a)
+ b = s.to_i
+ assert_equal(a, b, "sprintf('%u', #{a}) = #{s.inspect}")
+ }
+ end
+
+ def test_marshal
+ VS.reverse_each {|a|
+ s = Marshal.dump(a)
+ b = Marshal.load(s)
+ assert_equal(a, b, "Marshal.load(Marshal.dump(#{a}))")
+ }
+ end
+
+ def test_pack
+ %w[c C s S s! S! i I i! I! l L l! L! q Q n N v V].each {|template|
+ size = [0].pack(template).size
+ mask = (1 << (size * 8)) - 1
+ if /[A-Znv]/ =~ template
+ min = 0
+ max = (1 << (size * 8))-1
+ else
+ min = -(1 << (size * 8 - 1))
+ max = (1 << (size * 8 - 1)) - 1
+ end
+ VS.reverse_each {|a|
+ s = [a].pack(template)
+ b = s.unpack(template)[0]
+ assert_equal(a & mask, b & mask, "[#{a}].pack(#{template.dump}).unpack(#{template.dump}) & #{mask}")
+ if min <= a && a <= max
+ assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})")
+ end
+ }
+ }
+ end
+
+ def test_pack_ber
+ template = "w"
+ VS.reverse_each {|a|
+ if a < 0
+ assert_raise(ArgumentError) { [a].pack(template) }
+ else
+ s = [a].pack(template)
+ b = s.unpack(template)[0]
+ assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})")
+ end
+ }
+ end
+
+ def test_pack_utf8
+ template = "U"
+ VS.reverse_each {|a|
+ if a < 0 || 0x7fffffff < a
+ assert_raise(RangeError) { [a].pack(template) }
+ else
+ s = [a].pack(template)
+ b = s.unpack(template)[0]
+ assert_equal(a, b, "[#{a}].pack(#{template.dump}).unpack(#{template.dump})")
+ end
+ }
+ end
+end
diff --git a/trunk/test/ruby/test_io.rb b/trunk/test/ruby/test_io.rb
new file mode 100644
index 0000000000..de1a1526eb
--- /dev/null
+++ b/trunk/test/ruby/test_io.rb
@@ -0,0 +1,1276 @@
+require 'test/unit'
+require 'tmpdir'
+require 'io/nonblock'
+require 'socket'
+require 'stringio'
+require 'timeout'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestIO < Test::Unit::TestCase
+ def test_gets_rs
+ # default_rs
+ r, w = IO.pipe
+ w.print "aaa\nbbb\n"
+ w.close
+ assert_equal "aaa\n", r.gets
+ assert_equal "bbb\n", r.gets
+ assert_nil r.gets
+ r.close
+
+ # nil
+ r, w = IO.pipe
+ w.print "a\n\nb\n\n"
+ w.close
+ assert_equal "a\n\nb\n\n", r.gets(nil)
+ assert_nil r.gets("")
+ r.close
+
+ # "\377"
+ r, w = IO.pipe('ascii-8bit')
+ w.print "\377xyz"
+ w.close
+ r.binmode
+ assert_equal("\377", r.gets("\377"), "[ruby-dev:24460]")
+ r.close
+
+ # ""
+ r, w = IO.pipe
+ w.print "a\n\nb\n\n"
+ w.close
+ assert_equal "a\n\n", r.gets(""), "[ruby-core:03771]"
+ assert_equal "b\n\n", r.gets("")
+ assert_nil r.gets("")
+ r.close
+ end
+
+ def test_gets_limit_extra_arg
+ with_pipe {|r, w|
+ r, w = IO.pipe
+ w << "0123456789"
+ w.close
+ assert_raise(TypeError) { r.gets(3,nil) }
+ }
+ end
+
+ # This test cause SEGV.
+ def test_ungetc
+ r, w = IO.pipe
+ w.close
+ assert_raise(IOError, "[ruby-dev:31650]") { 20000.times { r.ungetc "a" } }
+ ensure
+ r.close
+ end
+
+ def test_each_byte
+ r, w = IO.pipe
+ w << "abc def"
+ w.close
+ r.each_byte {|byte| break if byte == 32 }
+ assert_equal("def", r.read, "[ruby-dev:31659]")
+ ensure
+ r.close
+ end
+
+ def test_rubydev33072
+ assert_raise(Errno::ENOENT, "[ruby-dev:33072]") do
+ File.read("empty", nil, nil, {})
+ end
+ end
+
+ def with_pipe
+ r, w = IO.pipe
+ begin
+ yield r, w
+ ensure
+ r.close unless r.closed?
+ w.close unless w.closed?
+ end
+ end
+
+ def with_read_pipe(content)
+ r, w = IO.pipe
+ w << content
+ w.close
+ begin
+ yield r
+ ensure
+ r.close
+ end
+ end
+
+ def mkcdtmpdir
+ Dir.mktmpdir {|d|
+ Dir.chdir(d) {
+ yield
+ }
+ }
+ end
+
+ def test_copy_stream
+ mkcdtmpdir {
+
+ content = "foobar"
+ File.open("src", "w") {|f| f << content }
+ ret = IO.copy_stream("src", "dst")
+ assert_equal(content.bytesize, ret)
+ assert_equal(content, File.read("dst"))
+
+ # overwrite by smaller file.
+ content = "baz"
+ File.open("src", "w") {|f| f << content }
+ ret = IO.copy_stream("src", "dst")
+ assert_equal(content.bytesize, ret)
+ assert_equal(content, File.read("dst"))
+
+ ret = IO.copy_stream("src", "dst", 2)
+ assert_equal(2, ret)
+ assert_equal(content[0,2], File.read("dst"))
+
+ ret = IO.copy_stream("src", "dst", 0)
+ assert_equal(0, ret)
+ assert_equal("", File.read("dst"))
+
+ ret = IO.copy_stream("src", "dst", nil, 1)
+ assert_equal(content.bytesize-1, ret)
+ assert_equal(content[1..-1], File.read("dst"))
+
+ assert_raise(Errno::ENOENT) {
+ IO.copy_stream("nodir/foo", "dst")
+ }
+
+ assert_raise(Errno::ENOENT) {
+ IO.copy_stream("src", "nodir/bar")
+ }
+
+ with_pipe {|r, w|
+ ret = IO.copy_stream("src", w)
+ assert_equal(content.bytesize, ret)
+ w.close
+ assert_equal(content, r.read)
+ }
+
+ with_pipe {|r, w|
+ w.close
+ assert_raise(IOError) { IO.copy_stream("src", w) }
+ }
+
+ pipe_content = "abc"
+ with_read_pipe(pipe_content) {|r|
+ ret = IO.copy_stream(r, "dst")
+ assert_equal(pipe_content.bytesize, ret)
+ assert_equal(pipe_content, File.read("dst"))
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ w2.sync = false
+ w2 << "def"
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(2, ret)
+ w2.close
+ assert_equal("defbc", r2.read)
+ }
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ w2.sync = false
+ w2 << "def"
+ ret = IO.copy_stream(r1, w2, 1)
+ assert_equal(1, ret)
+ w2.close
+ assert_equal("defb", r2.read)
+ }
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(2, ret)
+ w2.close
+ assert_equal("bc", r2.read)
+ }
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ ret = IO.copy_stream(r1, w2, 1)
+ assert_equal(1, ret)
+ w2.close
+ assert_equal("b", r2.read)
+ }
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ ret = IO.copy_stream(r1, w2, 0)
+ assert_equal(0, ret)
+ w2.close
+ assert_equal("", r2.read)
+ }
+ }
+
+ with_pipe {|r1, w1|
+ w1 << "abc"
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ w1 << "def"
+ w1.close
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(5, ret)
+ w2.close
+ assert_equal("bcdef", r2.read)
+ }
+ }
+
+ with_pipe {|r, w|
+ ret = IO.copy_stream("src", w, 1, 1)
+ assert_equal(1, ret)
+ w.close
+ assert_equal(content[1,1], r.read)
+ }
+
+ with_read_pipe("abc") {|r1|
+ assert_equal("a", r1.getc)
+ with_pipe {|r2, w2|
+ w2.nonblock = true
+ s = w2.syswrite("a" * 100000)
+ t = Thread.new { sleep 0.1; r2.read }
+ ret = IO.copy_stream(r1, w2)
+ w2.close
+ assert_equal(2, ret)
+ assert_equal("a" * s + "bc", t.value)
+ }
+ }
+
+ bigcontent = "abc" * 123456
+ File.open("bigsrc", "w") {|f| f << bigcontent }
+ ret = IO.copy_stream("bigsrc", "bigdst")
+ assert_equal(bigcontent.bytesize, ret)
+ assert_equal(bigcontent, File.read("bigdst"))
+
+ File.unlink("bigdst")
+ ret = IO.copy_stream("bigsrc", "bigdst", nil, 100)
+ assert_equal(bigcontent.bytesize-100, ret)
+ assert_equal(bigcontent[100..-1], File.read("bigdst"))
+
+ File.unlink("bigdst")
+ ret = IO.copy_stream("bigsrc", "bigdst", 30000, 100)
+ assert_equal(30000, ret)
+ assert_equal(bigcontent[100, 30000], File.read("bigdst"))
+
+ File.open("bigsrc") {|f|
+ assert_equal(0, f.pos)
+ ret = IO.copy_stream(f, "bigdst", nil, 10)
+ assert_equal(bigcontent.bytesize-10, ret)
+ assert_equal(bigcontent[10..-1], File.read("bigdst"))
+ assert_equal(0, f.pos)
+ ret = IO.copy_stream(f, "bigdst", 40, 30)
+ assert_equal(40, ret)
+ assert_equal(bigcontent[30, 40], File.read("bigdst"))
+ assert_equal(0, f.pos)
+ }
+
+ with_pipe {|r, w|
+ w.close
+ assert_raise(IOError) { IO.copy_stream("src", w) }
+ }
+
+ megacontent = "abc" * 1234567
+ File.open("megasrc", "w") {|f| f << megacontent }
+
+ with_pipe {|r1, w1|
+ with_pipe {|r2, w2|
+ t1 = Thread.new { w1 << megacontent; w1.close }
+ t2 = Thread.new { r2.read }
+ r1.nonblock = true
+ w2.nonblock = true
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(megacontent.bytesize, ret)
+ w2.close
+ t1.join
+ assert_equal(megacontent, t2.value)
+ }
+ }
+
+ with_pipe {|r1, w1|
+ with_pipe {|r2, w2|
+ t1 = Thread.new { w1 << megacontent; w1.close }
+ t2 = Thread.new { r2.read }
+ ret = IO.copy_stream(r1, w2)
+ assert_equal(megacontent.bytesize, ret)
+ w2.close
+ t1.join
+ assert_equal(megacontent, t2.value)
+ }
+ }
+
+ with_pipe {|r, w|
+ t = Thread.new { r.read }
+ ret = IO.copy_stream("megasrc", w)
+ assert_equal(megacontent.bytesize, ret)
+ w.close
+ assert_equal(megacontent, t.value)
+ }
+ }
+ end
+
+ def test_copy_stream_rbuf
+ mkcdtmpdir {
+ with_pipe {|r, w|
+ File.open("foo", "w") {|f| f << "abcd" }
+ File.open("foo") {|f|
+ f.read(1)
+ assert_equal(3, IO.copy_stream(f, w, 10, 1))
+ }
+ w.close
+ assert_equal("bcd", r.read)
+ }
+ }
+ end
+
+ def with_socketpair
+ s1, s2 = UNIXSocket.pair
+ begin
+ yield s1, s2
+ ensure
+ s1.close unless s1.closed?
+ s2.close unless s2.closed?
+ end
+ end
+
+ def test_copy_stream_socket
+ return unless defined? UNIXSocket
+ mkcdtmpdir {
+
+ content = "foobar"
+ File.open("src", "w") {|f| f << content }
+
+ with_socketpair {|s1, s2|
+ ret = IO.copy_stream("src", s1)
+ assert_equal(content.bytesize, ret)
+ s1.close
+ assert_equal(content, s2.read)
+ }
+
+ bigcontent = "abc" * 123456
+ File.open("bigsrc", "w") {|f| f << bigcontent }
+
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream("bigsrc", s1)
+ assert_equal(bigcontent.bytesize, ret)
+ s1.close
+ result = t.value
+ assert_equal(bigcontent, result)
+ }
+
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream("bigsrc", s1, 10000)
+ assert_equal(10000, ret)
+ s1.close
+ result = t.value
+ assert_equal(bigcontent[0,10000], result)
+ }
+
+ File.open("bigsrc") {|f|
+ assert_equal(0, f.pos)
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream(f, s1, nil, 100)
+ assert_equal(bigcontent.bytesize-100, ret)
+ assert_equal(0, f.pos)
+ s1.close
+ result = t.value
+ assert_equal(bigcontent[100..-1], result)
+ }
+ }
+
+ File.open("bigsrc") {|f|
+ assert_equal(bigcontent[0,100], f.read(100))
+ assert_equal(100, f.pos)
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ ret = IO.copy_stream(f, s1)
+ assert_equal(bigcontent.bytesize-100, ret)
+ assert_equal(bigcontent.length, f.pos)
+ s1.close
+ result = t.value
+ assert_equal(bigcontent[100..-1], result)
+ }
+ }
+
+ megacontent = "abc" * 1234567
+ File.open("megasrc", "w") {|f| f << megacontent }
+
+ with_socketpair {|s1, s2|
+ t = Thread.new { s2.read }
+ s1.nonblock = true
+ ret = IO.copy_stream("megasrc", s1)
+ assert_equal(megacontent.bytesize, ret)
+ s1.close
+ result = t.value
+ assert_equal(megacontent, result)
+ }
+ }
+ end
+
+ def test_copy_stream_strio
+ src = StringIO.new("abcd")
+ dst = StringIO.new
+ ret = IO.copy_stream(src, dst)
+ assert_equal(4, ret)
+ assert_equal("abcd", dst.string)
+ assert_equal(4, src.pos)
+ end
+
+ def test_copy_stream_strio_len
+ src = StringIO.new("abcd")
+ dst = StringIO.new
+ ret = IO.copy_stream(src, dst, 3)
+ assert_equal(3, ret)
+ assert_equal("abc", dst.string)
+ assert_equal(3, src.pos)
+ end
+
+ def test_copy_stream_strio_off
+ src = StringIO.new("abcd")
+ with_pipe {|r, w|
+ assert_raise(ArgumentError) {
+ IO.copy_stream(src, w, 3, 1)
+ }
+ }
+ end
+
+ def test_copy_stream_fname_to_strio
+ mkcdtmpdir {
+ File.open("foo", "w") {|f| f << "abcd" }
+ src = "foo"
+ dst = StringIO.new
+ ret = IO.copy_stream(src, dst, 3)
+ assert_equal(3, ret)
+ assert_equal("abc", dst.string)
+ }
+ end
+
+ def test_copy_stream_strio_to_fname
+ mkcdtmpdir {
+ # StringIO to filename
+ src = StringIO.new("abcd")
+ ret = IO.copy_stream(src, "fooo", 3)
+ assert_equal(3, ret)
+ assert_equal("abc", File.read("fooo"))
+ assert_equal(3, src.pos)
+ }
+ end
+
+ def test_copy_stream_io_to_strio
+ mkcdtmpdir {
+ # IO to StringIO
+ File.open("bar", "w") {|f| f << "abcd" }
+ File.open("bar") {|src|
+ dst = StringIO.new
+ ret = IO.copy_stream(src, dst, 3)
+ assert_equal(3, ret)
+ assert_equal("abc", dst.string)
+ assert_equal(3, src.pos)
+ }
+ }
+ end
+
+ def test_copy_stream_strio_to_io
+ mkcdtmpdir {
+ # StringIO to IO
+ src = StringIO.new("abcd")
+ ret = File.open("baz", "w") {|dst|
+ IO.copy_stream(src, dst, 3)
+ }
+ assert_equal(3, ret)
+ assert_equal("abc", File.read("baz"))
+ assert_equal(3, src.pos)
+ }
+ end
+
+ def test_copy_stream_strio_flush
+ with_pipe {|r, w|
+ w.sync = false
+ w.write "zz"
+ src = StringIO.new("abcd")
+ IO.copy_stream(src, w)
+ t = Thread.new {
+ w.close
+ }
+ assert_equal("zzabcd", r.read)
+ t.join
+ }
+ end
+
+ def test_copy_stream_strio_rbuf
+ with_pipe {|r, w|
+ w << "abcd"
+ w.close
+ assert_equal("a", r.read(1))
+ sio = StringIO.new
+ IO.copy_stream(r, sio)
+ assert_equal("bcd", sio.string)
+ }
+ end
+
+ def test_copy_stream_src_wbuf
+ mkcdtmpdir {
+ with_pipe {|r, w|
+ File.open("foe", "w+") {|f|
+ f.write "abcd\n"
+ f.rewind
+ f.write "xy"
+ IO.copy_stream(f, w)
+ }
+ assert_equal("xycd\n", File.read("foe"))
+ w.close
+ assert_equal("cd\n", r.read)
+ r.close
+ }
+ }
+ end
+
+ def test_copy_stream_dst_rbuf
+ mkcdtmpdir {
+ with_pipe {|r, w|
+ w << "xyz"
+ w.close
+ File.open("fom", "w+b") {|f|
+ f.write "abcd\n"
+ f.rewind
+ assert_equal("abc", f.read(3))
+ f.ungetc "c"
+ IO.copy_stream(r, f)
+ }
+ assert_equal("abxyz", File.read("fom"))
+ }
+ }
+ end
+
+ def safe_4
+ Thread.new do
+ Timeout.timeout(10) do
+ $SAFE = 4
+ yield
+ end
+ end.join
+ end
+
+ def pipe(wp, rp)
+ r, w = IO.pipe
+ rt = Thread.new { rp.call(r) }
+ wt = Thread.new { wp.call(w) }
+ flunk("timeout") unless rt.join(10) && wt.join(10)
+ ensure
+ r.close unless !r || r.closed?
+ w.close unless !w || w.closed?
+ (rt.kill; rt.join) if rt
+ (wt.kill; wt.join) if wt
+ end
+
+ def pipe2(&b)
+ a = []
+ a << IO.pipe while true
+ rescue Errno::EMFILE, Errno::ENFILE, Errno::ENOMEM
+ yield(*a.last)
+ ensure
+ a.each do |r, w|
+ r.close unless !r || r.closed?
+ w.close unless !w || w.closed?
+ end
+ end
+
+ def ruby(*args)
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def test_try_convert
+ assert_equal(STDOUT, IO.try_convert(STDOUT))
+ assert_equal(nil, IO.try_convert("STDOUT"))
+ end
+
+ def test_ungetc2
+ f = false
+ pipe(proc do |w|
+ 0 until f
+ w.write("1" * 10000)
+ w.close
+ end, proc do |r|
+ r.ungetc("0" * 10000)
+ f = true
+ assert_equal("0" * 10000 + "1" * 10000, r.read)
+ end)
+ end
+
+ def test_write_non_writable
+ with_pipe do |r, w|
+ assert_raise(IOError) do
+ r.write "foobarbaz"
+ end
+ end
+ end
+
+ def test_dup
+ ruby do |f|
+ f2 = f.dup
+ f.puts "foo"
+ f2.puts "bar"
+ f.close_write
+ f2.close_write
+ assert_equal("foo\nbar\n", f.read)
+ assert_equal("", f2.read)
+ end
+
+ pipe2 do |r, w|
+ assert_raise(Errno::EMFILE, Errno::ENFILE, Errno::ENOMEM) do
+ r2, w2 = r.dup, w.dup
+ end
+ end
+ end
+
+ def test_inspect
+ with_pipe do |r, w|
+ assert(r.inspect =~ /^#<IO:0x[0-9a-f]+>$/)
+ assert_raise(SecurityError) do
+ safe_4 { r.inspect }
+ end
+ end
+ end
+
+ def test_readpartial
+ pipe(proc do |w|
+ w.write "foobarbaz"
+ w.close
+ end, proc do |r|
+ assert_raise(ArgumentError) { r.readpartial(-1) }
+ assert_equal("fooba", r.readpartial(5))
+ r.readpartial(5, s = "")
+ assert_equal("rbaz", s)
+ end)
+ end
+
+ def test_readpartial_error
+ with_pipe do |r, w|
+ s = ""
+ t = Thread.new { r.readpartial(5, s) }
+ 0 until s.size == 5
+ s.clear
+ w.write "foobarbaz"
+ w.close
+ assert_raise(RuntimeError) { t.join }
+ end
+ end
+
+ def test_read
+ pipe(proc do |w|
+ w.write "foobarbaz"
+ w.close
+ end, proc do |r|
+ assert_raise(ArgumentError) { r.read(-1) }
+ assert_equal("fooba", r.read(5))
+ r.read(nil, s = "")
+ assert_equal("rbaz", s)
+ end)
+ end
+
+ def test_read_error
+ with_pipe do |r, w|
+ s = ""
+ t = Thread.new { r.read(5, s) }
+ 0 until s.size == 5
+ s.clear
+ w.write "foobarbaz"
+ w.close
+ assert_raise(RuntimeError) { t.join }
+ end
+ end
+
+ def test_write_nonblock
+ pipe(proc do |w|
+ w.write_nonblock(1)
+ w.close
+ end, proc do |r|
+ assert_equal("1", r.read)
+ end)
+ end
+
+ def test_gets
+ pipe(proc do |w|
+ w.write "foobarbaz"
+ w.close
+ end, proc do |r|
+ assert_equal("", r.gets(0))
+ assert_equal("foobarbaz", s = r.gets(9))
+ end)
+ end
+
+ def test_close_read
+ ruby do |f|
+ f.close_read
+ f.write "foobarbaz"
+ assert_raise(IOError) { f.read }
+ end
+ end
+
+ def test_close_read_pipe
+ with_pipe do |r, w|
+ r.close_read
+ assert_raise(Errno::EPIPE) { w.write "foobarbaz" }
+ end
+ end
+
+ def test_close_read_security_error
+ with_pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close_read }
+ end
+ end
+ end
+
+ def test_close_read_non_readable
+ with_pipe do |r, w|
+ assert_raise(IOError) do
+ w.close_read
+ end
+ end
+ end
+
+ def test_close_write
+ ruby do |f|
+ f.write "foobarbaz"
+ f.close_write
+ assert_equal("foobarbaz", f.read)
+ end
+ end
+
+ def test_close_write_security_error
+ with_pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close_write }
+ end
+ end
+ end
+
+ def test_close_write_non_readable
+ with_pipe do |r, w|
+ assert_raise(IOError) do
+ r.close_write
+ end
+ end
+ end
+
+ def test_pid
+ r, w = IO.pipe
+ assert_equal(nil, r.pid)
+ assert_equal(nil, w.pid)
+
+ pipe = IO.popen(EnvUtil.rubybin, "r+")
+ pid1 = pipe.pid
+ pipe.puts "p $$"
+ pipe.close_write
+ pid2 = pipe.read.chomp.to_i
+ assert_equal(pid2, pid1)
+ assert_equal(pid2, pipe.pid)
+ pipe.close
+ assert_raise(IOError) { pipe.pid }
+ end
+
+ def make_tempfile
+ t = Tempfile.new("foo")
+ t.binmode
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ t
+ end
+
+ def test_set_lineno
+ t = make_tempfile
+
+ ruby("-e", <<-SRC, t.path) do |f|
+ open(ARGV[0]) do |f|
+ p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.lineno = 1000; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.rewind; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.gets; p $.
+ end
+ SRC
+ assert_equal("nil,1,2,2,1001,1001,1001,1,2,3,3", f.read.chomp.gsub("\n", ","))
+ end
+
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ r.gets; assert_equal(1, $.)
+ r.gets; assert_equal(2, $.)
+ r.lineno = 1000; assert_equal(2, $.)
+ r.gets; assert_equal(1001, $.)
+ r.gets; assert_equal(1001, $.)
+ end)
+ end
+
+ def test_readline
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ r.readline; assert_equal(1, $.)
+ r.readline; assert_equal(2, $.)
+ r.lineno = 1000; assert_equal(2, $.)
+ r.readline; assert_equal(1001, $.)
+ assert_raise(EOFError) { r.readline }
+ end)
+ end
+
+ def test_each_char
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ a = []
+ r.each_char {|c| a << c }
+ assert_equal(%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"], a)
+ end)
+ end
+
+ def test_lines
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ e = r.lines
+ assert_equal("foo\n", e.next)
+ assert_equal("bar\n", e.next)
+ assert_equal("baz\n", e.next)
+ assert_raise(StopIteration) { e.next }
+ end)
+ end
+
+ def test_bytes
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ e = r.bytes
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c.ord, e.next)
+ end
+ assert_raise(StopIteration) { e.next }
+ end)
+ end
+
+ def test_chars
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ e = r.chars
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c, e.next)
+ end
+ assert_raise(StopIteration) { e.next }
+ end)
+ end
+
+ def test_readbyte
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c.ord, r.readbyte)
+ end
+ assert_raise(EOFError) { r.readbyte }
+ end)
+ end
+
+ def test_readchar
+ pipe(proc do |w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c, r.readchar)
+ end
+ assert_raise(EOFError) { r.readchar }
+ end)
+ end
+
+ def test_close_on_exec
+ # xxx
+ ruby do |f|
+ assert_equal(false, f.close_on_exec?)
+ f.close_on_exec = true
+ assert_equal(true, f.close_on_exec?)
+ f.close_on_exec = false
+ assert_equal(false, f.close_on_exec?)
+ end
+
+ with_pipe do |r, w|
+ assert_equal(false, r.close_on_exec?)
+ r.close_on_exec = true
+ assert_equal(true, r.close_on_exec?)
+ r.close_on_exec = false
+ assert_equal(false, r.close_on_exec?)
+
+ assert_equal(false, w.close_on_exec?)
+ w.close_on_exec = true
+ assert_equal(true, w.close_on_exec?)
+ w.close_on_exec = false
+ assert_equal(false, w.close_on_exec?)
+ end
+ end
+
+ def test_close_security_error
+ with_pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close }
+ end
+ end
+ end
+
+ def test_sysseek
+ t = make_tempfile
+
+ open(t.path) do |f|
+ f.sysseek(-4, IO::SEEK_END)
+ assert_equal("baz\n", f.read)
+ end
+
+ open(t.path) do |f|
+ a = [f.getc, f.getc, f.getc]
+ a.reverse_each {|c| f.ungetc c }
+ assert_raise(IOError) { f.sysseek(1) }
+ end
+ end
+
+ def test_syswrite
+ t = make_tempfile
+
+ open(t.path, "w") do |f|
+ o = Object.new
+ def o.to_s; "FOO\n"; end
+ f.syswrite(o)
+ end
+ assert_equal("FOO\n", File.read(t.path))
+ end
+
+ def test_sysread
+ t = make_tempfile
+
+ open(t.path) do |f|
+ a = [f.getc, f.getc, f.getc]
+ a.reverse_each {|c| f.ungetc c }
+ assert_raise(IOError) { f.sysread(1) }
+ end
+ end
+
+ def test_flag
+ t = make_tempfile
+
+ assert_raise(ArgumentError) do
+ open(t.path, "z") { }
+ end
+
+ assert_raise(ArgumentError) do
+ open(t.path, "rr") { }
+ end
+ end
+
+ def test_sysopen
+ t = make_tempfile
+
+ fd = IO.sysopen(t.path)
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ assert_equal("foo\nbar\nbaz\n", f.read)
+ f.close
+
+ fd = IO.sysopen(t.path, "w", 0666)
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ f.write("FOO\n")
+ f.close
+
+ fd = IO.sysopen(t.path, "r")
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ assert_equal("FOO\n", f.read)
+ f.close
+ end
+
+ def test_open_redirect
+ o = Object.new
+ def o.to_open; self; end
+ assert_equal(o, open(o))
+ o2 = nil
+ open(o) do |f|
+ o2 = f
+ end
+ assert_equal(o, o2)
+ end
+
+ def test_open_pipe
+ open("|" + EnvUtil.rubybin, "r+") do |f|
+ f.puts "puts 'foo'"
+ f.close_write
+ assert_equal("foo\n", f.read)
+ end
+ end
+
+ def test_reopen
+ t = make_tempfile
+
+ with_pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.reopen(t.path) }
+ end
+ end
+
+ open(__FILE__) do |f|
+ f.gets
+ assert_nothing_raised {
+ f.reopen(t.path)
+ assert_equal("foo\n", f.gets)
+ }
+ end
+ end
+
+ def test_foreach
+ a = []
+ IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ t = make_tempfile
+
+ a = []
+ IO.foreach(t.path) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:mode => "r" }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:open_args => [] }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:open_args => ["r"] }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, "b") {|x| a << x }
+ assert_equal(["foo\nb", "ar\nb", "az\n"], a)
+
+ a = []
+ IO.foreach(t.path, 3) {|x| a << x }
+ assert_equal(["foo", "\n", "bar", "\n", "baz", "\n"], a)
+
+ a = []
+ IO.foreach(t.path, "b", 3) {|x| a << x }
+ assert_equal(["foo", "\nb", "ar\n", "b", "az\n"], a)
+
+ end
+
+ def test_s_readlines
+ t = make_tempfile
+
+ assert_equal(["foo\n", "bar\n", "baz\n"], IO.readlines(t.path))
+ assert_equal(["foo\nb", "ar\nb", "az\n"], IO.readlines(t.path, "b"))
+ assert_equal(["fo", "o\n", "ba", "r\n", "ba", "z\n"], IO.readlines(t.path, 2))
+ assert_equal(["fo", "o\n", "b", "ar", "\nb", "az", "\n"], IO.readlines(t.path, "b", 2))
+ end
+
+ def test_printf
+ pipe(proc do |w|
+ printf(w, "foo %s baz\n", "bar")
+ w.close_write
+ end, proc do |r|
+ assert_equal("foo bar baz\n", r.read)
+ end)
+ end
+
+ def test_print
+ t = make_tempfile
+
+ assert_in_out_err(["-", t.path], "print while $<.gets", %w(foo bar baz), [])
+ end
+
+ def test_putc
+ pipe(proc do |w|
+ w.putc "A"
+ w.putc "BC"
+ w.putc 68
+ w.close_write
+ end, proc do |r|
+ assert_equal("ABD", r.read)
+ end)
+
+ assert_in_out_err([], "putc 65", %w(A), [])
+ end
+
+ def test_puts_recursive_array
+ a = ["foo"]
+ a << a
+ pipe(proc do |w|
+ w.puts a
+ w.close
+ end, proc do |r|
+ assert_equal("foo\n[...]\n", r.read)
+ end)
+ end
+
+ def test_display
+ pipe(proc do |w|
+ "foo".display(w)
+ w.close
+ end, proc do |r|
+ assert_equal("foo", r.read)
+ end)
+
+ assert_in_out_err([], "'foo'.display", %w(foo), [])
+ end
+
+ def test_set_stdout
+ assert_raise(TypeError) { $> = Object.new }
+
+ assert_in_out_err([], "$> = $stderr\nputs 'foo'", [], %w(foo))
+ end
+
+ def test_initialize
+ t = make_tempfile
+
+ fd = IO.sysopen(t.path)
+ assert_kind_of(Integer, fd)
+ f = IO.new(fd, "w")
+ f.write("FOO\n")
+ f.close
+
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+
+ with_pipe do |r, w|
+ assert_raise(RuntimeError) do
+ o = Object.new
+ class << o; self; end.instance_eval do
+ define_method(:to_io) { r }
+ end
+ w.instance_eval { initialize(o) }
+ end
+ end
+
+ pipe(proc do |w|
+ w = IO.new(w)
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ end, proc do |r|
+ r = IO.new(r)
+ assert_equal("foo\nbar\nbaz\n", r.read)
+ end)
+
+ with_pipe do |r, w|
+ assert_raise(ArgumentError) { IO.new(r, "r+") }
+ end
+
+ f = open(t.path)
+ assert_raise(RuntimeError) do
+ f.instance_eval { initialize }
+ end
+ end
+
+ def test_new_with_block
+ assert_in_out_err([], "r, w = IO.pipe; IO.new(r) {}", [], /^.+$/)
+ end
+
+ def test_readline2
+ assert_in_out_err(["-e", <<-SRC], "foo\nbar\nbaz\n", %w(foo bar baz end), [])
+ puts readline
+ puts readline
+ puts readline
+ begin
+ puts readline
+ rescue EOFError
+ puts "end"
+ end
+ SRC
+ end
+
+ def test_readlines
+ assert_in_out_err(["-e", "p readlines"], "foo\nbar\nbaz\n",
+ ["[\"foo\\n\", \"bar\\n\", \"baz\\n\"]"], [])
+ end
+
+ def test_s_read
+ t = make_tempfile
+
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+ assert_equal("foo\nba", File.read(t.path, 6))
+ assert_equal("bar\n", File.read(t.path, 4, 4))
+ end
+
+ def test_uninitialized
+ assert_raise(IOError) { IO.allocate.print "" }
+ end
+
+ def test_nofollow
+ # O_NOFOLLOW is not standard.
+ return if /freebsd|linux/ !~ RUBY_PLATFORM
+ return unless defined? File::NOFOLLOW
+ mkcdtmpdir {
+ open("file", "w") {|f| f << "content" }
+ begin
+ File.symlink("file", "slnk")
+ rescue NotImplementedError
+ return
+ end
+ assert_raise(Errno::EMLINK, Errno::ELOOP) {
+ open("slnk", File::RDONLY|File::NOFOLLOW) {}
+ }
+ assert_raise(Errno::EMLINK, Errno::ELOOP) {
+ File.foreach("slnk", :open_args=>[File::RDONLY|File::NOFOLLOW]) {}
+ }
+ }
+ end
+end
diff --git a/trunk/test/ruby/test_io_m17n.rb b/trunk/test/ruby/test_io_m17n.rb
new file mode 100644
index 0000000000..47d04a18d5
--- /dev/null
+++ b/trunk/test/ruby/test_io_m17n.rb
@@ -0,0 +1,1334 @@
+require 'test/unit'
+require 'tmpdir'
+require 'timeout'
+require_relative 'envutil'
+
+class TestIO_M17N < Test::Unit::TestCase
+ ENCS = [
+ Encoding::ASCII_8BIT,
+ Encoding::EUC_JP,
+ Encoding::Shift_JIS,
+ Encoding::UTF_8
+ ]
+
+ def with_tmpdir
+ Dir.mktmpdir {|dir|
+ Dir.chdir(dir) {
+ yield dir
+ }
+ }
+ end
+
+ def with_pipe(*args)
+ r, w = IO.pipe(*args)
+ begin
+ yield r, w
+ ensure
+ r.close if !r.closed?
+ w.close if !w.closed?
+ end
+ end
+
+ def generate_file(path, content)
+ open(path, "wb") {|f| f.write content }
+ end
+
+ def encdump(str)
+ "#{str.dump}.force_encoding(#{str.encoding.name.dump})"
+ end
+
+ def assert_str_equal(expected, actual, message=nil)
+ full_message = build_message(message, <<EOT)
+#{encdump expected} expected but not equal to
+#{encdump actual}.
+EOT
+ assert_block(full_message) { expected == actual }
+ end
+
+ def test_open_r
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r") {|f|
+ assert_equal(Encoding.default_external, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_rb
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "rb") {|f|
+ assert_equal(Encoding.default_external, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r:euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_in_opt
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r", encoding: "euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_in_opt2
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r", external_encoding: "euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_enc
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r:euc-jp:utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_enc_in_opt
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r", encoding: "euc-jp:utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_r_enc_enc_in_opt2
+ with_tmpdir {
+ generate_file('tmp', "")
+ open("tmp", "r", external_encoding: "euc-jp", internal_encoding: "utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w
+ with_tmpdir {
+ open("tmp", "w") {|f|
+ assert_equal(nil, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_wb
+ with_tmpdir {
+ open("tmp", "wb") {|f|
+ assert_equal(nil, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc
+ with_tmpdir {
+ open("tmp", "w:euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_in_opt
+ with_tmpdir {
+ open("tmp", "w", encoding: "euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_in_opt2
+ with_tmpdir {
+ open("tmp", "w", external_encoding: "euc-jp") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_enc
+ with_tmpdir {
+ open("tmp", "w:euc-jp:utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_enc_in_opt
+ with_tmpdir {
+ open("tmp", "w", encoding: "euc-jp:utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_enc_in_opt2
+ with_tmpdir {
+ open("tmp", "w", external_encoding: "euc-jp", internal_encoding: "utf-8") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_open_w_enc_enc_perm
+ with_tmpdir {
+ open("tmp", "w:euc-jp:utf-8", 0600) {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ }
+ }
+ end
+
+ def test_io_new_enc
+ with_tmpdir {
+ generate_file("tmp", "\xa1")
+ fd = IO.sysopen("tmp")
+ f = IO.new(fd, "r:sjis")
+ begin
+ assert_equal(Encoding::Shift_JIS, f.read.encoding)
+ ensure
+ f.close
+ end
+ }
+ end
+
+ def test_s_pipe_invalid
+ r, w = IO.pipe("utf-8", "euc-jp", :invalid=>:replace)
+ w << "\x80"
+ w.close
+ assert_equal("?", r.read)
+ ensure
+ r.close if r && !r.closed?
+ w.close if w && !w.closed?
+ end
+
+ def test_s_pipe_undef
+ r, w = IO.pipe("utf-8:euc-jp", :undef=>:replace)
+ w << "\ufffd"
+ w.close
+ assert_equal("?", r.read)
+ ensure
+ r.close if r && !r.closed?
+ w.close if w && !w.closed?
+ end
+
+ def test_dup
+ with_pipe("utf-8:euc-jp") {|r, w|
+ w << "\u3042"
+ w.close
+ r2 = r.dup
+ begin
+ assert_equal("\xA4\xA2".force_encoding("euc-jp"), r2.read)
+ ensure
+ r2.close
+ end
+
+ }
+ end
+
+ def test_dup_undef
+ with_pipe("utf-8:euc-jp", :undef=>:replace) {|r, w|
+ w << "\uFFFD"
+ w.close
+ r2 = r.dup
+ begin
+ assert_equal("?", r2.read)
+ ensure
+ r2.close
+ end
+ }
+ end
+
+ def test_stdin
+ assert_equal(Encoding.default_external, STDIN.external_encoding)
+ assert_equal(nil, STDIN.internal_encoding)
+ end
+
+ def test_stdout
+ assert_equal(nil, STDOUT.external_encoding)
+ assert_equal(nil, STDOUT.internal_encoding)
+ end
+
+ def test_stderr
+ assert_equal(nil, STDERR.external_encoding)
+ assert_equal(nil, STDERR.internal_encoding)
+ end
+
+ def test_terminator_conversion
+ with_tmpdir {
+ generate_file('tmp', "before \u00FF after")
+ s = open("tmp", "r:utf-8:iso-8859-1") {|f|
+ f.gets("\xFF".force_encoding("iso-8859-1"))
+ }
+ assert_equal(Encoding.find("iso-8859-1"), s.encoding)
+ assert_str_equal("before \xFF".force_encoding("iso-8859-1"), s, '[ruby-core:14288]')
+ }
+ end
+
+ def test_terminator_conversion2
+ with_tmpdir {
+ generate_file('tmp', "before \xA1\xA2\xA2\xA3 after")
+ s = open("tmp", "r:euc-jp:utf-8") {|f|
+ f.gets("\xA2\xA2".force_encoding("euc-jp").encode("utf-8"))
+ }
+ assert_equal(Encoding.find("utf-8"), s.encoding)
+ assert_str_equal("before \xA1\xA2\xA2\xA3 after".force_encoding("euc-jp").encode("utf-8"), s, '[ruby-core:14319]')
+ }
+ end
+
+ def test_terminator_stateful_conversion
+ with_tmpdir {
+ src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
+ generate_file('tmp', src)
+ s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
+ f.gets("0".force_encoding("euc-jp"))
+ }
+ assert_equal(Encoding.find("euc-jp"), s.encoding)
+ assert_str_equal(src.encode("euc-jp"), s)
+ }
+ end
+
+ def test_nonascii_terminator
+ with_tmpdir {
+ generate_file('tmp', "before \xA2\xA2 after")
+ open("tmp", "r:euc-jp") {|f|
+ assert_raise(ArgumentError) {
+ f.gets("\xA2\xA2".force_encoding("utf-8"))
+ }
+ }
+ }
+ end
+
+ def test_pipe_terminator_conversion
+ with_pipe("euc-jp:utf-8") {|r, w|
+ w.write "before \xa2\xa2 after"
+ rs = "\xA2\xA2".encode("utf-8", "euc-jp")
+ w.close
+ timeout(1) {
+ assert_equal("before \xa2\xa2".encode("utf-8", "euc-jp"),
+ r.gets(rs))
+ }
+ }
+ end
+
+ def test_pipe_conversion
+ with_pipe("euc-jp:utf-8") {|r, w|
+ w.write "\xa1\xa1"
+ assert_equal("\xa1\xa1".encode("utf-8", "euc-jp"), r.getc)
+ }
+ end
+
+ def test_pipe_convert_partial_read
+ with_pipe("euc-jp:utf-8") {|r, w|
+ begin
+ t = Thread.new {
+ w.write "\xa1"
+ sleep 0.1
+ w.write "\xa1"
+ }
+ assert_equal("\xa1\xa1".encode("utf-8", "euc-jp"), r.getc)
+ ensure
+ t.join if t
+ end
+ }
+ end
+
+ def test_getc_invalid
+ with_pipe("euc-jp:utf-8") {|r, w|
+ w << "\xa1xyz"
+ w.close
+ err = assert_raise(Encoding::InvalidByteSequence) { r.getc }
+ assert_equal("\xA1".force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal("xyz", r.read(10))
+ }
+ end
+
+ def test_getc_stateful_conversion
+ with_tmpdir {
+ src = "\e$B\x23\x30\x23\x31\e(B".force_encoding("iso-2022-jp")
+ generate_file('tmp', src)
+ open("tmp", "r:iso-2022-jp:euc-jp") {|f|
+ assert_equal("\xa3\xb0".force_encoding("euc-jp"), f.getc)
+ assert_equal("\xa3\xb1".force_encoding("euc-jp"), f.getc)
+ }
+ }
+ end
+
+ def test_ungetc_stateful_conversion
+ with_tmpdir {
+ src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
+ generate_file('tmp', src)
+ s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
+ f.ungetc("0".force_encoding("euc-jp"))
+ f.read
+ }
+ assert_equal(Encoding.find("euc-jp"), s.encoding)
+ assert_str_equal("0" + src.encode("euc-jp"), s)
+ }
+ end
+
+ def test_ungetc_stateful_conversion2
+ with_tmpdir {
+ src = "before \e$B\x23\x30\x23\x31\e(B after".force_encoding("iso-2022-jp")
+ former = "before \e$B\x23\x30\e(B".force_encoding("iso-2022-jp")
+ rs = "\e$B\x23\x30\e(B".force_encoding("iso-2022-jp")
+ latter = "\e$B\x23\x31\e(B after".force_encoding("iso-2022-jp")
+ generate_file('tmp', src)
+ s = open("tmp", "r:iso-2022-jp:euc-jp") {|f|
+ assert_equal(former.encode("euc-jp", "iso-2022-jp"),
+ f.gets(rs.encode("euc-jp", "iso-2022-jp")))
+ f.ungetc("0")
+ f.read
+ }
+ assert_equal(Encoding.find("euc-jp"), s.encoding)
+ assert_str_equal("0" + latter.encode("euc-jp"), s)
+ }
+ end
+
+ def test_open_ascii
+ with_tmpdir {
+ src = "abc\n"
+ generate_file('tmp', "abc\n")
+ ENCS.each {|enc|
+ s = open('tmp', "r:#{enc}") {|f| f.gets }
+ assert_equal(enc, s.encoding)
+ assert_str_equal(src, s)
+ }
+ }
+ end
+
+ def test_open_nonascii
+ with_tmpdir {
+ src = "\xc2\xa1\n"
+ generate_file('tmp', src)
+ ENCS.each {|enc|
+ content = src.dup.force_encoding(enc)
+ s = open('tmp', "r:#{enc}") {|f| f.gets }
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ }
+ end
+
+ def test_read_encoding
+ with_tmpdir {
+ src = "\xc2\xa1\n".force_encoding("ASCII-8BIT")
+ generate_file('tmp', "\xc2\xa1\n")
+ ENCS.each {|enc|
+ content = src.dup.force_encoding(enc)
+ open('tmp', "r:#{enc}") {|f|
+ s = f.getc
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content[0], s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.readchar
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content[0], s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.gets
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.readline
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ lines = f.readlines
+ assert_equal(1, lines.length)
+ s = lines[0]
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ f.each_line {|s|
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.read
+ assert_equal(enc, s.encoding)
+ assert_str_equal(content, s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.read(1)
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_str_equal(src[0], s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.readpartial(1)
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_str_equal(src[0], s)
+ }
+ open('tmp', "r:#{enc}") {|f|
+ s = f.sysread(1)
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_str_equal(src[0], s)
+ }
+ }
+ }
+ end
+
+ def test_write_noenc
+ src = "\xc2\xa1\n".force_encoding("ascii-8bit")
+ with_tmpdir {
+ open('tmp', "w") {|f|
+ ENCS.each {|enc|
+ f.write src.dup.force_encoding(enc)
+ }
+ }
+ open('tmp', 'r:ascii-8bit') {|f|
+ assert_equal(src*ENCS.length, f.read)
+ }
+ }
+ end
+
+ def test_write_conversion
+ utf8 = "\u6666"
+ eucjp = "\xb3\xa2".force_encoding("EUC-JP")
+ with_tmpdir {
+ open('tmp', "w:EUC-JP") {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ f.print utf8
+ }
+ assert_equal(eucjp, File.read('tmp').force_encoding("EUC-JP"))
+ open('tmp', 'r:EUC-JP:UTF-8') {|f|
+ assert_equal(Encoding::EUC_JP, f.external_encoding)
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ assert_equal(utf8, f.read)
+ }
+ }
+ end
+
+ def test_pipe
+ utf8 = "\u6666"
+ eucjp = "\xb3\xa2".force_encoding("EUC-JP")
+
+ with_pipe {|r,w|
+ assert_equal(Encoding.default_external, r.external_encoding)
+ assert_equal(nil, r.internal_encoding)
+ w << utf8
+ w.close
+ s = r.read
+ assert_equal(Encoding.default_external, s.encoding)
+ assert_str_equal(utf8.dup.force_encoding(Encoding.default_external), s)
+ }
+
+ with_pipe("EUC-JP") {|r,w|
+ assert_equal(Encoding::EUC_JP, r.external_encoding)
+ assert_equal(nil, r.internal_encoding)
+ w << eucjp
+ w.close
+ assert_equal(eucjp, r.read)
+ }
+
+ with_pipe("UTF-8:EUC-JP") {|r,w|
+ assert_equal(Encoding::UTF_8, r.external_encoding)
+ assert_equal(Encoding::EUC_JP, r.internal_encoding)
+ w << utf8
+ w.close
+ assert_equal(eucjp, r.read)
+ }
+
+ ENCS.each {|enc|
+ with_pipe(enc) {|r, w|
+ w << "\xc2\xa1"
+ w.close
+ s = r.getc
+ assert_equal(enc, s.encoding)
+ }
+ }
+
+ ENCS.each {|enc|
+ next if enc == Encoding::ASCII_8BIT
+ next if enc == Encoding::UTF_8
+ with_pipe("#{enc}:UTF-8") {|r, w|
+ w << "\xc2\xa1"
+ w.close
+ s = r.read
+ assert_equal(Encoding::UTF_8, s.encoding)
+ assert_equal(s.encode("UTF-8"), s)
+ }
+ }
+
+ end
+
+ def test_marshal
+ with_pipe("EUC-JP") {|r, w|
+ data = 56225
+ Marshal.dump(data, w)
+ w.close
+ result = nil
+ assert_nothing_raised("[ruby-dev:33264]") { result = Marshal.load(r) }
+ assert_equal(data, result)
+ }
+ end
+
+ def test_gets_nil
+ with_pipe("UTF-8:EUC-JP") {|r, w|
+ w << "\u{3042}"
+ w.close
+ result = r.gets(nil)
+ assert_equal("\u{3042}".encode("euc-jp"), result)
+ }
+ end
+
+ def test_gets_limit
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.gets(1))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.gets(2))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4".force_encoding("euc-jp"), r.gets(3))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4".force_encoding("euc-jp"), r.gets(4))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6".force_encoding("euc-jp"), r.gets(5))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6".force_encoding("euc-jp"), r.gets(6))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6\n".force_encoding("euc-jp"), r.gets(7))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6\n".force_encoding("euc-jp"), r.gets(8))
+ }
+ with_pipe("euc-jp") {|r, w| w << "\xa4\xa2\xa4\xa4\xa4\xa6\n\xa4\xa8\xa4\xaa"; w.close
+ assert_equal("\xa4\xa2\xa4\xa4\xa4\xa6\n".force_encoding("euc-jp"), r.gets(9))
+ }
+ end
+
+ def test_gets_invalid
+ with_pipe("utf-8:euc-jp") {|r, w|
+ before = "\u{3042}\u{3044}"
+ invalid = "\x80".force_encoding("utf-8")
+ after = "\u{3046}\u{3048}"
+ w << before + invalid + after
+ w.close
+ err = assert_raise(Encoding::InvalidByteSequence) { r.gets }
+ assert_equal(invalid.force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal(after.encode("euc-jp"), r.gets)
+ }
+ end
+
+ def test_getc_invalid2
+ with_pipe("utf-8:euc-jp") {|r, w|
+ before1 = "\u{3042}"
+ before2 = "\u{3044}"
+ invalid = "\x80".force_encoding("utf-8")
+ after1 = "\u{3046}"
+ after2 = "\u{3048}"
+ w << before1 + before2 + invalid + after1 + after2
+ w.close
+ assert_equal(before1.encode("euc-jp"), r.getc)
+ assert_equal(before2.encode("euc-jp"), r.getc)
+ err = assert_raise(Encoding::InvalidByteSequence) { r.getc }
+ assert_equal(invalid.force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal(after1.encode("euc-jp"), r.getc)
+ assert_equal(after2.encode("euc-jp"), r.getc)
+ }
+ end
+
+ def test_getc_invalid3
+ with_pipe("utf-16le:euc-jp") {|r, w|
+ before1 = "\x42\x30".force_encoding("utf-16le")
+ before2 = "\x44\x30".force_encoding("utf-16le")
+ invalid = "\x00\xd8".force_encoding("utf-16le")
+ after1 = "\x46\x30".force_encoding("utf-16le")
+ after2 = "\x48\x30".force_encoding("utf-16le")
+ w << before1 + before2 + invalid + after1 + after2
+ w.close
+ assert_equal(before1.encode("euc-jp"), r.getc)
+ assert_equal(before2.encode("euc-jp"), r.getc)
+ err = assert_raise(Encoding::InvalidByteSequence) { r.getc }
+ assert_equal(invalid.force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal(after1.encode("euc-jp"), r.getc)
+ assert_equal(after2.encode("euc-jp"), r.getc)
+ }
+ end
+
+ def test_read_all
+ with_pipe("utf-8:euc-jp") {|r, w|
+ str = "\u3042\u3044"
+ w << str
+ w.close
+ assert_equal(str.encode("euc-jp"), r.read)
+ }
+ end
+
+ def test_read_all_invalid
+ with_pipe("utf-8:euc-jp") {|r, w|
+ before = "\u{3042}\u{3044}"
+ invalid = "\x80".force_encoding("utf-8")
+ after = "\u{3046}\u{3048}"
+ w << before + invalid + after
+ w.close
+ err = assert_raise(Encoding::InvalidByteSequence) { r.read }
+ assert_equal(invalid.force_encoding("ascii-8bit"), err.error_bytes)
+ assert_equal(after.encode("euc-jp"), r.read)
+ }
+ end
+
+ def test_file_foreach
+ with_tmpdir {
+ generate_file('tst', 'a' * 8191 + "\xa1\xa1")
+ assert_nothing_raised {
+ File.foreach('tst', :encoding=>"euc-jp") {|line| line.inspect }
+ }
+ }
+ end
+
+ def test_set_encoding
+ with_pipe("utf-8:euc-jp") {|r, w|
+ s = "\u3042".force_encoding("ascii-8bit")
+ s << "\x82\xa0".force_encoding("ascii-8bit")
+ w << s
+ w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ r.set_encoding("shift_jis:euc-jp")
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ }
+ end
+
+ def test_set_encoding2
+ with_pipe("utf-8:euc-jp") {|r, w|
+ s = "\u3042".force_encoding("ascii-8bit")
+ s << "\x82\xa0".force_encoding("ascii-8bit")
+ w << s
+ w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ r.set_encoding("shift_jis", "euc-jp")
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ }
+ end
+
+ def test_set_encoding_nil
+ with_pipe("utf-8:euc-jp") {|r, w|
+ s = "\u3042".force_encoding("ascii-8bit")
+ s << "\x82\xa0".force_encoding("ascii-8bit")
+ w << s
+ w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ r.set_encoding(nil)
+ assert_equal("\x82\xa0".force_encoding(Encoding.default_external), r.read)
+ }
+ end
+
+ def test_set_encoding_enc
+ with_pipe("utf-8:euc-jp") {|r, w|
+ s = "\u3042".force_encoding("ascii-8bit")
+ s << "\x82\xa0".force_encoding("ascii-8bit")
+ w << s
+ w.close
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), r.getc)
+ r.set_encoding(Encoding::Shift_JIS)
+ assert_equal("\x82\xa0".force_encoding(Encoding::Shift_JIS), r.getc)
+ }
+ end
+
+ def test_set_encoding_invalid
+ with_pipe {|r, w|
+ w << "\x80"
+ w.close
+ r.set_encoding("utf-8:euc-jp", :invalid=>:replace)
+ assert_equal("?", r.read)
+ }
+ end
+
+ def test_set_encoding_undef
+ with_pipe {|r, w|
+ w << "\ufffd"
+ w.close
+ r.set_encoding("utf-8", "euc-jp", :undef=>:replace)
+ assert_equal("?", r.read)
+ }
+ end
+
+ def test_write_conversion_fixenc
+ with_pipe {|r, w|
+ w.set_encoding("iso-2022-jp:utf-8")
+ t = Thread.new { r.read.force_encoding("ascii-8bit") }
+ w << "\u3042"
+ w << "\u3044"
+ w.close
+ assert_equal("\e$B$\"$$\e(B".force_encoding("ascii-8bit"), t.value)
+ }
+ end
+
+ def test_write_conversion_anyenc_stateful
+ with_pipe {|r, w|
+ w.set_encoding("iso-2022-jp")
+ t = Thread.new { r.read.force_encoding("ascii-8bit") }
+ w << "\u3042"
+ w << "\x82\xa2".force_encoding("sjis")
+ w.close
+ assert_equal("\e$B$\"$$\e(B".force_encoding("ascii-8bit"), t.value)
+ }
+ end
+
+ def test_write_conversion_anyenc_stateless
+ with_pipe {|r, w|
+ w.set_encoding("euc-jp")
+ t = Thread.new { r.read.force_encoding("ascii-8bit") }
+ w << "\u3042"
+ w << "\x82\xa2".force_encoding("sjis")
+ w.close
+ assert_equal("\xa4\xa2\xa4\xa4".force_encoding("ascii-8bit"), t.value)
+ }
+ end
+
+ def test_write_conversion_anyenc_stateful_nosync
+ with_pipe {|r, w|
+ w.sync = false
+ w.set_encoding("iso-2022-jp")
+ t = Thread.new { r.read.force_encoding("ascii-8bit") }
+ w << "\u3042"
+ w << "\x82\xa2".force_encoding("sjis")
+ w.close
+ assert_equal("\e$B$\"$$\e(B".force_encoding("ascii-8bit"), t.value)
+ }
+ end
+
+ def test_stdin_external_encoding_with_reopen
+ with_tmpdir {
+ open("tst", "w+") {|f|
+ pid = spawn(EnvUtil.rubybin, '-e', <<-'End', 10=>f)
+ io = IO.new(10, "r+")
+ STDIN.reopen(io)
+ STDIN.external_encoding
+ STDIN.write "\u3042"
+ STDIN.flush
+ End
+ Process.wait pid
+ f.rewind
+ result = f.read.force_encoding("ascii-8bit")
+ assert_equal("\u3042".force_encoding("ascii-8bit"), result)
+ }
+ }
+ end
+
+ def test_popen_r_enc
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 255'", "r:ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
+
+ def test_popen_r_enc_in_opt
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 255'", "r", encoding: "ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
+
+ def test_popen_r_enc_in_opt2
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 255'", "r", external_encoding: "ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
+
+ def test_popen_r_enc_enc
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 0xa1'", "r:shift_jis:euc-jp") {|f|
+ assert_equal(Encoding::Shift_JIS, f.external_encoding)
+ assert_equal(Encoding::EUC_JP, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\x8e\xa1".force_encoding("euc-jp"), s)
+ }
+ end
+
+ def test_popen_r_enc_enc_in_opt
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 0xa1'", "r", encoding: "shift_jis:euc-jp") {|f|
+ assert_equal(Encoding::Shift_JIS, f.external_encoding)
+ assert_equal(Encoding::EUC_JP, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\x8e\xa1".force_encoding("euc-jp"), s)
+ }
+ end
+
+ def test_popen_r_enc_enc_in_opt2
+ IO.popen("#{EnvUtil.rubybin} -e 'putc 0xa1'", "r", external_encoding: "shift_jis", internal_encoding: "euc-jp") {|f|
+ assert_equal(Encoding::Shift_JIS, f.external_encoding)
+ assert_equal(Encoding::EUC_JP, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\x8e\xa1".force_encoding("euc-jp"), s)
+ }
+ end
+
+ def test_popenv_r_enc_enc_in_opt2
+ IO.popen([EnvUtil.rubybin, "-e", "putc 0xa1"], "r", external_encoding: "shift_jis", internal_encoding: "euc-jp") {|f|
+ assert_equal(Encoding::Shift_JIS, f.external_encoding)
+ assert_equal(Encoding::EUC_JP, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\x8e\xa1".force_encoding("euc-jp"), s)
+ }
+ end
+
+ def test_open_pipe_r_enc
+ open("|#{EnvUtil.rubybin} -e 'putc 255'", "r:ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
+
+ def test_s_foreach_enc
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :mode => "r:ascii-8bit") {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_in_opt
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :encoding => "ascii-8bit") {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_in_opt2
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :external_encoding => "ascii-8bit") {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_enc
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :mode => "r:utf-8:euc-jp") {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_enc_in_opt
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :mode => "r", :encoding => "utf-8:euc-jp") {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_enc_enc_in_opt2
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :mode => "r", :external_encoding => "utf-8", :internal_encoding => "euc-jp") {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :open_args => ["r:ascii-8bit"]) {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_in_opt
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :open_args => ["r", encoding: "ascii-8bit"]) {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_in_opt2
+ with_tmpdir {
+ generate_file("t", "\xff")
+ IO.foreach("t", :open_args => ["r", external_encoding: "ascii-8bit"]) {|s|
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_enc
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :open_args => ["r:utf-8:euc-jp"]) {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_enc_in_opt
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :open_args => ["r", encoding: "utf-8:euc-jp"]) {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_s_foreach_open_args_enc_enc_in_opt2
+ with_tmpdir {
+ generate_file("t", "\u3042")
+ IO.foreach("t", :open_args => ["r", external_encoding: "utf-8", internal_encoding: "euc-jp"]) {|s|
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ assert_equal("\xa4\xa2".force_encoding("euc-jp"), s)
+ }
+ }
+ end
+
+ def test_both_textmode_binmode
+ assert_raise(ArgumentError) { open("not-exist", "r", :textmode=>true, :binmode=>true) }
+ end
+
+ def test_textmode_decode_universal_newline_read
+ with_tmpdir {
+ generate_file("t.crlf", "a\r\nb\r\nc\r\n")
+ assert_equal("a\nb\nc\n", File.read("t.crlf", mode:"rt:euc-jp:utf-8"))
+ assert_equal("a\nb\nc\n", File.read("t.crlf", mode:"rt"))
+ open("t.crlf", "rt:euc-jp:utf-8") {|f| assert_equal("a\nb\nc\n", f.read) }
+ open("t.crlf", "rt") {|f| assert_equal("a\nb\nc\n", f.read) }
+ open("t.crlf", "r", :textmode=>true) {|f| assert_equal("a\nb\nc\n", f.read) }
+
+ generate_file("t.cr", "a\rb\rc\r")
+ assert_equal("a\nb\nc\n", File.read("t.cr", mode:"rt:euc-jp:utf-8"))
+ assert_equal("a\nb\nc\n", File.read("t.cr", mode:"rt"))
+
+ generate_file("t.lf", "a\nb\nc\n")
+ assert_equal("a\nb\nc\n", File.read("t.cr", mode:"rt:euc-jp:utf-8"))
+ assert_equal("a\nb\nc\n", File.read("t.cr", mode:"rt"))
+ }
+ end
+
+ def test_textmode_decode_universal_newline_getc
+ with_tmpdir {
+ generate_file("t.crlf", "a\r\nb\r\nc\r\n")
+ open("t.crlf", "rt") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("b", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+
+ generate_file("t.cr", "a\rb\rc\r")
+ open("t.cr", "rt") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("b", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+
+ generate_file("t.lf", "a\nb\nc\n")
+ open("t.lf", "rt") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("b", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+ }
+ end
+
+ def test_textmode_decode_universal_newline_gets
+ with_tmpdir {
+ generate_file("t.crlf", "a\r\nb\r\nc\r\n")
+ open("t.crlf", "rt") {|f|
+ assert_equal("a\n", f.gets)
+ assert_equal("b\n", f.gets)
+ assert_equal("c\n", f.gets)
+ assert_equal(nil, f.gets)
+ }
+
+ generate_file("t.cr", "a\rb\rc\r")
+ open("t.cr", "rt") {|f|
+ assert_equal("a\n", f.gets)
+ assert_equal("b\n", f.gets)
+ assert_equal("c\n", f.gets)
+ assert_equal(nil, f.gets)
+ }
+
+ generate_file("t.lf", "a\nb\nc\n")
+ open("t.lf", "rt") {|f|
+ assert_equal("a\n", f.gets)
+ assert_equal("b\n", f.gets)
+ assert_equal("c\n", f.gets)
+ assert_equal(nil, f.gets)
+ }
+ }
+ end
+
+ def test_textmode_decode_universal_newline_utf16
+ with_tmpdir {
+ generate_file("t.utf16be.crlf", "\0a\0\r\0\n\0b\0\r\0\n\0c\0\r\0\n")
+ assert_equal("a\nb\nc\n", File.read("t.utf16be.crlf", mode:"rt:utf-16be:utf-8"))
+
+ generate_file("t.utf16le.crlf", "a\0\r\0\n\0b\0\r\0\n\0c\0\r\0\n\0")
+ assert_equal("a\nb\nc\n", File.read("t.utf16le.crlf", mode:"rt:utf-16le:utf-8"))
+
+ generate_file("t.utf16be.cr", "\0a\0\r\0b\0\r\0c\0\r")
+ assert_equal("a\nb\nc\n", File.read("t.utf16be.cr", mode:"rt:utf-16be:utf-8"))
+
+ generate_file("t.utf16le.cr", "a\0\r\0b\0\r\0c\0\r\0")
+ assert_equal("a\nb\nc\n", File.read("t.utf16le.cr", mode:"rt:utf-16le:utf-8"))
+
+ generate_file("t.utf16be.lf", "\0a\0\n\0b\0\n\0c\0\n")
+ assert_equal("a\nb\nc\n", File.read("t.utf16be.lf", mode:"rt:utf-16be:utf-8"))
+
+ generate_file("t.utf16le.lf", "a\0\n\0b\0\n\0c\0\n\0")
+ assert_equal("a\nb\nc\n", File.read("t.utf16le.lf", mode:"rt:utf-16le:utf-8"))
+ }
+ end
+
+ def system_newline
+ File::BINARY == 0 ? "\n" : "\r\n"
+ end
+
+ def test_textmode_encode_newline
+ with_tmpdir {
+ open("t.txt", "wt") {|f|
+ f.puts "abc"
+ f.puts "def"
+ }
+ content = File.read("t.txt", :mode=>"rb")
+ nl = system_newline
+ assert_equal("abc#{nl}def#{nl}", content)
+ }
+ end
+
+ def test_binary
+ with_tmpdir {
+ src = "a\nb\rc\r\nd\n"
+ generate_file("t.txt", src)
+ open("t.txt", "rb") {|f|
+ assert_equal(src, f.read)
+ }
+ open("t.txt", "r", :binmode=>true) {|f|
+ assert_equal(src, f.read)
+ }
+ if File::BINARY == 0
+ open("t.txt", "r") {|f|
+ assert_equal(src, f.read)
+ }
+ end
+ }
+ end
+
+ def test_binmode
+ with_tmpdir {
+ src = "a\r\nb\r\nc\r\n"
+ generate_file("t.txt", src)
+ open("t.txt", "rt") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ f.binmode
+ assert_equal("\n", f.getc)
+ assert_equal("b", f.getc)
+ assert_equal("\r", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\r", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+ }
+ end
+
+ def test_binmode2
+ with_tmpdir {
+ src = "a\r\nb\r\nc\r\n"
+ generate_file("t.txt", src)
+ open("t.txt", "rt:euc-jp:utf-8") {|f|
+ assert_equal("a", f.getc)
+ assert_equal("\n", f.getc)
+ f.binmode
+ assert_equal("\n", f.getc)
+ assert_equal("b", f.getc)
+ assert_equal("\r", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal("c", f.getc)
+ assert_equal("\r", f.getc)
+ assert_equal("\n", f.getc)
+ assert_equal(nil, f.getc)
+ }
+ }
+ end
+
+ def test_invalid_r
+ with_tmpdir {
+ generate_file("t.txt", "a\x80b")
+ open("t.txt", "r:utf-8:euc-jp", :invalid => :replace) {|f|
+ assert_equal("a?b", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :invalid => :ignore) {|f|
+ assert_equal("ab", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :undef => :replace) {|f|
+ assert_raise(Encoding::InvalidByteSequence) { f.read }
+ assert_equal("b", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :undef => :ignore) {|f|
+ assert_raise(Encoding::InvalidByteSequence) { f.read }
+ assert_equal("b", f.read)
+ }
+ }
+ end
+
+ def test_undef_r
+ with_tmpdir {
+ generate_file("t.txt", "a\uFFFDb")
+ open("t.txt", "r:utf-8:euc-jp", :undef => :replace) {|f|
+ assert_equal("a?b", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :undef => :ignore) {|f|
+ assert_equal("ab", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :invalid => :replace) {|f|
+ assert_raise(Encoding::ConversionUndefined) { f.read }
+ assert_equal("b", f.read)
+ }
+ open("t.txt", "r:utf-8:euc-jp", :invalid => :ignore) {|f|
+ assert_raise(Encoding::ConversionUndefined) { f.read }
+ assert_equal("b", f.read)
+ }
+ }
+ end
+
+ def test_invalid_w
+ with_tmpdir {
+ invalid_utf8 = "a\x80b".force_encoding("utf-8")
+ open("t.txt", "w:euc-jp", :invalid => :replace) {|f|
+ assert_nothing_raised { f.write invalid_utf8 }
+ }
+ assert_equal("a?b", File.read("t.txt"))
+
+ open("t.txt", "w:euc-jp", :invalid => :ignore) {|f|
+ assert_nothing_raised { f.write invalid_utf8 }
+ }
+ assert_equal("ab", File.read("t.txt"))
+
+ open("t.txt", "w:euc-jp", :undef => :replace) {|f|
+ assert_raise(Encoding::InvalidByteSequence) { f.write invalid_utf8 }
+ }
+ open("t.txt", "w:euc-jp", :undef => :ignore) {|f|
+ assert_raise(Encoding::InvalidByteSequence) { f.write invalid_utf8 }
+ }
+ }
+ end
+
+ def test_undef_w_stateless
+ with_tmpdir {
+ generate_file("t.txt", "a\uFFFDb")
+ open("t.txt", "w:euc-jp:utf-8", :undef => :replace) {|f|
+ assert_nothing_raised { f.write "a\uFFFDb" }
+ }
+ assert_equal("a?b", File.read("t.txt"))
+ open("t.txt", "w:euc-jp:utf-8", :undef => :ignore) {|f|
+ assert_nothing_raised { f.write "a\uFFFDb" }
+ }
+ assert_equal("ab", File.read("t.txt"))
+ open("t.txt", "w:euc-jp:utf-8", :invalid => :replace) {|f|
+ assert_raise(Encoding::ConversionUndefined) { f.write "a\uFFFDb" }
+ }
+ open("t.txt", "w:euc-jp:utf-8", :invalid => :ignore) {|f|
+ assert_raise(Encoding::ConversionUndefined) { f.write "a\uFFFDb" }
+ }
+ }
+ end
+
+ def test_undef_w_stateful
+ with_tmpdir {
+ generate_file("t.txt", "a\uFFFDb")
+ open("t.txt", "w:iso-2022-jp:utf-8", :undef => :replace) {|f|
+ assert_nothing_raised { f.write "a\uFFFDb" }
+ }
+ assert_equal("a?b", File.read("t.txt"))
+ open("t.txt", "w:iso-2022-jp:utf-8", :undef => :ignore) {|f|
+ assert_nothing_raised { f.write "a\uFFFDb" }
+ }
+ assert_equal("ab", File.read("t.txt"))
+ open("t.txt", "w:iso-2022-jp:utf-8", :invalid => :replace) {|f|
+ assert_raise(Encoding::ConversionUndefined) { f.write "a\uFFFDb" }
+ }
+ open("t.txt", "w:iso-2022-jp:utf-8", :invalid => :ignore) {|f|
+ assert_raise(Encoding::ConversionUndefined) { f.write "a\uFFFDb" }
+ }
+ }
+ end
+
+end
+
diff --git a/trunk/test/ruby/test_iterator.rb b/trunk/test/ruby/test_iterator.rb
new file mode 100644
index 0000000000..f6ac645321
--- /dev/null
+++ b/trunk/test/ruby/test_iterator.rb
@@ -0,0 +1,497 @@
+require 'test/unit'
+
+class Array
+ def iter_test1
+ collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]}
+ end
+ def iter_test2
+ a = collect{|e| [e, yield(e)]}
+ a.sort{|a,b|a[1]<=>b[1]}
+ end
+end
+
+class TestIterator < Test::Unit::TestCase
+ def ttt
+ assert(iterator?)
+ end
+
+ def test_iterator
+ assert(!iterator?)
+
+ ttt{}
+
+ # yield at top level !! here's not toplevel
+ assert(!defined?(yield))
+ end
+
+ def test_array
+ $x = [1, 2, 3, 4]
+ $y = []
+
+ # iterator over array
+ for i in $x
+ $y.push i
+ end
+ assert_equal($x, $y)
+ end
+
+ def tt
+ 1.upto(10) {|i|
+ yield i
+ }
+ end
+
+ def tt2(dummy)
+ yield 1
+ end
+
+ def tt3(&block)
+ tt2(raise(ArgumentError,""),&block)
+ end
+
+ def test_nested_iterator
+ i = 0
+ tt{|i| break if i == 5}
+ assert_equal(0, i)
+
+ assert_raises(ArgumentError) do
+ tt3{}
+ end
+ end
+
+ def tt4 &block
+ tt2(raise(ArgumentError,""),&block)
+ end
+
+ def test_block_argument_without_paren
+ assert_raises(ArgumentError) do
+ tt4{}
+ end
+ end
+
+ # iterator break/redo/next
+ def test_break
+ done = true
+ loop{
+ break
+ done = false # should not reach here
+ }
+ assert(done)
+
+ done = false
+ $bad = false
+ loop {
+ break if done
+ done = true
+ next
+ $bad = true # should not reach here
+ }
+ assert(!$bad)
+
+ done = false
+ $bad = false
+ loop {
+ break if done
+ done = true
+ redo
+ $bad = true # should not reach here
+ }
+ assert(!$bad)
+
+ $x = []
+ for i in 1 .. 7
+ $x.push i
+ end
+ assert_equal(7, $x.size)
+ assert_equal([1, 2, 3, 4, 5, 6, 7], $x)
+ end
+
+ def test_append_method_to_built_in_class
+ $x = [[1,2],[3,4],[5,6]]
+ assert_equal($x.iter_test1{|x|x}, $x.iter_test2{|x|x})
+ end
+
+ class IterTest
+ def initialize(e); @body = e; end
+
+ def each0(&block); @body.each(&block); end
+ def each1(&block); @body.each {|*x| block.call(*x) } end
+ def each2(&block); @body.each {|*x| block.call(x) } end
+ def each3(&block); @body.each {|x| block.call(*x) } end
+ def each4(&block); @body.each {|x| block.call(x) } end
+ def each5; @body.each {|*x| yield(*x) } end
+ def each6; @body.each {|*x| yield(x) } end
+ def each7; @body.each {|x| yield(*x) } end
+ def each8; @body.each {|x| yield(x) } end
+
+ def f(a)
+ a
+ end
+ end
+
+ def test_itertest
+ assert_equal([1], IterTest.new(nil).method(:f).to_proc.call([1]))
+ m = /\w+/.match("abc")
+ assert_equal([m], IterTest.new(nil).method(:f).to_proc.call([m]))
+
+ IterTest.new([0]).each0 {|x| assert_equal(0, x)}
+ IterTest.new([1]).each1 {|x| assert_equal(1, x)}
+ IterTest.new([2]).each2 {|x| assert_equal([2], x)}
+ IterTest.new([4]).each4 {|x| assert_equal(4, x)}
+ IterTest.new([5]).each5 {|x| assert_equal(5, x)}
+ IterTest.new([6]).each6 {|x| assert_equal([6], x)}
+ IterTest.new([8]).each8 {|x| assert_equal(8, x)}
+
+ IterTest.new([[0]]).each0 {|x| assert_equal([0], x)}
+ IterTest.new([[1]]).each1 {|x| assert_equal([1], x)}
+ IterTest.new([[2]]).each2 {|x| assert_equal([[2]], x)}
+ IterTest.new([[3]]).each3 {|x| assert_equal(3, x)}
+ IterTest.new([[4]]).each4 {|x| assert_equal([4], x)}
+ IterTest.new([[5]]).each5 {|x| assert_equal([5], x)}
+ IterTest.new([[6]]).each6 {|x| assert_equal([[6]], x)}
+ IterTest.new([[7]]).each7 {|x| assert_equal(7, x)}
+ IterTest.new([[8]]).each8 {|x| assert_equal([8], x)}
+
+ IterTest.new([[0,0]]).each0 {|*x| assert_equal([[0,0]], x)}
+ IterTest.new([[8,8]]).each8 {|*x| assert_equal([[8,8]], x)}
+ end
+
+ def m(var)
+ var
+ end
+
+ def m1
+ m(block_given?)
+ end
+
+ def m2
+ m(block_given?,&proc{})
+ end
+
+ def test_block_given
+ assert(m1{p 'test'})
+ assert(m2{p 'test'})
+ assert(!m1())
+ assert(!m2())
+ end
+
+ def m3(var, &block)
+ m(yield(var), &block)
+ end
+
+ def m4(&block)
+ m(m1(), &block)
+ end
+
+ def test_block_passing
+ assert(!m4())
+ assert(!m4 {})
+ assert_equal(100, m3(10) {|x|x*x})
+ end
+
+ class C
+ include Enumerable
+ def initialize
+ @a = [1,2,3]
+ end
+ def each(&block)
+ @a.each(&block)
+ end
+ end
+
+ def test_collect
+ assert_equal([1,2,3], C.new.collect{|n| n})
+ end
+
+ def test_proc
+ assert_instance_of(Proc, lambda{})
+ assert_instance_of(Proc, Proc.new{})
+ lambda{|a|assert_equal(a, 1)}.call(1)
+ end
+
+ def test_block
+ assert_instance_of(NilClass, get_block)
+ assert_instance_of(Proc, get_block{})
+ end
+
+ def test_argument
+ assert_nothing_raised {lambda{||}.call}
+ assert_raises(ArgumentError) {lambda{||}.call(1)}
+ assert_nothing_raised {lambda{|a,|}.call(1)}
+ assert_raises(ArgumentError) {lambda{|a,|}.call()}
+ assert_raises(ArgumentError) {lambda{|a,|}.call(1,2)}
+ end
+
+ def get_block(&block)
+ block
+ end
+
+ def test_get_block
+ assert_instance_of(Proc, get_block{})
+ assert_nothing_raised {get_block{||}.call()}
+ assert_nothing_raised {get_block{||}.call(1)}
+ assert_nothing_raised {get_block{|a,|}.call(1)}
+ assert_nothing_raised {get_block{|a,|}.call()}
+ assert_nothing_raised {get_block{|a,|}.call(1,2)}
+
+ assert_nothing_raised {get_block(&lambda{||}).call()}
+ assert_raises(ArgumentError) {get_block(&lambda{||}).call(1)}
+ assert_nothing_raised {get_block(&lambda{|a,|}).call(1)}
+ assert_raises(ArgumentError) {get_block(&lambda{|a,|}).call(1,2)}
+
+ block = get_block{11}
+ assert_instance_of(Proc, block)
+ assert_instance_of(Proc, block.to_proc)
+ assert_equal(block.clone.call, 11)
+ assert_instance_of(Proc, get_block(&block))
+
+ lmd = lambda{44}
+ assert_instance_of(Proc, lmd)
+ assert_instance_of(Proc, lmd.to_proc)
+ assert_equal(lmd.clone.call, 44)
+ assert_instance_of(Proc, get_block(&lmd))
+
+ assert_equal(1, Proc.new{|a,| a}.call(1,2,3))
+ assert_nothing_raised {Proc.new{|a,|}.call(1,2)}
+ end
+
+ def return1_test
+ Proc.new {
+ return 55
+ }.call + 5
+ end
+
+ def test_return1
+ assert_equal(55, return1_test())
+ end
+
+ def return2_test
+ lambda {
+ return 55
+ }.call + 5
+ end
+
+ def test_return2
+ assert_equal(60, return2_test())
+ end
+
+ def proc_call(&b)
+ b.call
+ end
+ def proc_yield()
+ yield
+ end
+ def proc_return1
+ proc_call{return 42}+1
+ end
+
+ def test_proc_return1
+ assert_equal(42, proc_return1())
+ end
+
+ def proc_return2
+ proc_yield{return 42}+1
+ end
+
+ def test_proc_return2
+ assert_equal(42, proc_return2())
+ end
+
+ def test_ljump
+ assert_raises(LocalJumpError) {get_block{break}.call}
+
+ # cannot use assert_nothing_raised due to passing block.
+ begin
+ val = lambda{break 11}.call
+ rescue LocalJumpError
+ assert(false, "LocalJumpError occurred from break in lambda")
+ else
+ assert(11, val)
+ end
+
+ block = get_block{11}
+ lmd = lambda{44}
+ assert_equal(0, block.arity)
+ assert_equal(0, lmd.arity)
+ assert_equal(0, lambda{||}.arity)
+ assert_equal(1, lambda{|a|}.arity)
+ assert_equal(1, lambda{|a,|}.arity)
+ assert_equal(2, lambda{|a,b|}.arity)
+ end
+
+ def marity_test(m)
+ mobj = method(m)
+ assert_equal(mobj.arity, mobj.to_proc.arity)
+ end
+
+ def test_marity
+ marity_test(:assert)
+ marity_test(:marity_test)
+ marity_test(:p)
+
+ lambda(&method(:assert)).call(true)
+ lambda(&get_block{|a,n| assert(a,n)}).call(true, "marity")
+ end
+
+ def foo
+ yield(:key, :value)
+ end
+ def bar(&blk)
+ blk.call(:key, :value)
+ end
+
+ def test_yield_vs_call
+ foo{|k,v| assert_equal([:key, :value], [k,v])}
+ bar{|k,v| assert_equal([:key, :value], [k,v])}
+ end
+
+ class H
+ def each
+ yield [:key, :value]
+ end
+ alias each_pair each
+ end
+
+ def test_assoc_yield
+ [{:key=>:value}, H.new].each {|h|
+ h.each{|a| assert_equal([:key, :value], a)}
+ h.each{|a,| assert_equal(:key, a)}
+ h.each{|*a| assert_equal([[:key, :value]], a)}
+ h.each{|k,v| assert_equal([:key, :value], [k,v])}
+ h.each_pair{|a| assert_equal([:key, :value], a)}
+ h.each_pair{|a,| assert_equal(:key, a)}
+ h.each_pair{|*a| assert_equal([[:key, :value]], a)}
+ h.each_pair{|k,v| assert_equal([:key, :value], [k,v])}
+ }
+ end
+
+ class ITER_TEST1
+ def a
+ block_given?
+ end
+ end
+
+ class ITER_TEST2 < ITER_TEST1
+ include Test::Unit::Assertions
+ def a
+ assert(super)
+ super
+ end
+ end
+
+ def test_iter_test2
+ assert(ITER_TEST2.new.a {})
+ end
+
+ class ITER_TEST3
+ def foo x
+ return yield if block_given?
+ x
+ end
+ end
+
+ class ITER_TEST4 < ITER_TEST3
+ include Test::Unit::Assertions
+ def foo x
+ assert_equal(super, yield)
+ assert_equal(x, super(x, &nil))
+ end
+ end
+
+ def test_iter4
+ ITER_TEST4.new.foo(44){55}
+ end
+
+ def test_break__nested_loop1
+ _test_break__nested_loop1 do
+ break
+ end
+ end
+
+ def _test_break__nested_loop1
+ while true
+ yield
+ end
+ assert(false, "must not reach here")
+ end
+
+ def test_break__nested_loop2
+ _test_break__nested_loop2 do
+ break
+ end
+ end
+
+ def _test_break__nested_loop2
+ until false
+ yield
+ end
+ assert(false, "must not reach here")
+ end
+
+ def test_break__nested_loop3
+ _test_break__nested_loop3 do
+ break
+ end
+ end
+
+ def _test_break__nested_loop3
+ loop do
+ yield
+ end
+ assert(false, "must not reach here")
+ end
+
+ def test_break_from_enum
+ result = ["a"].inject("ng") {|x,y| break "ok"}
+ assert_equal("ok", result)
+ end
+
+ def _test_return_trace_func(x)
+ set_trace_func(proc {})
+ [].fetch(2) {return x}
+ ensure
+ set_trace_func(nil)
+ end
+
+ def test_return_trace_func
+ ok = "returned gracefully"
+ result = "skipped"
+ result = _test_return_trace_func(ok)
+ ensure
+ assert_equal(ok, result)
+ return
+ end
+
+ class IterString < ::String
+ def ===(other)
+ super if !block_given?
+ end
+ end
+
+ # Check that the block passed to an iterator
+ # does not get propagated inappropriately
+ def test_block_given_within_iterator
+ assert_equal(["b"], ["a", "b", "c"].grep(IterString.new("b")) {|s| s})
+ end
+
+ def test_enumerator
+ [1,2,3].each.with_index {|x,i|
+ assert_equal(x, i+1)
+ }
+
+ e = [1,2,3].each
+ assert_equal(1, e.next)
+ assert_equal(2, e.next)
+ assert_equal(3, e.next)
+ assert_raises(StopIteration){e.next}
+ e.rewind
+ assert_equal(1, e.next)
+ e.rewind
+ a = []
+ loop{a.push e.next}
+ assert_equal([1,2,3], a)
+
+ assert_equal([[8, 1, 10], [6, 2, 11], [4, 3, 12]],
+ [8,6,4].zip((1..10),(10..100)).to_a)
+ end
+end
diff --git a/trunk/test/ruby/test_lambda.rb b/trunk/test/ruby/test_lambda.rb
new file mode 100644
index 0000000000..bb0861ab53
--- /dev/null
+++ b/trunk/test/ruby/test_lambda.rb
@@ -0,0 +1,68 @@
+require 'test/unit'
+
+class TestLambdaParameters < Test::Unit::TestCase
+
+ def test_exact_parameter
+ assert_raise(ArgumentError){(1..3).each(&lambda{})}
+ end
+
+ def test_call_simple
+ assert_equal(1, lambda{|a| a}.call(1))
+ assert_equal([1,2], lambda{|a, b| [a,b]}.call(1,2))
+ assert_raises(ArgumentError) { lambda{|a|}.call(1,2) }
+ assert_raises(ArgumentError) { lambda{|a|}.call() }
+ assert_raises(ArgumentError) { lambda{}.call(1) }
+ assert_raises(ArgumentError) { lambda{|a, b|}.call(1,2,3) }
+
+ assert_equal(1, ->(a){ a }.call(1))
+ assert_equal([1,2], ->(a,b){ [a,b] }.call(1,2))
+ assert_raises(ArgumentError) { ->(a){ }.call(1,2) }
+ assert_raises(ArgumentError) { ->(a){ }.call() }
+ assert_raises(ArgumentError) { ->(){ }.call(1) }
+ assert_raises(ArgumentError) { ->(a,b){ }.call(1,2,3) }
+ end
+
+end
+
+__END__
+ def test_lambda_as_iterator
+ a = 0
+ 2.times(&->(_){ a += 1 })
+ assert_equal(a, 2)
+ end
+
+ def test_call_rest_args
+ assert_equal([1,2], ->(*a){ a }.call(1,2))
+ assert_equal([1,2,[]], ->(a,b,*c){ [a,b,c] }.call(1,2))
+ assert_raises(ArgumentError){ ->(a,*b){ }.call() }
+ end
+
+ def test_call_opt_args
+ assert_equal([1,2,3,4], ->(a,b,c=3,d=4){ [a,b,c,d] }.call(1,2))
+ assert_equal([1,2,3,4], ->(a,b,c=0,d=4){ [a,b,c,d] }.call(1,2,3))
+ assert_raises(ArgumentError){ ->(a,b=1){ }.call() }
+ assert_raises(ArgumentError){ ->(a,b=1){ }.call(1,2,3) }
+ end
+
+ def test_call_rest_and_opt
+ assert_equal([1,2,3,[]], ->(a,b=2,c=3,*d){ [a,b,c,d] }.call(1))
+ assert_equal([1,2,3,[]], ->(a,b=0,c=3,*d){ [a,b,c,d] }.call(1,2))
+ assert_equal([1,2,3,[4,5,6]], ->(a,b=0,c=0,*d){ [a,b,c,d] }.call(1,2,3,4,5,6))
+ assert_raises(ArgumentError){ ->(a,b=1,*c){ }.call() }
+ end
+
+ def test_call_with_block
+ f = ->(a,b,c=3,*d,&e){ [a,b,c,d,e.call(d + [a,b,c])] }
+ assert_equal([1,2,3,[],6], f.call(1,2){|z| z.inject{|s,x| s+x} } )
+ assert_equal(nil, ->(&b){ b }.call)
+ foo { puts "bogus block " }
+ assert_equal(1, ->(&b){ b.call }.call { 1 })
+ b = nil
+ assert_equal(1, ->(&b){ b.call }.call { 1 })
+ assert_nil(b)
+ end
+
+ def foo
+ assert_equal(nil, ->(&b){ b }.call)
+ end
+end
diff --git a/trunk/test/ruby/test_literal.rb b/trunk/test/ruby/test_literal.rb
new file mode 100644
index 0000000000..e87769a6c8
--- /dev/null
+++ b/trunk/test/ruby/test_literal.rb
@@ -0,0 +1,241 @@
+require 'test/unit'
+
+class TestRubyLiteral < Test::Unit::TestCase
+
+ def test_special_const
+ assert_equal 'true', true.inspect
+ assert_instance_of TrueClass, true
+ assert_equal 'false', false.inspect
+ assert_instance_of FalseClass, false
+ assert_equal 'nil', nil.inspect
+ assert_instance_of NilClass, nil
+ assert_equal ':sym', :sym.inspect
+ assert_instance_of Symbol, :sym
+ assert_equal '1234', 1234.inspect
+ assert_instance_of Fixnum, 1234
+ assert_equal '1234', 1_2_3_4.inspect
+ assert_instance_of Fixnum, 1_2_3_4
+ assert_equal '18', 0x12.inspect
+ assert_instance_of Fixnum, 0x12
+ assert_raise(SyntaxError) { eval("0x") }
+ assert_equal '15', 0o17.inspect
+ assert_instance_of Fixnum, 0o17
+ assert_raise(SyntaxError) { eval("0o") }
+ assert_equal '5', 0b101.inspect
+ assert_instance_of Fixnum, 0b101
+ assert_raise(SyntaxError) { eval("0b") }
+ assert_equal '123456789012345678901234567890', 123456789012345678901234567890.inspect
+ assert_instance_of Bignum, 123456789012345678901234567890
+ assert_instance_of Float, 1.3
+ end
+
+ def test_self
+ assert_equal self, self
+ assert_instance_of TestRubyLiteral, self
+ assert_respond_to self, :test_self
+ end
+
+ def test_string
+ assert_instance_of String, ?a
+ assert_equal "a", ?a
+ assert_instance_of String, ?A
+ assert_equal "A", ?A
+ assert_instance_of String, ?\n
+ assert_equal "\n", ?\n
+ assert_equal " ", ?\ # space
+ assert_equal '', ''
+ assert_equal 'string', 'string'
+ assert_equal 'string string', 'string string'
+ assert_equal ' ', ' '
+ assert_equal ' ', " "
+ assert_equal "\0", "\0"
+ assert_equal "\1", "\1"
+ assert_equal "3", "\x33"
+ assert_equal "\n", "\n"
+ end
+
+ def test_dstring
+ assert_equal '2', "#{1+1}"
+ assert_equal '16', "#{2 ** 4}"
+ s = "string"
+ assert_equal s, "#{s}"
+ end
+
+ def test_dsymbol
+ assert_equal :a3c, :"a#{1+2}c"
+ end
+
+ def test_xstring
+ assert_equal "foo\n", `echo foo`
+ s = 'foo'
+ assert_equal "foo\n", `echo #{s}`
+ end
+
+ def test_regexp
+ assert_instance_of Regexp, //
+ assert_match //, 'a'
+ assert_match //, ''
+ assert_instance_of Regexp, /a/
+ assert_match /a/, 'a'
+ assert_no_match /test/, 'tes'
+ re = /test/
+ assert_match re, 'test'
+ str = 'test'
+ assert_match re, str
+ assert_match /test/, str
+ assert_equal 0, (/test/ =~ 'test')
+ assert_equal 0, (re =~ 'test')
+ assert_equal 0, (/test/ =~ str)
+ assert_equal 0, (re =~ str)
+ assert_equal 0, ('test' =~ /test/)
+ assert_equal 0, ('test' =~ re)
+ assert_equal 0, (str =~ /test/)
+ assert_equal 0, (str =~ re)
+ end
+
+ def test_dregexp
+ assert_instance_of Regexp, /re#{'ge'}xp/
+ assert_equal(/regexp/, /re#{'ge'}xp/)
+ end
+
+ def test_array
+ assert_instance_of Array, []
+ assert_equal [], []
+ assert_equal 0, [].size
+ assert_instance_of Array, [0]
+ assert_equal [3], [3]
+ assert_equal 1, [3].size
+ a = [3]
+ assert_equal 3, a[0]
+ assert_instance_of Array, [1,2]
+ assert_equal [1,2], [1,2]
+ assert_instance_of Array, [1,2,3,4,5]
+ assert_equal [1,2,3,4,5], [1,2,3,4,5]
+ assert_equal 5, [1,2,3,4,5].size
+ a = [1,2]
+ assert_equal 1, a[0]
+ assert_equal 2, a[1]
+ a = [1 + 2, 3 + 4, 5 + 6]
+ assert_instance_of Array, a
+ assert_equal [3, 7, 11], a
+ assert_equal 7, a[1]
+ assert_equal 1, ([0][0] += 1)
+ assert_equal 1, ([2][0] -= 1)
+ a = [obj = Object.new]
+ assert_instance_of Array, a
+ assert_equal 1, a.size
+ assert_equal obj, a[0]
+ a = [1,2,3]
+ a[1] = 5
+ assert_equal 5, a[1]
+ end
+
+ def test_hash
+ assert_instance_of Hash, {}
+ assert_equal({}, {})
+ assert_instance_of Hash, {1 => 2}
+ assert_equal({1 => 2}, {1 => 2})
+ h = {1 => 2}
+ assert_equal 2, h[1]
+ h = {"string" => "literal", "goto" => "hell"}
+ assert_equal h, h
+ assert_equal 2, h.size
+ assert_equal h, h
+ assert_equal "literal", h["string"]
+ end
+
+ def test_range
+ assert_instance_of Range, (1..2)
+ assert_equal(1..2, 1..2)
+ r = 1..2
+ assert_equal 1, r.begin
+ assert_equal 2, r.end
+ assert_equal false, r.exclude_end?
+ assert_instance_of Range, (1...3)
+ assert_equal(1...3, 1...3)
+ r = 1...3
+ assert_equal 1, r.begin
+ assert_equal 3, r.end
+ assert_equal true, r.exclude_end?
+ r = 1+2 .. 3+4
+ assert_instance_of Range, r
+ assert_equal 3, r.begin
+ assert_equal 7, r.end
+ assert_equal false, r.exclude_end?
+ r = 1+2 ... 3+4
+ assert_instance_of Range, r
+ assert_equal 3, r.begin
+ assert_equal 7, r.end
+ assert_equal true, r.exclude_end?
+ assert_instance_of Range, 'a'..'c'
+ r = 'a'..'c'
+ assert_equal 'a', r.begin
+ assert_equal 'c', r.end
+ end
+
+ def test__FILE__
+ assert_instance_of String, __FILE__
+ assert_equal __FILE__, __FILE__
+ assert_equal 'test_literal.rb', File.basename(__FILE__)
+ end
+
+ def test__LINE__
+ assert_instance_of Fixnum, __LINE__
+ assert_equal __LINE__, __LINE__
+ end
+
+ def test_integer
+ head = ['', '0x', '0o', '0b', '0d', '-', '+']
+ chars = ['0', '1', '_', '9', 'f']
+ head.each {|h|
+ 4.times {|len|
+ a = [h]
+ len.times { a = a.product(chars).map {|x| x.join('') } }
+ a.each {|s|
+ next if s.empty?
+ begin
+ r1 = Integer(s)
+ rescue ArgumentError
+ r1 = :err
+ end
+ begin
+ r2 = eval(s)
+ rescue NameError, SyntaxError
+ r2 = :err
+ end
+ assert_equal(r1, r2, "Integer(#{s.inspect}) != eval(#{s.inspect})")
+ }
+ }
+ }
+ end
+
+ def test_float
+ head = ['', '-', '+']
+ chars = ['0', '1', '_', '9', 'f', '.']
+ head.each {|h|
+ 6.times {|len|
+ a = [h]
+ len.times { a = a.product(chars).map {|x| x.join('') } }
+ a.each {|s|
+ next if s.empty?
+ next if /\.\z/ =~ s
+ next if /\A[-+]?\./ =~ s
+ next if /\A[-+]?0/ =~ s
+ begin
+ r1 = Float(s)
+ rescue ArgumentError
+ r1 = :err
+ end
+ begin
+ r2 = eval(s)
+ rescue NameError, SyntaxError
+ r2 = :err
+ end
+ r2 = :err if Range === r2
+ assert_equal(r1, r2, "Float(#{s.inspect}) != eval(#{s.inspect})")
+ }
+ }
+ }
+ end
+
+end
diff --git a/trunk/test/ruby/test_m17n.rb b/trunk/test/ruby/test_m17n.rb
new file mode 100644
index 0000000000..e82e04beb7
--- /dev/null
+++ b/trunk/test/ruby/test_m17n.rb
@@ -0,0 +1,1290 @@
+require 'test/unit'
+require 'stringio'
+
+class TestM17N < Test::Unit::TestCase
+ def assert_encoding(encname, actual, message=nil)
+ assert_equal(Encoding.find(encname), actual, message)
+ end
+
+ module AESU
+ def a(str) str.dup.force_encoding("ASCII-8BIT") end
+ def e(str) str.dup.force_encoding("EUC-JP") end
+ def s(str) str.dup.force_encoding("Windows-31J") end
+ def u(str) str.dup.force_encoding("UTF-8") end
+ end
+ include AESU
+ extend AESU
+
+ def assert_strenc(bytes, enc, actual, message=nil)
+ assert_instance_of(String, actual, message)
+ enc = Encoding.find(enc) if String === enc
+ assert_equal(enc, actual.encoding, message)
+ assert_equal(a(bytes), a(actual), message)
+ end
+
+ def assert_warning(pat, mesg=nil)
+ begin
+ org_stderr = $stderr
+ $stderr = StringIO.new(warn = '')
+ yield
+ ensure
+ $stderr = org_stderr
+ end
+ assert_match(pat, warn, mesg)
+ end
+
+ def assert_regexp_generic_encoding(r)
+ assert(!r.fixed_encoding?)
+ %w[ASCII-8BIT EUC-JP Windows-31J UTF-8].each {|ename|
+ # "\xc2\xa1" is a valid sequence for ASCII-8BIT, EUC-JP, Windows-31J and UTF-8.
+ assert_nothing_raised { r =~ "\xc2\xa1".force_encoding(ename) }
+ }
+ end
+
+ def assert_regexp_fixed_encoding(r)
+ assert(r.fixed_encoding?)
+ %w[ASCII-8BIT EUC-JP Windows-31J UTF-8].each {|ename|
+ enc = Encoding.find(ename)
+ if enc == r.encoding
+ assert_nothing_raised { r =~ "\xc2\xa1".force_encoding(enc) }
+ else
+ assert_raise(ArgumentError) { r =~ "\xc2\xa1".force_encoding(enc) }
+ end
+ }
+ end
+
+ def assert_regexp_generic_ascii(r)
+ assert_encoding("US-ASCII", r.encoding)
+ assert_regexp_generic_encoding(r)
+ end
+
+ def assert_regexp_fixed_ascii8bit(r)
+ assert_encoding("ASCII-8BIT", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_eucjp(r)
+ assert_encoding("EUC-JP", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_sjis(r)
+ assert_encoding("Windows-31J", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_utf8(r)
+ assert_encoding("UTF-8", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_usascii_literal(r, enc, ex = nil)
+ code = "# -*- encoding: US-ASCII -*-\n#{r}.encoding"
+ if ex
+ assert_raise(ex) { eval(code) }
+ else
+ assert_equal(enc, eval(code))
+ end
+ end
+
+ def encdump(str)
+ d = str.dump
+ if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
+ d
+ else
+ "#{d}.force_encoding(#{str.encoding.name.dump})"
+ end
+ end
+
+ def encdumpargs(args)
+ r = '('
+ args.each_with_index {|a, i|
+ r << ',' if 0 < i
+ if String === a
+ r << encdump(a)
+ else
+ r << a.inspect
+ end
+ }
+ r << ')'
+ r
+ end
+
+ def assert_str_enc_propagation(t, s1, s2)
+ if !s1.ascii_only?
+ assert_equal(s1.encoding, t.encoding)
+ elsif !s2.ascii_only?
+ assert_equal(s2.encoding, t.encoding)
+ else
+ assert([s1.encoding, s2.encoding].include?(t.encoding))
+ end
+ end
+
+ def assert_same_result(expected_proc, actual_proc)
+ e = nil
+ begin
+ t = expected_proc.call
+ rescue
+ e = $!
+ end
+ if e
+ assert_raise(e.class) { actual_proc.call }
+ else
+ assert_equal(t, actual_proc.call)
+ end
+ end
+
+ def str_enc_compatible?(*strs)
+ encs = []
+ strs.each {|s|
+ encs << s.encoding if !s.ascii_only?
+ }
+ encs.uniq!
+ encs.length <= 1
+ end
+
+ # tests start
+
+ def test_string_ascii_literal
+ assert_encoding("US-ASCII", eval(a(%{""})).encoding)
+ assert_encoding("US-ASCII", eval(a(%{"a"})).encoding)
+ end
+
+ def test_string_eucjp_literal
+ assert_encoding("US-ASCII", eval(e(%{""})).encoding)
+ assert_encoding("US-ASCII", eval(e(%{"a"})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"\xa1\xa1"})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"\\xa1\\xa1"})).encoding)
+ assert_encoding("US-ASCII", eval(e(%{"\\x20"})).encoding)
+ assert_encoding("US-ASCII", eval(e(%{"\\n"})).encoding)
+ assert_encoding("EUC-JP", eval(e(%{"\\x80"})).encoding)
+ end
+
+ def test_utf8_literal
+ assert_equal(Encoding::UTF_8, "\u3042".encoding, "[ruby-dev:33406] \"\\u3042\".encoding")
+ assert_raise(SyntaxError) { eval(a('\u3052\x80')) }
+ end
+
+ def test_string_mixed_unicode
+ assert_raise(SyntaxError) { eval(a(%{"\xc2\xa1\\u{6666}"})) }
+ assert_raise(SyntaxError) { eval(e(%{"\xc2\xa1\\u{6666}"})) }
+ assert_raise(SyntaxError) { eval(s(%{"\xc2\xa1\\u{6666}"})) }
+ assert_nothing_raised { eval(u(%{"\xc2\xa1\\u{6666}"})) }
+ assert_raise(SyntaxError) { eval(a(%{"\\u{6666}\xc2\xa1"})) }
+ assert_raise(SyntaxError) { eval(e(%{"\\u{6666}\xc2\xa1"})) }
+ assert_raise(SyntaxError) { eval(s(%{"\\u{6666}\xc2\xa1"})) }
+ assert_nothing_raised { eval(u(%{"\\u{6666}\xc2\xa1"})) }
+ end
+
+ def test_string_inspect
+ assert_equal('"\xFE"', e("\xfe").inspect)
+ assert_equal('"\x8E"', e("\x8e").inspect)
+ assert_equal('"\x8F"', e("\x8f").inspect)
+ assert_equal('"\x8F\xA1"', e("\x8f\xa1").inspect)
+ assert_equal('"\xEF"', s("\xef").inspect)
+ assert_equal('"\xC2"', u("\xc2").inspect)
+ assert_equal('"\xE0\x80"', u("\xe0\x80").inspect)
+ assert_equal('"\xF0\x80\x80"', u("\xf0\x80\x80").inspect)
+ assert_equal('"\xF8\x80\x80\x80"', u("\xf8\x80\x80\x80").inspect)
+ assert_equal('"\xFC\x80\x80\x80\x80"', u("\xfc\x80\x80\x80\x80").inspect)
+
+ assert_equal('"\xFE "', e("\xfe ").inspect)
+ assert_equal('"\x8E "', e("\x8e ").inspect)
+ assert_equal('"\x8F "', e("\x8f ").inspect)
+ assert_equal('"\x8F\xA1 "', e("\x8f\xa1 ").inspect)
+ assert_equal('"\xEF "', s("\xef ").inspect)
+ assert_equal('"\xC2 "', u("\xc2 ").inspect)
+ assert_equal('"\xE0\x80 "', u("\xe0\x80 ").inspect)
+ assert_equal('"\xF0\x80\x80 "', u("\xf0\x80\x80 ").inspect)
+ assert_equal('"\xF8\x80\x80\x80 "', u("\xf8\x80\x80\x80 ").inspect)
+ assert_equal('"\xFC\x80\x80\x80\x80 "', u("\xfc\x80\x80\x80\x80 ").inspect)
+
+
+ assert_equal(e("\"\\xA1\x8f\xA1\xA1\""), e("\xa1\x8f\xa1\xa1").inspect)
+
+ assert_equal('"\x81."', s("\x81.").inspect)
+ assert_equal(s("\"\x81@\""), s("\x81@").inspect)
+
+ assert_equal('"\xFC"', u("\xfc").inspect)
+ end
+
+ def test_str_dump
+ [
+ e("\xfe"),
+ e("\x8e"),
+ e("\x8f"),
+ e("\x8f\xa1"),
+ s("\xef"),
+ u("\xc2"),
+ u("\xe0\x80"),
+ u("\xf0\x80\x80"),
+ u("\xf8\x80\x80\x80"),
+ u("\xfc\x80\x80\x80\x80"),
+
+ e("\xfe "),
+ e("\x8e "),
+ e("\x8f "),
+ e("\x8f\xa1 "),
+ s("\xef "),
+ u("\xc2 "),
+ u("\xe0\x80 "),
+ u("\xf0\x80\x80 "),
+ u("\xf8\x80\x80\x80 "),
+ u("\xfc\x80\x80\x80\x80 "),
+
+
+ e("\xa1\x8f\xa1\xa1"),
+
+ s("\x81."),
+ s("\x81@"),
+
+ u("\xfc"),
+ "\u3042",
+ "ascii",
+ ].each do |str|
+ assert_equal(str, eval(str.dump), "[ruby-dev:33142]")
+ end
+ end
+
+ def test_validate_redundant_utf8
+ bits_0x10ffff = "11110100 10001111 10111111 10111111"
+ [
+ "0xxxxxxx",
+ "110XXXXx 10xxxxxx",
+ "1110XXXX 10Xxxxxx 10xxxxxx",
+ "11110XXX 10XXxxxx 10xxxxxx 10xxxxxx",
+ "111110XX 10XXXxxx 10xxxxxx 10xxxxxx 10xxxxxx",
+ "1111110X 10XXXXxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx",
+ "11111110 10XXXXXx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx",
+ "11111111 10XXXXXX 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx",
+ ].each {|pat0|
+ [
+ pat0.gsub(/x/, '1'),
+ pat0.gsub(/x/, '0')
+ ].each {|pat1|
+ [
+ pat1.sub(/X([^X]*)\z/, '1\1').gsub(/X/, "0"),
+ pat1.gsub(/X/, "1"),
+ ].each {|pat2|
+ s = [pat2.gsub(/ /, "")].pack("B*").force_encoding("utf-8")
+ if pat2 <= bits_0x10ffff
+ assert(s.valid_encoding?, "#{pat2}")
+ else
+ assert(!s.valid_encoding?, "#{pat2}")
+ end
+ }
+ if / / =~ pat0
+ pat3 = pat1.gsub(/X/, "0")
+ s = [pat3.gsub(/ /, "")].pack("B*").force_encoding("utf-8")
+ assert(!s.valid_encoding?, "#{pat3}")
+ end
+ }
+ }
+ end
+
+ def test_validate_surrogate
+ # 1110XXXX 10Xxxxxx 10xxxxxx : 3 bytes UTF-8
+ pats = [
+ "11101101 10011111 10111111", # just before surrogate high
+ "11101101 1010xxxx 10xxxxxx", # surrogate high
+ "11101101 1011xxxx 10xxxxxx", # surrogate low
+ "11101110 10000000 10000000", # just after surrogate low
+ ]
+ pats.values_at(1,2).each {|pat0|
+ [
+ pat0.gsub(/x/, '0'),
+ pat0.gsub(/x/, '1'),
+ ].each {|pat1|
+ s = [pat1.gsub(/ /, "")].pack("B*").force_encoding("utf-8")
+ assert(!s.valid_encoding?, "#{pat1}")
+ }
+ }
+ pats.values_at(0,3).each {|pat|
+ s = [pat.gsub(/ /, "")].pack("B*").force_encoding("utf-8")
+ assert(s.valid_encoding?, "#{pat}")
+ }
+ end
+
+ def test_regexp_too_short_multibyte_character
+ assert_raise(SyntaxError) { eval('/\xfe/e') }
+ assert_raise(SyntaxError) { eval('/\x8e/e') }
+ assert_raise(SyntaxError) { eval('/\x8f/e') }
+ assert_raise(SyntaxError) { eval('/\x8f\xa1/e') }
+ assert_raise(SyntaxError) { eval('/\xef/s') }
+ assert_raise(SyntaxError) { eval('/\xc2/u') }
+ assert_raise(SyntaxError) { eval('/\xe0\x80/u') }
+ assert_raise(SyntaxError) { eval('/\xf0\x80\x80/u') }
+ assert_raise(SyntaxError) { eval('/\xf8\x80\x80\x80/u') }
+ assert_raise(SyntaxError) { eval('/\xfc\x80\x80\x80\x80/u') }
+
+ # raw 8bit
+ assert_raise(SyntaxError) { eval("/\xfe/e") }
+ assert_raise(SyntaxError) { eval("/\xc2/u") }
+
+ # invalid suffix
+ assert_raise(SyntaxError) { eval('/\xc2\xff/u') }
+ assert_raise(SyntaxError) { eval('/\xc2 /u') }
+ assert_raise(SyntaxError) { eval('/\xc2\x20/u') }
+ end
+
+ def test_regexp_generic
+ assert_regexp_generic_ascii(/a/)
+ assert_regexp_generic_ascii(Regexp.new(a("a")))
+ assert_regexp_generic_ascii(Regexp.new(e("a")))
+ assert_regexp_generic_ascii(Regexp.new(s("a")))
+ assert_regexp_generic_ascii(Regexp.new(u("a")))
+
+ [/a/, Regexp.new(a("a"))].each {|r|
+ assert_equal(0, r =~ a("a"))
+ assert_equal(0, r =~ e("a"))
+ assert_equal(0, r =~ s("a"))
+ assert_equal(0, r =~ u("a"))
+ assert_equal(nil, r =~ a("\xc2\xa1"))
+ assert_equal(nil, r =~ e("\xc2\xa1"))
+ assert_equal(nil, r =~ s("\xc2\xa1"))
+ assert_equal(nil, r =~ u("\xc2\xa1"))
+ }
+ end
+
+ def test_regexp_ascii_none
+ r = /a/n
+
+ assert_warning(%r{regexp match /.../n against to}) {
+ assert_regexp_generic_ascii(r)
+ }
+
+ assert_equal(0, r =~ a("a"))
+ assert_equal(0, r =~ e("a"))
+ assert_equal(0, r =~ s("a"))
+ assert_equal(0, r =~ u("a"))
+ assert_equal(nil, r =~ a("\xc2\xa1"))
+ assert_warning(%r{regexp match /.../n against to EUC-JP string}) {
+ assert_equal(nil, r =~ e("\xc2\xa1"))
+ }
+ assert_warning(%r{regexp match /.../n against to Windows-31J string}) {
+ assert_equal(nil, r =~ s("\xc2\xa1"))
+ }
+ assert_warning(%r{regexp match /.../n against to UTF-8 string}) {
+ assert_equal(nil, r =~ u("\xc2\xa1"))
+ }
+
+ assert_nothing_raised { eval(e("/\\x80/n")) }
+ end
+
+ def test_regexp_ascii
+ assert_regexp_fixed_ascii8bit(/\xc2\xa1/n)
+ assert_regexp_fixed_ascii8bit(eval(a(%{/\xc2\xa1/})))
+ assert_regexp_fixed_ascii8bit(eval(a(%{/\xc2\xa1/n})))
+ assert_regexp_fixed_ascii8bit(eval(a(%q{/\xc2\xa1/})))
+
+ assert_raise(SyntaxError) { eval("/\xa1\xa1/n".force_encoding("euc-jp")) }
+
+ [/\xc2\xa1/n, eval(a(%{/\xc2\xa1/})), eval(a(%{/\xc2\xa1/n}))].each {|r|
+ assert_equal(nil, r =~ a("a"))
+ assert_equal(nil, r =~ e("a"))
+ assert_equal(nil, r =~ s("a"))
+ assert_equal(nil, r =~ u("a"))
+ assert_equal(0, r =~ a("\xc2\xa1"))
+ assert_raise(ArgumentError) { r =~ e("\xc2\xa1") }
+ assert_raise(ArgumentError) { r =~ s("\xc2\xa1") }
+ assert_raise(ArgumentError) { r =~ u("\xc2\xa1") }
+ }
+ end
+
+ def test_regexp_euc
+ assert_regexp_fixed_eucjp(/a/e)
+ assert_regexp_fixed_eucjp(/\xc2\xa1/e)
+ assert_regexp_fixed_eucjp(eval(e(%{/\xc2\xa1/})))
+ assert_regexp_fixed_eucjp(eval(e(%q{/\xc2\xa1/})))
+
+ [/a/e].each {|r|
+ assert_equal(0, r =~ a("a"))
+ assert_equal(0, r =~ e("a"))
+ assert_equal(0, r =~ s("a"))
+ assert_equal(0, r =~ u("a"))
+ assert_raise(ArgumentError) { r =~ a("\xc2\xa1") }
+ assert_equal(nil, r =~ e("\xc2\xa1"))
+ assert_raise(ArgumentError) { r =~ s("\xc2\xa1") }
+ assert_raise(ArgumentError) { r =~ u("\xc2\xa1") }
+ }
+
+ [/\xc2\xa1/e, eval(e(%{/\xc2\xa1/})), eval(e(%q{/\xc2\xa1/}))].each {|r|
+ assert_equal(nil, r =~ a("a"))
+ assert_equal(nil, r =~ e("a"))
+ assert_equal(nil, r =~ s("a"))
+ assert_equal(nil, r =~ u("a"))
+ assert_raise(ArgumentError) { r =~ a("\xc2\xa1") }
+ assert_equal(0, r =~ e("\xc2\xa1"))
+ assert_raise(ArgumentError) { r =~ s("\xc2\xa1") }
+ assert_raise(ArgumentError) { r =~ u("\xc2\xa1") }
+ }
+ end
+
+ def test_regexp_sjis
+ assert_regexp_fixed_sjis(/a/s)
+ assert_regexp_fixed_sjis(/\xc2\xa1/s)
+ assert_regexp_fixed_sjis(eval(s(%{/\xc2\xa1/})))
+ assert_regexp_fixed_sjis(eval(s(%q{/\xc2\xa1/})))
+ end
+
+ def test_regexp_windows_31j
+ begin
+ Regexp.new("\xa1".force_encoding("windows-31j")) =~ "\xa1\xa1".force_encoding("euc-jp")
+ rescue ArgumentError
+ err = $!
+ end
+ assert_match(/windows-31j/i, err.message)
+ end
+
+ def test_regexp_embed
+ r = eval(e("/\xc2\xa1/"))
+ assert_raise(ArgumentError) { eval(s("/\xc2\xa1\#{r}/s")) }
+ assert_raise(ArgumentError) { eval(s("/\#{r}\xc2\xa1/s")) }
+
+ r = /\xc2\xa1/e
+ assert_raise(ArgumentError) { eval(s("/\xc2\xa1\#{r}/s")) }
+ assert_raise(ArgumentError) { eval(s("/\#{r}\xc2\xa1/s")) }
+
+ r = eval(e("/\xc2\xa1/"))
+ assert_raise(ArgumentError) { /\xc2\xa1#{r}/s }
+
+ r = /\xc2\xa1/e
+ assert_raise(ArgumentError) { /\xc2\xa1#{r}/s }
+
+ r1 = Regexp.new('foo'.force_encoding("ascii-8bit"))
+ r2 = eval('/bar#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::US_ASCII, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("us-ascii"))
+ r2 = eval('/bar#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::US_ASCII, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("ascii-8bit"))
+ r2 = eval('/bar#{r1}/'.force_encoding('us-ascii'))
+ assert_equal(Encoding::US_ASCII, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("us-ascii"))
+ r2 = eval('/bar#{r1}/'.force_encoding('us-ascii'))
+ assert_equal(Encoding::US_ASCII, r2.encoding)
+
+ r1 = Regexp.new('\xa1'.force_encoding("ascii-8bit"))
+ r2 = eval('/bar#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+
+ r1 = Regexp.new('\xa1'.force_encoding("ascii-8bit"))
+ r2 = eval('/bar#{r1}/'.force_encoding('us-ascii'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("ascii-8bit"))
+ r2 = eval('/\xa1#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+
+ r1 = Regexp.new('foo'.force_encoding("us-ascii"))
+ r2 = eval('/\xa1#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+
+ r1 = Regexp.new('\xa1'.force_encoding("ascii-8bit"))
+ r2 = eval('/\xa1#{r1}/'.force_encoding('ascii-8bit'))
+ assert_equal(Encoding::ASCII_8BIT, r2.encoding)
+ end
+
+ def test_regexp_named_class
+ assert_match(/[[:space:]]/u, "\u{00a0}")
+ assert_match(/[[:space:]]/, "\u{00a0}")
+ end
+
+ def test_regexp_property
+ s = '\p{Hiragana}'.force_encoding("euc-jp")
+ assert_equal(Encoding::EUC_JP, s.encoding)
+ r = nil
+ assert_nothing_raised {
+ r = Regexp.new(s)
+ }
+ assert(r.fixed_encoding?)
+ assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+ r = eval('/\p{Hiragana}/'.force_encoding("euc-jp"))
+ assert(r.fixed_encoding?)
+ assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+ r = /\p{Hiragana}/e
+ assert(r.fixed_encoding?)
+ assert_match(r, "\xa4\xa2".force_encoding("euc-jp"))
+
+ r = eval('/\u{3042}\p{Hiragana}/'.force_encoding("euc-jp"))
+ assert(r.fixed_encoding?)
+ assert_equal(Encoding::UTF_8, r.encoding)
+
+ r = eval('/\p{Hiragana}\u{3042}/'.force_encoding("euc-jp"))
+ assert(r.fixed_encoding?)
+ assert_equal(Encoding::UTF_8, r.encoding)
+ end
+
+ def test_regexp_embed_preprocess
+ r1 = /\xa4\xa2/e
+ r2 = /#{r1}/
+ assert(r2.source.include?(r1.source))
+ end
+
+ def test_begin_end_offset
+ str = e("\244\242\244\244\244\246\244\250\244\252a")
+ assert(/(a)/ =~ str)
+ assert_equal("a", $&)
+ assert_equal(5, $~.begin(0))
+ assert_equal(6, $~.end(0))
+ assert_equal([5,6], $~.offset(0))
+ assert_equal(5, $~.begin(1))
+ assert_equal(6, $~.end(1))
+ assert_equal([5,6], $~.offset(1))
+ end
+
+ def test_begin_end_offset_sjis
+ str = s("\x81@@")
+ assert(/@/ =~ str)
+ assert_equal(s("\x81@"), $`)
+ assert_equal("@", $&)
+ assert_equal("", $')
+ assert_equal([1,2], $~.offset(0))
+ end
+
+ def test_quote
+ assert_regexp_generic_ascii(/#{Regexp.quote(a("a"))}#{Regexp.quote(e("e"))}/)
+
+ assert_encoding("US-ASCII", Regexp.quote(a("")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(e("")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(s("")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(u("")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(a("a")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(e("a")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(s("a")).encoding)
+ assert_encoding("US-ASCII", Regexp.quote(u("a")).encoding)
+
+ assert_encoding("ASCII-8BIT", Regexp.quote(a("\xc2\xa1")).encoding)
+ assert_encoding("EUC-JP", Regexp.quote(e("\xc2\xa1")).encoding)
+ assert_encoding("Windows-31J", Regexp.quote(s("\xc2\xa1")).encoding)
+ assert_encoding("UTF-8", Regexp.quote(u("\xc2\xa1")).encoding)
+ end
+
+ def test_union_0
+ r = Regexp.union
+ assert_regexp_generic_ascii(r)
+ assert(r !~ a(""))
+ assert(r !~ e(""))
+ assert(r !~ s(""))
+ assert(r !~ u(""))
+ end
+
+ def test_union_1_asciionly_string
+ assert_regexp_generic_ascii(Regexp.union(a("")))
+ assert_regexp_generic_ascii(Regexp.union(e("")))
+ assert_regexp_generic_ascii(Regexp.union(s("")))
+ assert_regexp_generic_ascii(Regexp.union(u("")))
+ assert_regexp_generic_ascii(Regexp.union(a("a")))
+ assert_regexp_generic_ascii(Regexp.union(e("a")))
+ assert_regexp_generic_ascii(Regexp.union(s("a")))
+ assert_regexp_generic_ascii(Regexp.union(u("a")))
+ assert_regexp_generic_ascii(Regexp.union(a("\t")))
+ assert_regexp_generic_ascii(Regexp.union(e("\t")))
+ assert_regexp_generic_ascii(Regexp.union(s("\t")))
+ assert_regexp_generic_ascii(Regexp.union(u("\t")))
+ end
+
+ def test_union_1_nonascii_string
+ assert_regexp_fixed_ascii8bit(Regexp.union(a("\xc2\xa1")))
+ assert_regexp_fixed_eucjp(Regexp.union(e("\xc2\xa1")))
+ assert_regexp_fixed_sjis(Regexp.union(s("\xc2\xa1")))
+ assert_regexp_fixed_utf8(Regexp.union(u("\xc2\xa1")))
+ end
+
+ def test_union_1_regexp
+ assert_regexp_generic_ascii(Regexp.union(//))
+ assert_warning(%r{regexp match /.../n against to}) {
+ assert_regexp_generic_ascii(Regexp.union(//n))
+ }
+ assert_regexp_fixed_eucjp(Regexp.union(//e))
+ assert_regexp_fixed_sjis(Regexp.union(//s))
+ assert_regexp_fixed_utf8(Regexp.union(//u))
+ end
+
+ def test_union_2
+ ary = [
+ a(""), e(""), s(""), u(""),
+ a("\xc2\xa1"), e("\xc2\xa1"), s("\xc2\xa1"), u("\xc2\xa1")
+ ]
+ ary.each {|s1|
+ ary.each {|s2|
+ if s1.empty?
+ if s2.empty?
+ assert_regexp_generic_ascii(Regexp.union(s1, s2))
+ else
+ r = Regexp.union(s1, s2)
+ assert_regexp_fixed_encoding(r)
+ assert_equal(s2.encoding, r.encoding)
+ end
+ else
+ if s2.empty?
+ r = Regexp.union(s1, s2)
+ assert_regexp_fixed_encoding(r)
+ assert_equal(s1.encoding, r.encoding)
+ else
+ if s1.encoding == s2.encoding
+ r = Regexp.union(s1, s2)
+ assert_regexp_fixed_encoding(r)
+ assert_equal(s1.encoding, r.encoding)
+ else
+ assert_raise(ArgumentError) { Regexp.union(s1, s2) }
+ end
+ end
+ end
+ }
+ }
+ end
+
+ def test_dynamic_ascii_regexp
+ assert_warning(%r{regexp match /.../n against to}) {
+ assert_regexp_generic_ascii(/#{}/n)
+ }
+ assert_regexp_fixed_ascii8bit(/#{}\xc2\xa1/n)
+ assert_regexp_fixed_ascii8bit(/\xc2\xa1#{}/n)
+ assert_nothing_raised { s1, s2 = a('\xc2'), a('\xa1'); /#{s1}#{s2}/ }
+ end
+
+ def test_dynamic_eucjp_regexp
+ assert_regexp_fixed_eucjp(/#{}/e)
+ assert_regexp_fixed_eucjp(/#{}\xc2\xa1/e)
+ assert_regexp_fixed_eucjp(/\xc2\xa1#{}/e)
+ assert_raise(SyntaxError) { eval('/\xc2#{}/e') }
+ assert_raise(SyntaxError) { eval('/#{}\xc2/e') }
+ assert_raise(SyntaxError) { eval('/\xc2#{}\xa1/e') }
+ assert_raise(ArgumentError) { s1, s2 = e('\xc2'), e('\xa1'); /#{s1}#{s2}/ }
+ end
+
+ def test_dynamic_sjis_regexp
+ assert_regexp_fixed_sjis(/#{}/s)
+ assert_regexp_fixed_sjis(/#{}\xc2\xa1/s)
+ assert_regexp_fixed_sjis(/\xc2\xa1#{}/s)
+ assert_raise(SyntaxError) { eval('/\x81#{}/s') }
+ assert_raise(SyntaxError) { eval('/#{}\x81/s') }
+ assert_raise(SyntaxError) { eval('/\x81#{}\xa1/s') }
+ assert_raise(ArgumentError) { s1, s2 = s('\x81'), s('\xa1'); /#{s1}#{s2}/ }
+ end
+
+ def test_dynamic_utf8_regexp
+ assert_regexp_fixed_utf8(/#{}/u)
+ assert_regexp_fixed_utf8(/#{}\xc2\xa1/u)
+ assert_regexp_fixed_utf8(/\xc2\xa1#{}/u)
+ assert_raise(SyntaxError) { eval('/\xc2#{}/u') }
+ assert_raise(SyntaxError) { eval('/#{}\xc2/u') }
+ assert_raise(SyntaxError) { eval('/\xc2#{}\xa1/u') }
+ assert_raise(ArgumentError) { s1, s2 = u('\xc2'), u('\xa1'); /#{s1}#{s2}/ }
+ end
+
+ def test_regexp_unicode
+ assert_nothing_raised { eval '/\u{0}/u' }
+ assert_nothing_raised { eval '/\u{D7FF}/u' }
+ assert_raise(SyntaxError) { eval '/\u{D800}/u' }
+ assert_raise(SyntaxError) { eval '/\u{DFFF}/u' }
+ assert_nothing_raised { eval '/\u{E000}/u' }
+ assert_nothing_raised { eval '/\u{10FFFF}/u' }
+ assert_raise(SyntaxError) { eval '/\u{110000}/u' }
+ end
+
+ def test_regexp_mixed_unicode
+ assert_raise(SyntaxError) { eval(a(%{/\xc2\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\xc2\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\xc2\xa1\\u{6666}/})) }
+ assert_nothing_raised { eval(u(%{/\xc2\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(a(%{/\\u{6666}\xc2\xa1/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\u{6666}\xc2\xa1/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\u{6666}\xc2\xa1/})) }
+ assert_nothing_raised { eval(u(%{/\\u{6666}\xc2\xa1/})) }
+
+ assert_raise(SyntaxError) { eval(a(%{/\\xc2\\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\xc2\\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\xc2\\xa1\\u{6666}/})) }
+ assert_nothing_raised { eval(u(%{/\\xc2\\xa1\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(a(%{/\\u{6666}\\xc2\\xa1/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\u{6666}\\xc2\\xa1/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\u{6666}\\xc2\\xa1/})) }
+ assert_nothing_raised { eval(u(%{/\\u{6666}\\xc2\\xa1/})) }
+
+ assert_raise(SyntaxError) { eval(a(%{/\xc2\xa1#{}\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\xc2\xa1#{}\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\xc2\xa1#{}\\u{6666}/})) }
+ assert_nothing_raised { eval(u(%{/\xc2\xa1#{}\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(a(%{/\\u{6666}#{}\xc2\xa1/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\u{6666}#{}\xc2\xa1/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\u{6666}#{}\xc2\xa1/})) }
+ assert_nothing_raised { eval(u(%{/\\u{6666}#{}\xc2\xa1/})) }
+
+ assert_raise(SyntaxError) { eval(a(%{/\\xc2\\xa1#{}\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\xc2\\xa1#{}\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\xc2\\xa1#{}\\u{6666}/})) }
+ assert_nothing_raised { eval(u(%{/\\xc2\\xa1#{}\\u{6666}/})) }
+ assert_raise(SyntaxError) { eval(a(%{/\\u{6666}#{}\\xc2\\xa1/})) }
+ assert_raise(SyntaxError) { eval(e(%{/\\u{6666}#{}\\xc2\\xa1/})) }
+ assert_raise(SyntaxError) { eval(s(%{/\\u{6666}#{}\\xc2\\xa1/})) }
+ assert_nothing_raised { eval(u(%{/\\u{6666}#{}\\xc2\\xa1/})) }
+ end
+
+ def test_str_allocate
+ s = String.allocate
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ end
+
+ def test_str_String
+ s = String(10)
+ assert_equal(Encoding::US_ASCII, s.encoding)
+ end
+
+ def test_sprintf_c
+ assert_strenc("\x80", 'ASCII-8BIT', a("%c") % 128)
+ #assert_raise(ArgumentError) { a("%c") % 0xc2a1 }
+ assert_strenc("\xc2\xa1", 'EUC-JP', e("%c") % 0xc2a1)
+ assert_raise(ArgumentError) { e("%c") % 0xc2 }
+ assert_strenc("\xc2", 'Windows-31J', s("%c") % 0xc2)
+ #assert_raise(ArgumentError) { s("%c") % 0xc2a1 }
+ assert_strenc("\u{c2a1}", 'UTF-8', u("%c") % 0xc2a1)
+ assert_strenc("\u{c2}", 'UTF-8', u("%c") % 0xc2)
+ assert_raise(EncodingCompatibilityError) {
+ "%s%s" % [s("\xc2\xa1"), e("\xc2\xa1")]
+ }
+ end
+
+ def test_sprintf_p
+ assert_strenc('""', 'ASCII-8BIT', a("%p") % a(""))
+ assert_strenc('""', 'EUC-JP', e("%p") % e(""))
+ assert_strenc('""', 'Windows-31J', s("%p") % s(""))
+ assert_strenc('""', 'UTF-8', u("%p") % u(""))
+
+ assert_strenc('"a"', 'ASCII-8BIT', a("%p") % a("a"))
+ assert_strenc('"a"', 'EUC-JP', e("%p") % e("a"))
+ assert_strenc('"a"', 'Windows-31J', s("%p") % s("a"))
+ assert_strenc('"a"', 'UTF-8', u("%p") % u("a"))
+
+ assert_strenc('"\xC2\xA1"', 'ASCII-8BIT', a("%p") % a("\xc2\xa1"))
+ assert_strenc("\"\xC2\xA1\"", 'EUC-JP', e("%p") % e("\xc2\xa1"))
+ #assert_strenc("\"\xC2\xA1\"", 'Windows-31J', s("%p") % s("\xc2\xa1"))
+ assert_strenc("\"\xC2\xA1\"", 'UTF-8', u("%p") % u("\xc2\xa1"))
+
+ assert_strenc('"\xC2\xA1"', 'US-ASCII', "%10p" % a("\xc2\xa1"))
+ assert_strenc(" \"\xC2\xA1\"", 'EUC-JP', "%10p" % e("\xc2\xa1"))
+ #assert_strenc(" \"\xC2\xA1\"", 'Windows-31J', "%10p" % s("\xc2\xa1"))
+ assert_strenc(" \"\xC2\xA1\"", 'UTF-8', "%10p" % u("\xc2\xa1"))
+
+ assert_strenc('"\x00"', 'ASCII-8BIT', a("%p") % a("\x00"))
+ assert_strenc('"\x00"', 'EUC-JP', e("%p") % e("\x00"))
+ assert_strenc('"\x00"', 'Windows-31J', s("%p") % s("\x00"))
+ assert_strenc('"\x00"', 'UTF-8', u("%p") % u("\x00"))
+ end
+
+ def test_sprintf_s
+ assert_strenc('', 'ASCII-8BIT', a("%s") % a(""))
+ assert_strenc('', 'EUC-JP', e("%s") % e(""))
+ assert_strenc('', 'Windows-31J', s("%s") % s(""))
+ assert_strenc('', 'UTF-8', u("%s") % u(""))
+
+ assert_strenc('a', 'ASCII-8BIT', a("%s") % a("a"))
+ assert_strenc('a', 'EUC-JP', e("%s") % e("a"))
+ assert_strenc('a', 'Windows-31J', s("%s") % s("a"))
+ assert_strenc('a', 'UTF-8', u("%s") % u("a"))
+
+ assert_strenc("\xC2\xA1", 'ASCII-8BIT', a("%s") % a("\xc2\xa1"))
+ assert_strenc("\xC2\xA1", 'EUC-JP', e("%s") % e("\xc2\xa1"))
+ #assert_strenc("\xC2\xA1", 'Windows-31J', s("%s") % s("\xc2\xa1"))
+ assert_strenc("\xC2\xA1", 'UTF-8', u("%s") % u("\xc2\xa1"))
+
+ assert_strenc(" \xC2\xA1", 'ASCII-8BIT', "%10s" % a("\xc2\xa1"))
+ assert_strenc(" \xA1\xA1", 'EUC-JP', "%10s" % e("\xa1\xa1"))
+ #assert_strenc(" \xC2\xA1", 'Windows-31J', "%10s" % s("\xc2\xa1"))
+ assert_strenc(" \xC2\xA1", 'UTF-8', "%10s" % u("\xc2\xa1"))
+
+ assert_strenc("\x00", 'ASCII-8BIT', a("%s") % a("\x00"))
+ assert_strenc("\x00", 'EUC-JP', e("%s") % e("\x00"))
+ assert_strenc("\x00", 'Windows-31J', s("%s") % s("\x00"))
+ assert_strenc("\x00", 'UTF-8', u("%s") % u("\x00"))
+ assert_equal("EUC-JP", (e("\xc2\xa1 %s") % "foo").encoding.name)
+ end
+
+ def test_str_lt
+ assert(a("a") < a("\xa1"))
+ assert(a("a") < s("\xa1"))
+ assert(s("a") < a("\xa1"))
+ end
+
+ def test_str_multiply
+ str = "\u3042"
+ assert_equal(true, (str * 0).ascii_only?, "[ruby-dev:33895]")
+ assert_equal(false, (str * 1).ascii_only?)
+ assert_equal(false, (str * 2).ascii_only?)
+ end
+
+ def test_str_aref
+ assert_equal(a("\xc2"), a("\xc2\xa1")[0])
+ assert_equal(a("\xa1"), a("\xc2\xa1")[1])
+ assert_equal(nil, a("\xc2\xa1")[2])
+ assert_equal(e("\xc2\xa1"), e("\xc2\xa1")[0])
+ assert_equal(nil, e("\xc2\xa1")[1])
+ assert_equal(s("\xc2"), s("\xc2\xa1")[0])
+ assert_equal(s("\xa1"), s("\xc2\xa1")[1])
+ assert_equal(nil, s("\xc2\xa1")[2])
+ assert_equal(u("\xc2\xa1"), u("\xc2\xa1")[0])
+ assert_equal(nil, u("\xc2\xa1")[1])
+
+ str = "\u3042"
+ assert_equal(true, str[0, 0].ascii_only?, "[ruby-dev:33895]")
+ assert_equal(false, str[0, 1].ascii_only?)
+ assert_equal(false, str[0..-1].ascii_only?)
+ end
+
+ def test_utf8str_aref
+ s = "abcdefghijklmnopqrstuvwxyz\u{3042 3044 3046 3048 304A}"
+ assert_equal("a", s[0])
+ assert_equal("h", s[7])
+ assert_equal("i", s[8])
+ assert_equal("j", s[9])
+ assert_equal("\u{3044}", s[27])
+ assert_equal("\u{3046}", s[28])
+ assert_equal("\u{3048}", s[29])
+ s = "abcdefghijklmnopqrstuvw\u{3042 3044 3046 3048 304A}"
+ assert_equal("\u{3044}", s[24])
+ end
+
+ def test_str_aref_len
+ assert_equal(a("\xa1"), a("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 1])
+ assert_equal(a("\xa1\xc2"), a("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 2])
+
+ assert_equal(e("\xc2\xa2"), e("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 1])
+ assert_equal(e("\xc2\xa2\xc2\xa3"), e("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 2])
+
+ assert_equal(s("\xa1"), s("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 1])
+ assert_equal(s("\xa1\xc2"), s("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 2])
+
+ assert_equal(u("\xc2\xa2"), u("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 1])
+ assert_equal(u("\xc2\xa2\xc2\xa3"), u("\xc2\xa1\xc2\xa2\xc2\xa3")[1, 2])
+ end
+
+ def test_str_aref_substr
+ assert_equal(a("\xa1\xc2"), a("\xc2\xa1\xc2\xa2\xc2\xa3")[a("\xa1\xc2")])
+ assert_raise(EncodingCompatibilityError) { a("\xc2\xa1\xc2\xa2\xc2\xa3")[e("\xa1\xc2")] }
+
+ assert_equal(nil, e("\xc2\xa1\xc2\xa2\xc2\xa3")[e("\xa1\xc2")])
+ assert_raise(EncodingCompatibilityError) { e("\xc2\xa1\xc2\xa2\xc2\xa3")[s("\xa1\xc2")] }
+
+ assert_equal(s("\xa1\xc2"), s("\xc2\xa1\xc2\xa2\xc2\xa3")[s("\xa1\xc2")])
+ assert_raise(EncodingCompatibilityError) { s("\xc2\xa1\xc2\xa2\xc2\xa3")[u("\xa1\xc2")] }
+
+ assert_equal(nil, u("\xc2\xa1\xc2\xa2\xc2\xa3")[u("\xa1\xc2")])
+ assert_raise(EncodingCompatibilityError) { u("\xc2\xa1\xc2\xa2\xc2\xa3")[a("\xa1\xc2")] }
+ assert_nil(e("\xa1\xa2\xa3\xa4")[e("\xa2\xa3")])
+ end
+
+ def test_aset
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(EncodingCompatibilityError){s["\xb0\xa3"] = "foo"}
+ end
+
+ def test_str_center
+ assert_encoding("EUC-JP", "a".center(5, e("\xa1\xa2")).encoding)
+ assert_encoding("EUC-JP", e("\xa3\xb0").center(10).encoding)
+ end
+
+ def test_squeeze
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb1\xa3\xb3\xa3\xb4")
+ assert_equal(e("\xa3\xb0\xa3\xb1\xa3\xb3\xa3\xb4"), s.squeeze)
+ end
+
+ def test_tr
+ s = s("\x81\x41")
+ assert_equal(s.tr("A", "B"), s)
+ assert_equal(s.tr_s("A", "B"), s)
+
+ assert_nothing_raised {
+ "a".force_encoding("ASCII-8BIT").tr(a("a"), a("a"))
+ }
+
+ assert_equal(e("\xA1\xA1"), a("a").tr(a("a"), e("\xA1\xA1")))
+
+ assert_equal("X\u3042\u3044X", "A\u3042\u3044\u3046".tr("^\u3042\u3044", "X"))
+ assert_equal("\u3042\u3046" * 100, ("\u3042\u3044" * 100).tr("\u3044", "\u3046"))
+ end
+
+ def test_tr_s
+ assert_equal("\xA1\xA1".force_encoding("EUC-JP"),
+ "a".force_encoding("ASCII-8BIT").tr("a".force_encoding("ASCII-8BIT"), "\xA1\xA1".force_encoding("EUC-JP")))
+ end
+
+ def test_count
+ assert_equal(0, e("\xa1\xa2").count("z"))
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(EncodingCompatibilityError){s.count(a("\xa3\xb0"))}
+ end
+
+ def test_delete
+ assert_equal(1, e("\xa1\xa2").delete("z").length)
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(EncodingCompatibilityError){s.delete(a("\xa3\xb2"))}
+
+ a = "\u3042\u3044\u3046\u3042\u3044\u3046"
+ a.delete!("\u3042\u3044", "^\u3044")
+ assert_equal("\u3044\u3046\u3044\u3046", a)
+ end
+
+ def test_include?
+ assert_equal(false, e("\xa1\xa2\xa3\xa4").include?(e("\xa3")))
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_equal(false, s.include?(e("\xb0\xa3")))
+ end
+
+ def test_index
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_nil(s.index(e("\xb3\xa3")))
+ assert_nil(e("\xa1\xa2\xa3\xa4").index(e("\xa3")))
+ assert_nil(e("\xa1\xa2\xa3\xa4").rindex(e("\xa3")))
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(EncodingCompatibilityError){s.rindex(a("\xb1\xa3"))}
+ end
+
+ def test_next
+ s1 = e("\xa1\xa1")
+ s2 = s1.dup
+ (94*94+94).times { s2.next! }
+ assert_not_equal(s1, s2)
+ end
+
+ def test_sub
+ s = "abc".sub(/b/, "\xa1\xa1".force_encoding("euc-jp"))
+ assert_encoding("EUC-JP", s.encoding)
+ assert_equal(Encoding::EUC_JP, "\xa4\xa2".force_encoding("euc-jp").sub(/./, '\&').encoding)
+ assert_equal(Encoding::EUC_JP, "\xa4\xa2".force_encoding("euc-jp").gsub(/./, '\&').encoding)
+ end
+
+ def test_insert
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_equal(e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4a"), s.insert(-1, "a"))
+ end
+
+ def test_scan
+ assert_equal(["a"], e("\xa1\xa2a\xa3\xa4").scan(/a/))
+ end
+
+ def test_dup_scan
+ s1 = e("\xa4\xa2")*100
+ s2 = s1.dup.force_encoding("ascii-8bit")
+ s2.scan(/\A./n) {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.encoding)
+ }
+ end
+
+ def test_dup_aref
+ s1 = e("\xa4\xa2")*100
+ s2 = s1.dup.force_encoding("ascii-8bit")
+ assert_equal(Encoding::ASCII_8BIT, s2[10..-1].encoding)
+ end
+
+ def test_upto
+ s1 = e("\xa1\xa2")
+ s2 = s("\xa1\xa2")
+ assert_raise(EncodingCompatibilityError){s1.upto(s2) {|x| break }}
+ end
+
+ def test_casecmp
+ s1 = s("\x81\x41")
+ s2 = s("\x81\x61")
+ assert_not_equal(0, s1.casecmp(s2))
+ end
+
+ def test_reverse
+ assert_equal(u("\xf0jihgfedcba"), u("abcdefghij\xf0").reverse)
+ end
+
+ def test_reverse_bang
+ s = u("abcdefghij\xf0")
+ s.reverse!
+ assert_equal(u("\xf0jihgfedcba"), s)
+ end
+
+ def test_plus
+ assert_raise(EncodingCompatibilityError){u("\xe3\x81\x82") + a("\xa1")}
+ end
+
+ def test_chomp
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(EncodingCompatibilityError){s.chomp(s("\xa3\xb4"))}
+ end
+
+ def test_gsub
+ s = 'abc'
+ s.ascii_only?
+ s.gsub!(/b/, "\x80")
+ assert_equal(false, s.ascii_only?, "[ruby-core:14566] reported by Sam Ruby")
+
+ s = "abc".force_encoding(Encoding::ASCII_8BIT)
+ t = s.gsub(/b/, "\xa1\xa1".force_encoding("euc-jp"))
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+
+ assert_raise(EncodingCompatibilityError) {
+ "abc".gsub(/[ac]/) {
+ $& == "a" ? "\xc2\xa1".force_encoding("euc-jp") :
+ "\xc2\xa1".force_encoding("utf-8")
+ }
+ }
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_equal(e("\xa3\xb0z\xa3\xb2\xa3\xb3\xa3\xb4"), s.gsub(/\xa3\xb1/e, "z"))
+
+ assert_equal(Encoding::EUC_JP, (a("").gsub(//) { e("") }.encoding))
+ assert_equal(Encoding::EUC_JP, (a("a").gsub(/a/) { e("") }.encoding))
+ end
+
+ def test_end_with
+ s1 = s("\x81\x40")
+ s2 = "@"
+ assert_equal(false, s1.end_with?(s2), "#{encdump s1}.end_with?(#{encdump s2})")
+ end
+
+ def test_each_line
+ s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
+ assert_raise(EncodingCompatibilityError){s.each_line(a("\xa3\xb1")) {|l| }}
+ s = e("\xa4\xa2\nfoo")
+
+ actual = []
+ s.each_line {|line| actual << line }
+ expected = [e("\xa4\xa2\n"), e("foo")]
+ assert_equal(expected, actual)
+ end
+
+ def test_each_char
+ a = [e("\xa4\xa2"), "b", e("\xa4\xa4"), "c"]
+ s = "\xa4\xa2b\xa4\xa4c".force_encoding("euc-jp")
+ assert_equal(a, s.each_char.to_a, "[ruby-dev:33211] #{encdump s}.each_char.to_a")
+ end
+
+ def test_regexp_match
+ assert_equal([0,0], //.match("\xa1\xa1".force_encoding("euc-jp"),-1).offset(0))
+ assert_equal(0, // =~ :a)
+ end
+
+ def test_split
+ assert_equal(e("\xa1\xa2\xa1\xa3").split(//),
+ [e("\xa1\xa2"), e("\xa1\xa3")],
+ '[ruby-dev:32452]')
+ end
+
+ def test_nonascii_method_name
+ eval(e("def \xc2\xa1() @nonascii_method_name = :e end"))
+ eval(u("def \xc2\xa1() @nonascii_method_name = :u end"))
+ eval(e("\xc2\xa1()"))
+ assert_equal(:e, @nonascii_method_name)
+ eval(u("\xc2\xa1()"))
+ assert_equal(:u, @nonascii_method_name)
+ me = method(e("\xc2\xa1"))
+ mu = method(u("\xc2\xa1"))
+ assert_not_equal(me.name, mu.name)
+ assert_not_equal(me.inspect, mu.inspect)
+ assert_equal(e("\xc2\xa1"), me.name.to_s)
+ assert_equal(u("\xc2\xa1"), mu.name.to_s)
+ end
+
+ def test_symbol
+ s1 = "\xc2\xa1".force_encoding("euc-jp").intern
+ s2 = "\xc2\xa1".force_encoding("utf-8").intern
+ assert_not_equal(s1, s2)
+ end
+
+ def test_symbol_op
+ ops = %w[
+ .. ... + - +(binary) -(binary) * / % ** +@ -@ | ^ & ! <=> > >= < <= ==
+ === != =~ !~ ~ ! [] []= << >> :: `
+ ] #`
+ ops.each do |op|
+ assert_equal(Encoding::US_ASCII, op.intern.encoding, "[ruby-dev:33449]")
+ end
+ end
+
+ def test_chr
+ 0.upto(255) {|b|
+ assert_equal([b].pack("C"), b.chr)
+ }
+ end
+
+ def test_marshal
+ s1 = "\xa1\xa1".force_encoding("euc-jp")
+ s2 = Marshal.load(Marshal.dump(s1))
+ assert_equal(s1, s2)
+ end
+
+ def test_env
+ ENV.each {|k, v|
+ assert_equal(Encoding::ASCII_8BIT, k.encoding)
+ assert_equal(Encoding::ASCII_8BIT, v.encoding)
+ }
+ end
+
+ def test_empty_string
+ assert_equal(Encoding::US_ASCII, "".encoding)
+ end
+
+ def test_nil_to_s
+ assert_equal(Encoding::US_ASCII, nil.to_s.encoding)
+ end
+
+ def test_nil_inspect
+ assert_equal(Encoding::US_ASCII, nil.inspect.encoding)
+ end
+
+ def test_true_to_s
+ assert_equal(Encoding::US_ASCII, true.to_s.encoding)
+ end
+
+ def test_false_to_s
+ assert_equal(Encoding::US_ASCII, false.to_s.encoding)
+ end
+
+ def test_fixnum_to_s
+ assert_equal(Encoding::US_ASCII, 1.to_s.encoding)
+ end
+
+ def test_float_to_s
+ assert_equal(Encoding::US_ASCII, 1.0.to_s.encoding)
+ end
+
+ def test_bignum_to_s
+ assert_equal(Encoding::US_ASCII, (1<<129).to_s.encoding)
+ end
+
+ def test_array_to_s
+ assert_equal(Encoding::US_ASCII, [].to_s.encoding)
+ assert_equal(Encoding::US_ASCII, [nil].to_s.encoding)
+ assert_equal(Encoding::US_ASCII, [1].to_s.encoding)
+ assert_equal(Encoding::US_ASCII, [""].to_s.encoding)
+ assert_equal(Encoding::US_ASCII, ["a"].to_s.encoding)
+ assert_equal(Encoding::US_ASCII, [nil,1,"","a","\x20",[]].to_s.encoding)
+ end
+
+ def test_hash_to_s
+ assert_equal(Encoding::US_ASCII, {}.to_s.encoding)
+ assert_equal(Encoding::US_ASCII, {1=>nil,"foo"=>""}.to_s.encoding)
+ end
+
+ def test_encoding_find
+ assert_raise(TypeError) {Encoding.find(nil)}
+ assert_raise(TypeError) {Encoding.find(0)}
+ assert_raise(TypeError) {Encoding.find([])}
+ assert_raise(TypeError) {Encoding.find({})}
+ end
+
+ def test_encoding_to_s
+ assert_equal(Encoding::US_ASCII, Encoding::US_ASCII.to_s.encoding)
+ assert_equal(Encoding::US_ASCII, Encoding::US_ASCII.inspect.encoding)
+ end
+
+ def test_regexp_source
+ s = "\xa4\xa2".force_encoding("euc-jp")
+ r = Regexp.new(s)
+ t = r.source
+ assert_equal(s, t, "[ruby-dev:33377] Regexp.new(#{encdump s}).source")
+ end
+
+ def test_magic_comment
+ assert_equal(Encoding::US_ASCII, eval("__ENCODING__".force_encoding("US-ASCII")))
+ assert_equal(Encoding::ASCII_8BIT, eval("__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::US_ASCII, eval("# -*- encoding: US-ASCII -*-\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::ASCII_8BIT, eval("# -*- encoding: ASCII-8BIT -*-\n__ENCODING__".force_encoding("US-ASCII")))
+ end
+
+ def test_magic_comment_vim
+ assert_equal(Encoding::US_ASCII, eval("# vim: filetype=ruby, fileencoding: US-ASCII, ts=3, sw=3\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::ASCII_8BIT, eval("# vim: filetype=ruby, fileencoding: ASCII-8BIT, ts=3, sw=3\n__ENCODING__".force_encoding("US-ASCII")))
+ end
+
+ def test_magic_comment_at_various_positions
+ # after shebang
+ assert_equal(Encoding::US_ASCII, eval("#!/usr/bin/ruby\n# -*- encoding: US-ASCII -*-\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::ASCII_8BIT, eval("#!/usr/bin/ruby\n# -*- encoding: ASCII-8BIT -*-\n__ENCODING__".force_encoding("US-ASCII")))
+ # wrong position
+ assert_equal(Encoding::ASCII_8BIT, eval("\n# -*- encoding: US-ASCII -*-\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::US_ASCII, eval("\n# -*- encoding: ASCII-8BIT -*-\n__ENCODING__".force_encoding("US-ASCII")))
+
+ # leading expressions
+ assert_equal(Encoding::ASCII_8BIT, eval("1+1 # -*- encoding: US-ASCII -*-\n__ENCODING__".force_encoding("ASCII-8BIT")))
+ assert_equal(Encoding::US_ASCII, eval("1+1 # -*- encoding: ASCII-8BIT -*-\n__ENCODING__".force_encoding("US-ASCII")))
+ end
+
+ def test_regexp_usascii
+ assert_regexp_usascii_literal('//', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/#{}/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/#{"a"}/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/#{%q"\x80"}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/#{"\x80"}/', nil, SyntaxError)
+
+ assert_regexp_usascii_literal('/a/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/a#{}/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/a#{"a"}/', Encoding::US_ASCII)
+ assert_regexp_usascii_literal('/a#{%q"\x80"}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/a#{"\x80"}/', nil, SyntaxError)
+
+ assert_regexp_usascii_literal('/\x80/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/\x80#{}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/\x80#{"a"}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/\x80#{%q"\x80"}/', Encoding::ASCII_8BIT)
+ assert_regexp_usascii_literal('/\x80#{"\x80"}/', nil, SyntaxError)
+
+ assert_regexp_usascii_literal('/\u1234/', Encoding::UTF_8)
+ assert_regexp_usascii_literal('/\u1234#{}/', Encoding::UTF_8)
+ assert_regexp_usascii_literal('/\u1234#{"a"}/', Encoding::UTF_8)
+ assert_regexp_usascii_literal('/\u1234#{%q"\x80"}/', nil, SyntaxError)
+ assert_regexp_usascii_literal('/\u1234#{"\x80"}/', nil, SyntaxError)
+ assert_regexp_usascii_literal('/\u1234\x80/', nil, SyntaxError)
+ assert_regexp_usascii_literal('/\u1234#{}\x80/', nil, ArgumentError)
+ end
+
+ def test_gbk
+ assert_equal("", "\x81\x40".force_encoding("GBK").chop)
+ end
+
+ def test_euc_tw
+ assert_equal("a", "a\x8e\xa2\xa1\xa1".force_encoding("euc-tw").chop)
+ end
+
+ def test_valid_encoding
+ s = "\xa1".force_encoding("euc-jp")
+ assert_equal(false, s.valid_encoding?)
+ assert_equal(true, (s+s).valid_encoding?, "[ruby-dev:33826]")
+ assert_equal(true, (s*2).valid_encoding?, "[ruby-dev:33826]")
+ assert_equal(true, ("%s%s" % [s, s]).valid_encoding?)
+ assert_equal(true, (s.dup << s).valid_encoding?)
+ assert_equal(true, "".center(2, s).valid_encoding?)
+
+ s = "\xa1\xa1\x8f".force_encoding("euc-jp")
+ assert_equal(false, s.valid_encoding?)
+ assert_equal(true, s.reverse.valid_encoding?)
+ end
+
+ def test_getbyte
+ assert_equal(0x82, u("\xE3\x81\x82\xE3\x81\x84").getbyte(2))
+ assert_equal(0x82, u("\xE3\x81\x82\xE3\x81\x84").getbyte(-4))
+ assert_nil(u("\xE3\x81\x82\xE3\x81\x84").getbyte(100))
+ end
+
+ def test_setbyte
+ s = u("\xE3\x81\x82\xE3\x81\x84")
+ s.setbyte(2, 0x84)
+ assert_equal(u("\xE3\x81\x84\xE3\x81\x84"), s)
+
+ s = u("\xE3\x81\x82\xE3\x81\x84")
+ assert_raise(IndexError) { s.setbyte(100, 0) }
+
+ s = u("\xE3\x81\x82\xE3\x81\x84")
+ s.setbyte(-4, 0x84)
+ assert_equal(u("\xE3\x81\x84\xE3\x81\x84"), s)
+ end
+
+ def test_compatible
+ assert_equal(nil, Encoding.compatible?("",0), "moved from btest/knownbug")
+ end
+
+ def test_force_encoding
+ assert(("".center(1, "\x80".force_encoding("utf-8")); true),
+ "moved from btest/knownbug, [ruby-dev:33807]")
+ end
+end
diff --git a/trunk/test/ruby/test_m17n_comb.rb b/trunk/test/ruby/test_m17n_comb.rb
new file mode 100644
index 0000000000..37b1a687a2
--- /dev/null
+++ b/trunk/test/ruby/test_m17n_comb.rb
@@ -0,0 +1,1623 @@
+require 'test/unit'
+require 'stringio'
+require_relative 'allpairs'
+
+class TestM17NComb < Test::Unit::TestCase
+ def assert_encoding(encname, actual, message=nil)
+ assert_equal(Encoding.find(encname), actual, message)
+ end
+
+ module AESU
+ def a(str) str.dup.force_encoding("ASCII-8BIT") end
+ def e(str) str.dup.force_encoding("EUC-JP") end
+ def s(str) str.dup.force_encoding("Shift_JIS") end
+ def u(str) str.dup.force_encoding("UTF-8") end
+ end
+ include AESU
+ extend AESU
+
+ def assert_strenc(bytes, enc, actual, message=nil)
+ assert_instance_of(String, actual, message)
+ enc = Encoding.find(enc) if String === enc
+ assert_equal(enc, actual.encoding, message)
+ assert_equal(a(bytes), a(actual), message)
+ end
+
+ def assert_warning(pat, mesg=nil)
+ begin
+ org_stderr = $stderr
+ $stderr = StringIO.new(warn = '')
+ yield
+ ensure
+ $stderr = org_stderr
+ end
+ assert_match(pat, warn, mesg)
+ end
+
+ def assert_regexp_generic_encoding(r)
+ assert(!r.fixed_encoding?)
+ %w[ASCII-8BIT EUC-JP Shift_JIS UTF-8].each {|ename|
+ # "\xc2\xa1" is a valid sequence for ASCII-8BIT, EUC-JP, Shift_JIS and UTF-8.
+ assert_nothing_raised { r =~ "\xc2\xa1".force_encoding(ename) }
+ }
+ end
+
+ def assert_regexp_fixed_encoding(r)
+ assert(r.fixed_encoding?)
+ %w[ASCII-8BIT EUC-JP Shift_JIS UTF-8].each {|ename|
+ enc = Encoding.find(ename)
+ if enc == r.encoding
+ assert_nothing_raised { r =~ "\xc2\xa1".force_encoding(enc) }
+ else
+ assert_raise(ArgumentError) { r =~ "\xc2\xa1".force_encoding(enc) }
+ end
+ }
+ end
+
+ def assert_regexp_generic_ascii(r)
+ assert_encoding("ASCII-8BIT", r.encoding)
+ assert_regexp_generic_encoding(r)
+ end
+
+ def assert_regexp_fixed_ascii8bit(r)
+ assert_encoding("ASCII-8BIT", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_eucjp(r)
+ assert_encoding("EUC-JP", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_sjis(r)
+ assert_encoding("Shift_JIS", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ def assert_regexp_fixed_utf8(r)
+ assert_encoding("UTF-8", r.encoding)
+ assert_regexp_fixed_encoding(r)
+ end
+
+ STRINGS = [
+ a(""), e(""), s(""), u(""),
+ a("a"), e("a"), s("a"), u("a"),
+ a("."), e("."), s("."), u("."),
+
+ # single character
+ a("\x80"), a("\xff"),
+ e("\xa1\xa1"), e("\xfe\xfe"),
+ e("\x8e\xa1"), e("\x8e\xfe"),
+ e("\x8f\xa1\xa1"), e("\x8f\xfe\xfe"),
+ s("\x81\x40"), s("\xfc\xfc"),
+ s("\xa1"), s("\xdf"),
+ u("\xc2\x80"), u("\xf4\x8f\xbf\xbf"),
+
+ # same byte sequence
+ a("\xc2\xa1"), e("\xc2\xa1"), s("\xc2\xa1"), u("\xc2\xa1"),
+
+ s("\x81A"), # mutibyte character which contains "A"
+ s("\x81a"), # mutibyte character which contains "a"
+
+ # invalid
+ e("\xa1"), e("\x80"),
+ s("\x81"), s("\x80"),
+ u("\xc2"), u("\x80"),
+
+ # for transitivity test
+ u("\xe0\xa0\xa1"),
+ e("\xe0\xa0\xa1"),
+ s("\xe0\xa0\xa1"),
+
+ #"aa".force_encoding("utf-16be"),
+ #"aaaa".force_encoding("utf-32be"),
+ #"aaa".force_encoding("utf-32be"),
+ ]
+
+ def combination(*args, &b)
+ AllPairs.each(*args, &b)
+ end
+
+ def encdump(str)
+ d = str.dump
+ if /\.force_encoding\("[A-Za-z0-9.:_+-]*"\)\z/ =~ d
+ d
+ else
+ "#{d}.force_encoding(#{str.encoding.name.dump})"
+ end
+ end
+
+ def encdumpargs(args)
+ r = '('
+ args.each_with_index {|a, i|
+ r << ',' if 0 < i
+ if String === a
+ r << encdump(a)
+ else
+ r << a.inspect
+ end
+ }
+ r << ')'
+ r
+ end
+
+ def enccall(recv, meth, *args, &block)
+ desc = ''
+ if String === recv
+ desc << encdump(recv)
+ else
+ desc << recv.inspect
+ end
+ desc << '.' << meth.to_s
+ if !args.empty?
+ desc << '('
+ args.each_with_index {|a, i|
+ desc << ',' if 0 < i
+ if String === a
+ desc << encdump(a)
+ else
+ desc << a.inspect
+ end
+ }
+ desc << ')'
+ end
+ if block
+ desc << ' {}'
+ end
+ result = nil
+ assert_nothing_raised(desc) {
+ result = recv.send(meth, *args, &block)
+ }
+ result
+ end
+
+ def assert_str_enc_propagation(t, s1, s2)
+ if !s1.ascii_only?
+ assert_equal(s1.encoding, t.encoding)
+ elsif !s2.ascii_only?
+ assert_equal(s2.encoding, t.encoding)
+ else
+ assert([s1.encoding, s2.encoding].include?(t.encoding))
+ end
+ end
+
+ def assert_same_result(expected_proc, actual_proc)
+ e = nil
+ begin
+ t = expected_proc.call
+ rescue
+ e = $!
+ end
+ if e
+ assert_raise(e.class) { actual_proc.call }
+ else
+ assert_equal(t, actual_proc.call)
+ end
+ end
+
+ def each_slice_call
+ combination(STRINGS, -2..2) {|s, nth|
+ yield s, nth
+ }
+ combination(STRINGS, -2..2, 0..2) {|s, nth, len|
+ yield s, nth, len
+ }
+ combination(STRINGS, STRINGS) {|s, substr|
+ yield s, substr
+ }
+ combination(STRINGS, -2..2, 0..2) {|s, first, last|
+ yield s, first..last
+ yield s, first...last
+ }
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s2.valid_encoding?
+ next
+ end
+ yield s1, Regexp.new(Regexp.escape(s2))
+ }
+ combination(STRINGS, STRINGS, 0..2) {|s1, s2, nth|
+ if !s2.valid_encoding?
+ next
+ end
+ yield s1, Regexp.new(Regexp.escape(s2)), nth
+ }
+ end
+
+ ASCII_INCOMPATIBLE_ENCODINGS = %w[
+ UTF-16BE
+ UTF-16LE
+ UTF-32BE
+ UTF-32LE
+ ]
+ def str_enc_compatible?(*strs)
+ encs = []
+ ascii_incompatible_encodings = {}
+ has_ascii_compatible = false
+ strs.each {|s|
+ encs << s.encoding if !s.ascii_only?
+ if /\A#{Regexp.union ASCII_INCOMPATIBLE_ENCODINGS}\z/o =~ s.encoding.name
+ ascii_incompatible_encodings[s.encoding] = true
+ else
+ has_ascii_compatible = true
+ end
+ }
+ if ascii_incompatible_encodings.empty?
+ encs.uniq!
+ encs.length <= 1
+ else
+ !has_ascii_compatible && ascii_incompatible_encodings.size == 1
+ end
+ end
+
+ # tests start
+
+ def test_str_new
+ STRINGS.each {|s|
+ t = String.new(s)
+ assert_strenc(a(s), s.encoding, t)
+ }
+ end
+
+ def test_str_plus
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1.encoding != s2.encoding && !s1.ascii_only? && !s2.ascii_only?
+ assert_raise(EncodingCompatibilityError) { s1 + s2 }
+ else
+ t = enccall(s1, :+, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert_equal(a(s1) + a(s2), a(t))
+ assert_str_enc_propagation(t, s1, s2)
+ end
+ }
+ end
+
+ def test_str_times
+ STRINGS.each {|s|
+ [0,1,2].each {|n|
+ t = s * n
+ assert(t.valid_encoding?) if s.valid_encoding?
+ assert_strenc(a(s) * n, s.encoding, t)
+ }
+ }
+ end
+
+ def test_sprintf_s
+ STRINGS.each {|s|
+ assert_strenc(a(s), s.encoding, "%s".force_encoding(s.encoding) % s)
+ if !s.empty? # xxx
+ t = enccall(a("%s"), :%, s)
+ assert_strenc(a(s), s.encoding, t)
+ end
+ }
+ end
+
+ def test_str_eq_reflexive
+ STRINGS.each {|s|
+ assert(s == s, "#{encdump s} == #{encdump s}")
+ }
+ end
+
+ def test_str_eq_symmetric
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1 == s2
+ assert(s2 == s1, "#{encdump s2} == #{encdump s1}")
+ else
+ assert(!(s2 == s1), "!(#{encdump s2} == #{encdump s1})")
+ end
+ }
+ end
+
+ def test_str_eq_transitive
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ if s1 == s2 && s2 == s3
+ assert(s1 == s3, "transitive: #{encdump s1} == #{encdump s2} == #{encdump s3}")
+ end
+ }
+ end
+
+ def test_str_eq
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc_eq = "#{encdump s1} == #{encdump s2}"
+ if s1.ascii_only? && s2.ascii_only? && a(s1) == a(s2)
+ assert(s1 == s2, desc_eq)
+ assert(s1.eql?(s2), desc_eq)
+ elsif s1.encoding == s2.encoding && a(s1) == a(s2)
+ assert(s1 == s2, desc_eq)
+ assert(!(s1 != s2))
+ assert_equal(0, s1 <=> s2)
+ assert(s1.eql?(s2), desc_eq)
+ else
+ assert(!(s1 == s2), "!(#{desc_eq})")
+ assert(s1 != s2)
+ assert_not_equal(0, s1 <=> s2)
+ assert(!s1.eql?(s2))
+ end
+ }
+ end
+
+ def test_str_concat
+ combination(STRINGS, STRINGS) {|s1, s2|
+ s = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ s << s2
+ assert(s.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert_equal(a(s), a(s1) + a(s2))
+ assert_str_enc_propagation(s, s1, s2)
+ else
+ assert_raise(EncodingCompatibilityError) { s << s2 }
+ end
+ }
+ end
+
+ def test_str_aref
+ STRINGS.each {|s|
+ t = ''.force_encoding(s.encoding)
+ 0.upto(s.length-1) {|i|
+ u = s[i]
+ assert(u.valid_encoding?) if s.valid_encoding?
+ t << u
+ }
+ assert_equal(t, s)
+ }
+ end
+
+ def test_str_aref_len
+ STRINGS.each {|s|
+ t = ''.force_encoding(s.encoding)
+ 0.upto(s.length-1) {|i|
+ u = s[i,1]
+ assert(u.valid_encoding?) if s.valid_encoding?
+ t << u
+ }
+ assert_equal(t, s)
+ }
+
+ STRINGS.each {|s|
+ t = ''.force_encoding(s.encoding)
+ 0.step(s.length-1, 2) {|i|
+ u = s[i,2]
+ assert(u.valid_encoding?) if s.valid_encoding?
+ t << u
+ }
+ assert_equal(t, s)
+ }
+ end
+
+ def test_str_aref_substr
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ t = enccall(s1, :[], s2)
+ if t != nil
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert_equal(s2, t)
+ assert_match(/#{Regexp.escape(a(s2))}/, a(s1))
+ if s1.valid_encoding?
+ assert_match(/#{Regexp.escape(s2)}/, s1)
+ end
+ end
+ else
+ assert_raise(EncodingCompatibilityError) { s1[s2] }
+ end
+ }
+ end
+
+ def test_str_aref_range2
+ combination(STRINGS, -2..2, -2..2) {|s, first, last|
+ desc = "#{encdump s}[#{first}..#{last}]"
+ t = s[first..last]
+ if first < 0
+ first += s.length
+ if first < 0
+ assert_nil(t, desc)
+ next
+ end
+ end
+ if s.length < first
+ assert_nil(t, desc)
+ next
+ end
+ assert(t.valid_encoding?) if s.valid_encoding?
+ if last < 0
+ last += s.length
+ end
+ t2 = ''
+ first.upto(last) {|i|
+ c = s[i]
+ t2 << c if c
+ }
+ assert_equal(t2, t, desc)
+ }
+ end
+
+ def test_str_aref_range3
+ combination(STRINGS, -2..2, -2..2) {|s, first, last|
+ desc = "#{encdump s}[#{first}..#{last}]"
+ t = s[first...last]
+ if first < 0
+ first += s.length
+ if first < 0
+ assert_nil(t, desc)
+ next
+ end
+ end
+ if s.length < first
+ assert_nil(t, desc)
+ next
+ end
+ if last < 0
+ last += s.length
+ end
+ assert(t.valid_encoding?) if s.valid_encoding?
+ t2 = ''
+ first.upto(last-1) {|i|
+ c = s[i]
+ t2 << c if c
+ }
+ assert_equal(t2, t, desc)
+ }
+ end
+
+ def test_str_assign
+ combination(STRINGS, STRINGS) {|s1, s2|
+ (-2).upto(2) {|i|
+ t = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ if i < -s1.length || s1.length < i
+ assert_raise(IndexError) { t[i] = s2 }
+ else
+ t[i] = s2
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s2)))
+ if s1.valid_encoding? && s2.valid_encoding?
+ if i == s1.length && s2.empty?
+ assert_nil(t[i])
+ elsif i < 0
+ assert_equal(s2, t[i-s2.length+1,s2.length],
+ "t = #{encdump(s1)}; t[#{i}] = #{encdump(s2)}; t[#{i-s2.length+1},#{s2.length}]")
+ else
+ assert_equal(s2, t[i,s2.length],
+ "t = #{encdump(s1)}; t[#{i}] = #{encdump(s2)}; t[#{i},#{s2.length}]")
+ end
+ end
+ end
+ else
+ assert_raise(EncodingCompatibilityError) { t[i] = s2 }
+ end
+ }
+ }
+ end
+
+ def test_str_assign_len
+ combination(STRINGS, -2..2, 0..2, STRINGS) {|s1, i, len, s2|
+ t = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ if i < -s1.length || s1.length < i
+ assert_raise(IndexError) { t[i,len] = s2 }
+ else
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ t[i,len] = s2
+ assert(a(t).index(a(s2)))
+ if s1.valid_encoding? && s2.valid_encoding?
+ if i == s1.length && s2.empty?
+ assert_nil(t[i])
+ elsif i < 0
+ if -i < len
+ len = -i
+ end
+ assert_equal(s2, t[i-s2.length+len,s2.length],
+ "t = #{encdump(s1)}; t[#{i},#{len}] = #{encdump(s2)}; t[#{i-s2.length+len},#{s2.length}]")
+ else
+ assert_equal(s2, t[i,s2.length],
+ "t = #{encdump(s1)}; t[#{i},#{len}] = #{encdump(s2)}; t[#{i},#{s2.length}]")
+ end
+ end
+ end
+ else
+ assert_raise(EncodingCompatibilityError) { t[i,len] = s2 }
+ end
+ }
+ end
+
+ def test_str_assign_substr
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ t = s1.dup
+ encs = [
+ !s1.ascii_only? ? s1.encoding : nil,
+ !s2.ascii_only? ? s2.encoding : nil,
+ !s3.ascii_only? ? s3.encoding : nil].uniq.compact
+ if 1 < encs.length
+ assert_raise(EncodingCompatibilityError, IndexError) { t[s2] = s3 }
+ else
+ if encs.empty?
+ encs = [
+ s1.encoding,
+ s2.encoding,
+ s3.encoding].uniq.reject {|e| e == Encoding.find("ASCII-8BIT") }
+ if encs.empty?
+ encs = [Encoding.find("ASCII-8BIT")]
+ end
+ end
+ if !t[s2]
+ else
+ enccall(t, :[]=, s2, s3)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding? && s3.valid_encoding?
+ end
+ end
+ }
+ end
+
+ def test_str_assign_range2
+ combination(STRINGS, -2..2, -2..2, STRINGS) {|s1, first, last, s2|
+ t = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ if first < -s1.length || s1.length < first
+ assert_raise(RangeError) { t[first..last] = s2 }
+ else
+ enccall(t, :[]=, first..last, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s2)))
+ if s1.valid_encoding? && s2.valid_encoding?
+ if first < 0
+ assert_equal(s2, t[s1.length+first, s2.length])
+ else
+ assert_equal(s2, t[first, s2.length])
+ end
+ end
+ end
+ else
+ assert_raise(EncodingCompatibilityError, RangeError,
+ "t=#{encdump(s1)};t[#{first}..#{last}]=#{encdump(s2)}") {
+ t[first..last] = s2
+ }
+ end
+ }
+ end
+
+ def test_str_assign_range3
+ combination(STRINGS, -2..2, -2..2, STRINGS) {|s1, first, last, s2|
+ t = s1.dup
+ if s1.ascii_only? || s2.ascii_only? || s1.encoding == s2.encoding
+ if first < -s1.length || s1.length < first
+ assert_raise(RangeError) { t[first...last] = s2 }
+ else
+ enccall(t, :[]=, first...last, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s2)))
+ if s1.valid_encoding? && s2.valid_encoding?
+ if first < 0
+ assert_equal(s2, t[s1.length+first, s2.length])
+ else
+ assert_equal(s2, t[first, s2.length])
+ end
+ end
+ end
+ else
+ assert_raise(EncodingCompatibilityError, RangeError,
+ "t=#{encdump(s1)};t[#{first}...#{last}]=#{encdump(s2)}") {
+ t[first...last] = s2
+ }
+ end
+ }
+ end
+
+ def test_str_cmp
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1} <=> #{encdump s2}"
+ r = s1 <=> s2
+ if s1 == s2
+ assert_equal(0, r, desc)
+ else
+ assert_not_equal(0, r, desc)
+ end
+ }
+ end
+
+ def test_str_capitalize
+ STRINGS.each {|s|
+ begin
+ t1 = s.capitalize
+ rescue ArgumentError
+ assert(!s.valid_encoding?)
+ next
+ end
+ assert(t1.valid_encoding?) if s.valid_encoding?
+ assert(t1.casecmp(s))
+ t2 = s.dup
+ t2.capitalize!
+ assert_equal(t1, t2)
+ r = s.downcase
+ r = enccall(r, :sub, /\A[a-z]/) {|ch| a(ch).upcase }
+ assert_equal(r, t1)
+ }
+ end
+
+ def test_str_casecmp
+ combination(STRINGS, STRINGS) {|s1, s2|
+ #puts "#{encdump(s1)}.casecmp(#{encdump(s2)})"
+ begin
+ r = s1.casecmp(s2)
+ rescue ArgumentError
+ assert(!s1.valid_encoding? || !s2.valid_encoding?)
+ next
+ end
+ #assert_equal(s1.upcase <=> s2.upcase, r)
+ }
+ end
+
+ def test_str_center
+ combination(STRINGS, [0,1,2,3,10]) {|s1, width|
+ t = s1.center(width)
+ assert(a(t).index(a(s1)))
+ }
+ combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
+ if s2.empty?
+ assert_raise(ArgumentError) { s1.center(width, s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.center(width, s2) }
+ next
+ end
+ t = enccall(s1, :center, width, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s1)))
+ assert_str_enc_propagation(t, s1, s2) if (t != s1)
+ }
+ end
+
+ def test_str_ljust
+ combination(STRINGS, [0,1,2,3,10]) {|s1, width|
+ t = s1.ljust(width)
+ assert(a(t).index(a(s1)))
+ }
+ combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
+ if s2.empty?
+ assert_raise(ArgumentError) { s1.ljust(width, s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.ljust(width, s2) }
+ next
+ end
+ t = enccall(s1, :ljust, width, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s1)))
+ assert_str_enc_propagation(t, s1, s2) if (t != s1)
+ }
+ end
+
+ def test_str_rjust
+ combination(STRINGS, [0,1,2,3,10]) {|s1, width|
+ t = s1.rjust(width)
+ assert(a(t).index(a(s1)))
+ }
+ combination(STRINGS, [0,1,2,3,10], STRINGS) {|s1, width, s2|
+ if s2.empty?
+ assert_raise(ArgumentError) { s1.rjust(width, s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.rjust(width, s2) }
+ next
+ end
+ t = enccall(s1, :rjust, width, s2)
+ assert(t.valid_encoding?) if s1.valid_encoding? && s2.valid_encoding?
+ assert(a(t).index(a(s1)))
+ assert_str_enc_propagation(t, s1, s2) if (t != s1)
+ }
+ end
+
+ def test_str_chomp
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.ascii_only? && !s2.ascii_only? && !Encoding.compatible?(s1,s2)
+ if s1.bytesize > s2.bytesize
+ assert_raise(EncodingCompatibilityError) { s1.chomp(s2) }
+ end
+ next
+ end
+ t = enccall(s1, :chomp, s2)
+ assert(t.valid_encoding?, "#{encdump(s1)}.chomp(#{encdump(s2)})") if s1.valid_encoding? && s2.valid_encoding?
+ assert_equal(s1.encoding, t.encoding)
+ t2 = s1.dup
+ t2.chomp!(s2)
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_chop
+ STRINGS.each {|s|
+ s = s.dup
+ desc = "#{encdump s}.chop"
+ if !s.valid_encoding?
+ #assert_raise(ArgumentError, desc) { s.chop }
+ begin
+ s.chop
+ rescue ArgumentError
+ e = $!
+ end
+ next if e
+ end
+ t = nil
+ assert_nothing_raised(desc) { t = s.chop }
+ assert(t.valid_encoding?) if s.valid_encoding?
+ assert(a(s).index(a(t)))
+ t2 = s.dup
+ t2.chop!
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_clear
+ STRINGS.each {|s|
+ t = s.dup
+ t.clear
+ assert(t.valid_encoding?)
+ assert(t.empty?)
+ }
+ end
+
+ def test_str_clone
+ STRINGS.each {|s|
+ t = s.clone
+ assert_equal(s, t)
+ assert_equal(s.encoding, t.encoding)
+ assert_equal(a(s), a(t))
+ }
+ end
+
+ def test_str_dup
+ STRINGS.each {|s|
+ t = s.dup
+ assert_equal(s, t)
+ assert_equal(s.encoding, t.encoding)
+ assert_equal(a(s), a(t))
+ }
+ end
+
+ def test_str_count
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_raise(ArgumentError, EncodingCompatibilityError) { s1.count(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.count(s2) }
+ next
+ end
+ n = enccall(s1, :count, s2)
+ n0 = a(s1).count(a(s2))
+ assert_operator(n, :<=, n0)
+ }
+ end
+
+ def test_str_crypt
+ combination(STRINGS, STRINGS) {|str, salt|
+ if a(salt).length < 2
+ assert_raise(ArgumentError) { str.crypt(salt) }
+ next
+ end
+ t = str.crypt(salt)
+ assert_equal(a(str).crypt(a(salt)), t, "#{encdump(str)}.crypt(#{encdump(salt)})")
+ assert_encoding('ASCII-8BIT', t.encoding)
+ }
+ end
+
+ def test_str_delete
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1.empty?
+ assert_equal(s1, s1.delete(s2))
+ next
+ end
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_raise(ArgumentError, EncodingCompatibilityError) { s1.delete(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.delete(s2) }
+ next
+ end
+ t = enccall(s1, :delete, s2)
+ assert(t.valid_encoding?)
+ assert_equal(t.encoding, s1.encoding)
+ assert_operator(t.length, :<=, s1.length)
+ t2 = s1.dup
+ t2.delete!(s2)
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_downcase
+ STRINGS.each {|s|
+ if !s.valid_encoding?
+ assert_raise(ArgumentError) { s.downcase }
+ next
+ end
+ t = s.downcase
+ assert(t.valid_encoding?)
+ assert_equal(t.encoding, s.encoding)
+ assert(t.casecmp(s))
+ t2 = s.dup
+ t2.downcase!
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_dump
+ STRINGS.each {|s|
+ t = s.dump
+ assert(t.valid_encoding?)
+ assert(t.ascii_only?)
+ u = eval(t)
+ assert_equal(a(s), a(u))
+ }
+ end
+
+ def test_str_each_line
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_raise(ArgumentError, EncodingCompatibilityError) { s1.each_line(s2) {} }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.each_line(s2) {} }
+ next
+ end
+ lines = []
+ enccall(s1, :each_line, s2) {|line|
+ assert(line.valid_encoding?)
+ assert_equal(s1.encoding, line.encoding)
+ lines << line
+ }
+ next if lines.size == 0
+ s2 = lines.join('')
+ assert_equal(s1.encoding, s2.encoding)
+ assert_equal(s1, s2)
+ }
+ end
+
+ def test_str_each_byte
+ STRINGS.each {|s|
+ bytes = []
+ s.each_byte {|b|
+ bytes << b
+ }
+ a(s).split(//).each_with_index {|ch, i|
+ assert_equal(ch.ord, bytes[i])
+ }
+ }
+ end
+
+ def test_str_empty?
+ STRINGS.each {|s|
+ if s.length == 0
+ assert(s.empty?)
+ else
+ assert(!s.empty?)
+ end
+ }
+ end
+
+ def test_str_hex
+ STRINGS.each {|s|
+ t = s.hex
+ t2 = a(s)[/\A[0-9a-fA-Fx]*/].hex
+ assert_equal(t2, t)
+ }
+ end
+
+ def test_str_include?
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.include?(s2) }
+ assert_raise(EncodingCompatibilityError) { s1.index(s2) }
+ assert_raise(EncodingCompatibilityError) { s1.rindex(s2) }
+ next
+ end
+ t = enccall(s1, :include?, s2)
+ if t
+ assert(a(s1).include?(a(s2)))
+ assert(s1.index(s2))
+ assert(s1.rindex(s2))
+ else
+ assert(!s1.index(s2))
+ assert(!s1.rindex(s2), "!#{encdump(s1)}.rindex(#{encdump(s2)})")
+ end
+ if s2.empty?
+ assert_equal(true, t)
+ next
+ end
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_equal(false, t, "#{encdump s1}.include?(#{encdump s2})")
+ next
+ end
+ if t && s1.valid_encoding? && s2.valid_encoding?
+ assert_match(/#{Regexp.escape(s2)}/, s1)
+ else
+ assert_no_match(/#{Regexp.escape(s2)}/, s1)
+ end
+ }
+ end
+
+ def test_str_index
+ combination(STRINGS, STRINGS, -2..2) {|s1, s2, pos|
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.index(s2) }
+ next
+ end
+ t = enccall(s1, :index, s2, pos)
+ if s2.empty?
+ if pos < 0 && pos+s1.length < 0
+ assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ elsif pos < 0
+ assert_equal(s1.length+pos, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ elsif s1.length < pos
+ assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ else
+ assert_equal(pos, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ end
+ next
+ end
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_equal(nil, t, "#{encdump s1}.index(#{encdump s2}, #{pos})");
+ next
+ end
+ if t
+ re = /#{Regexp.escape(s2)}/
+ assert(re.match(s1, pos))
+ assert_equal($`.length, t, "#{encdump s1}.index(#{encdump s2}, #{pos})")
+ else
+ assert_no_match(/#{Regexp.escape(s2)}/, s1[pos..-1])
+ end
+ }
+ end
+
+ def test_str_rindex
+ combination(STRINGS, STRINGS, -2..2) {|s1, s2, pos|
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.rindex(s2) }
+ next
+ end
+ t = enccall(s1, :rindex, s2, pos)
+ if s2.empty?
+ if pos < 0 && pos+s1.length < 0
+ assert_equal(nil, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ elsif pos < 0
+ assert_equal(s1.length+pos, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ elsif s1.length < pos
+ assert_equal(s1.length, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ else
+ assert_equal(pos, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ end
+ next
+ end
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_equal(nil, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ next
+ end
+ if t
+ #puts "#{encdump s1}.rindex(#{encdump s2}, #{pos}) => #{t}"
+ assert(a(s1).index(a(s2)))
+ pos2 = pos
+ pos2 += s1.length if pos < 0
+ re = /\A(.{0,#{pos2}})#{Regexp.escape(s2)}/m
+ m = enccall(re, :match, s1)
+ assert(m, "#{re.inspect}.match(#{encdump(s1)})")
+ assert_equal(m[1].length, t, "#{encdump s1}.rindex(#{encdump s2}, #{pos})")
+ else
+ re = /#{Regexp.escape(s2)}/
+ n = re =~ s1
+ if n
+ if pos < 0
+ assert_operator(n, :>, s1.length+pos)
+ else
+ assert_operator(n, :>, pos)
+ end
+ end
+ end
+ }
+ end
+
+ def test_str_insert
+ combination(STRINGS, 0..2, STRINGS) {|s1, nth, s2|
+ t1 = s1.dup
+ t2 = s1.dup
+ begin
+ t1[nth, 0] = s2
+ rescue EncodingCompatibilityError, IndexError => e1
+ end
+ begin
+ t2.insert(nth, s2)
+ rescue EncodingCompatibilityError, IndexError => e2
+ end
+ assert_equal(t1, t2, "t=#{encdump s1}; t.insert(#{nth},#{encdump s2}); t")
+ assert_equal(e1.class, e2.class, "begin #{encdump s1}.insert(#{nth},#{encdump s2}); rescue ArgumentError, IndexError => e; e end")
+ }
+ combination(STRINGS, -2..-1, STRINGS) {|s1, nth, s2|
+ next if s1.length + nth < 0
+ next unless s1.valid_encoding?
+ next unless s2.valid_encoding?
+ t1 = s1.dup
+ begin
+ t1.insert(nth, s2)
+ slen = s2.length
+ assert_equal(t1[nth-slen+1,slen], s2, "t=#{encdump s1}; t.insert(#{nth},#{encdump s2}); t")
+ rescue EncodingCompatibilityError, IndexError => e
+ end
+ }
+ end
+
+ def test_str_intern
+ STRINGS.each {|s|
+ if /\0/ =~ a(s)
+ assert_raise(ArgumentError) { s.intern }
+ else
+ sym = s.intern
+ assert_equal(s, sym.to_s, "#{encdump s}.intern.to_s")
+ assert_equal(sym, s.to_sym)
+ end
+ }
+ end
+
+ def test_str_length
+ STRINGS.each {|s|
+ assert_operator(s.length, :<=, s.bytesize)
+ }
+ end
+
+ def test_str_oct
+ STRINGS.each {|s|
+ t = s.oct
+ t2 = a(s)[/\A[0-9a-fA-FxXbB]*/].oct
+ assert_equal(t2, t)
+ }
+ end
+
+ def test_str_replace
+ combination(STRINGS, STRINGS) {|s1, s2|
+ t = s1.dup
+ t.replace s2
+ assert_equal(s2, t)
+ assert_equal(s2.encoding, t.encoding)
+ }
+ end
+
+ def test_str_reverse
+ STRINGS.each {|s|
+ t = s.reverse
+ assert_equal(s.bytesize, t.bytesize)
+ if !s.valid_encoding?
+ assert_operator(t.length, :<=, s.length)
+ next
+ end
+ assert_equal(s, t.reverse)
+ }
+ end
+
+ def test_str_scan
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s2.valid_encoding?
+ assert_raise(RegexpError) { s1.scan(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(ArgumentError) { s1.scan(s2) }
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError) { s1.scan(s2) }
+ next
+ end
+ r = enccall(s1, :scan, s2)
+ r.each {|t|
+ assert_equal(s2, t)
+ }
+ }
+ end
+
+ def test_str_slice
+ each_slice_call {|obj, *args|
+ assert_same_result(lambda { obj[*args] }, lambda { obj.slice(*args) })
+ }
+ end
+
+ def test_str_slice!
+ each_slice_call {|s, *args|
+ desc_slice = "#{encdump s}.slice#{encdumpargs args}"
+ desc_slice_bang = "#{encdump s}.slice!#{encdumpargs args}"
+ t = s.dup
+ begin
+ r = t.slice!(*args)
+ rescue
+ e = $!
+ end
+ if e
+ assert_raise(e.class, desc_slice) { s.slice(*args) }
+ next
+ end
+ if !r
+ assert_nil(s.slice(*args), desc_slice)
+ next
+ end
+ assert_equal(s.slice(*args), r, desc_slice_bang)
+ assert_equal(s.bytesize, r.bytesize + t.bytesize)
+ if args.length == 1 && String === args[0]
+ assert_equal(args[0].encoding, r.encoding,
+ "#{encdump s}.slice!#{encdumpargs args}.encoding")
+ else
+ assert_equal(s.encoding, r.encoding,
+ "#{encdump s}.slice!#{encdumpargs args}.encoding")
+ end
+ if [s, *args].all? {|o| !(String === o) || o.valid_encoding? }
+ assert(r.valid_encoding?)
+ assert(t.valid_encoding?)
+ assert_equal(s.length, r.length + t.length)
+ end
+ }
+ end
+
+ def test_str_split
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s2.valid_encoding?
+ assert_raise(RegexpError) { s1.split(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(ArgumentError) { s1.split(s2) }
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError) { s1.split(s2) }
+ next
+ end
+ t = enccall(s1, :split, s2)
+ t.each {|r|
+ assert(a(s1).include?(a(r)))
+ assert_equal(s1.encoding, r.encoding)
+ }
+ assert(a(s1).include?(t.map {|u| a(u) }.join(a(s2))))
+ if s1.valid_encoding? && s2.valid_encoding?
+ t.each {|r|
+ assert(r.valid_encoding?)
+ }
+ end
+ }
+ end
+
+ def test_str_squeeze
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if !s1.valid_encoding? || !s2.valid_encoding?
+ assert_raise(ArgumentError, EncodingCompatibilityError, "#{encdump s1}.squeeze(#{encdump s2})") { s1.squeeze(s2) }
+ next
+ end
+ if !s1.ascii_only? && !s2.ascii_only? && s1.encoding != s2.encoding
+ assert_raise(EncodingCompatibilityError) { s1.squeeze(s2) }
+ next
+ end
+ t = enccall(s1, :squeeze, s2)
+ assert_operator(t.length, :<=, s1.length)
+ t2 = s1.dup
+ t2.squeeze!(s2)
+ assert_equal(t, t2)
+ }
+ end
+
+ def test_str_strip
+ STRINGS.each {|s|
+ if !s.valid_encoding?
+ assert_raise(ArgumentError, "#{encdump s}.strip") { s.strip }
+ next
+ end
+ t = s.strip
+ l = s.lstrip
+ r = s.rstrip
+ assert_operator(l.length, :<=, s.length)
+ assert_operator(r.length, :<=, s.length)
+ assert_operator(t.length, :<=, l.length)
+ assert_operator(t.length, :<=, r.length)
+ t2 = s.dup
+ t2.strip!
+ assert_equal(t, t2)
+ l2 = s.dup
+ l2.lstrip!
+ assert_equal(l, l2)
+ r2 = s.dup
+ r2.rstrip!
+ assert_equal(r, r2)
+ }
+ end
+
+ def test_str_sum
+ STRINGS.each {|s|
+ assert_equal(a(s).sum, s.sum)
+ }
+ end
+
+ def test_str_swapcase
+ STRINGS.each {|s|
+ if !s.valid_encoding?
+ assert_raise(ArgumentError, "#{encdump s}.swapcase") { s.swapcase }
+ next
+ end
+ t1 = s.swapcase
+ assert(t1.valid_encoding?) if s.valid_encoding?
+ assert(t1.casecmp(s))
+ t2 = s.dup
+ t2.swapcase!
+ assert_equal(t1, t2)
+ t3 = t1.swapcase
+ assert_equal(s, t3);
+ }
+ end
+
+
+ def test_str_to_f
+ STRINGS.each {|s|
+ assert_nothing_raised { s.to_f }
+ }
+ end
+
+ def test_str_to_i
+ STRINGS.each {|s|
+ assert_nothing_raised { s.to_i }
+ 2.upto(36) {|radix|
+ assert_nothing_raised { s.to_i(radix) }
+ }
+ }
+ end
+
+ def test_str_to_s
+ STRINGS.each {|s|
+ assert_same(s, s.to_s)
+ assert_same(s, s.to_str)
+ }
+ end
+
+ def test_tr
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ desc = "#{encdump s1}.tr(#{encdump s2}, #{encdump s3})"
+ if s1.empty?
+ assert_equal(s1, s1.tr(s2, s3), desc)
+ next
+ end
+ if !str_enc_compatible?(s1, s2, s3)
+ assert_raise(EncodingCompatibilityError, desc) { s1.tr(s2, s3) }
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError, desc) { s1.tr(s2, s3) }
+ next
+ end
+ if s2.empty?
+ t = enccall(s1, :tr, s2, s3)
+ assert_equal(s1, t, desc)
+ next
+ end
+ if !s2.valid_encoding? || !s3.valid_encoding?
+ assert_raise(ArgumentError, desc) { s1.tr(s2, s3) }
+ next
+ end
+ t = enccall(s1, :tr, s2, s3)
+ assert_operator(s1.length, :>=, t.length, desc)
+ }
+ end
+
+ def test_tr_s
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ desc = "#{encdump s1}.tr_s(#{encdump s2}, #{encdump s3})"
+ if s1.empty?
+ assert_equal(s1, s1.tr_s(s2, s3), desc)
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError, EncodingCompatibilityError, desc) { s1.tr_s(s2, s3) }
+ next
+ end
+ if !str_enc_compatible?(s1, s2, s3)
+ assert_raise(EncodingCompatibilityError, desc) { s1.tr(s2, s3) }
+ next
+ end
+ if s2.empty?
+ t = enccall(s1, :tr_s, s2, s3)
+ assert_equal(s1, t, desc)
+ next
+ end
+ if !s2.valid_encoding? || !s3.valid_encoding?
+ assert_raise(ArgumentError, desc) { s1.tr_s(s2, s3) }
+ next
+ end
+
+ t = enccall(s1, :tr_s, s2, s3)
+ assert_operator(s1.length, :>=, t.length, desc)
+ }
+ end
+
+ def test_str_upcase
+ STRINGS.each {|s|
+ desc = "#{encdump s}.upcase"
+ if !s.valid_encoding?
+ assert_raise(ArgumentError, desc) { s.upcase }
+ next
+ end
+ t1 = s.upcase
+ assert(t1.valid_encoding?)
+ assert(t1.casecmp(s))
+ t2 = s.dup
+ t2.upcase!
+ assert_equal(t1, t2)
+ }
+ end
+
+ def test_str_succ
+ STRINGS.each {|s0|
+ next if s0.empty?
+ s = s0.dup
+ n = 1000
+ h = {}
+ n.times {|i|
+ if h[s]
+ assert(false, "#{encdump s} cycle with succ #{i-h[s]} times")
+ end
+ h[s] = i
+ assert_operator(s.length, :<=, s0.length + Math.log2(i+1) + 1, "#{encdump s0} succ #{i} times => #{encdump s}")
+ #puts encdump(s)
+ t = s.succ
+ if s.valid_encoding?
+ assert(t.valid_encoding?, "#{encdump s}.succ.valid_encoding?")
+ end
+ s = t
+ }
+ }
+ end
+
+ def test_str_hash
+ combination(STRINGS, STRINGS) {|s1, s2|
+ if s1.eql?(s2)
+ assert_equal(s1.hash, s2.hash, "#{encdump s1}.hash == #{encdump s2}.dump")
+ end
+ }
+ end
+
+ def test_marshal
+ STRINGS.each {|s|
+ m = Marshal.dump(s)
+ t = Marshal.load(m)
+ assert_equal(s, t)
+ }
+ end
+
+ def test_str_sub
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ if !s2.valid_encoding?
+ assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }
+ next
+ end
+ r2 = Regexp.new(Regexp.escape(s2))
+ [
+ [
+ "#{encdump s1}.sub(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { s1.sub(r2, s3) }
+ ],
+ [
+ "#{encdump s1}.sub(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { s1.sub(r2) { s3 } }
+ ],
+ [
+ "#{encdump s1}.gsub(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { s1.gsub(r2, s3) }
+ ],
+ [
+ "#{encdump s1}.gsub(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { s1.gsub(r2) { s3 } }
+ ]
+ ].each {|desc, doit|
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError, desc) { doit.call }
+ next
+ end
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(ArgumentError, desc) { doit.call }
+ next
+ end
+ if !enccall(s1, :include?, s2)
+ assert_equal(s1, doit.call)
+ next
+ end
+ if !str_enc_compatible?(s1.gsub(r2, ''), s3)
+ assert_raise(EncodingCompatibilityError, desc) { doit.call }
+ next
+ end
+ t = nil
+ assert_nothing_raised(desc) {
+ t = doit.call
+ }
+ if s2 == s3
+ assert_equal(s1, t, desc)
+ else
+ assert_not_equal(s1, t, desc)
+ end
+ }
+ }
+ end
+
+ def test_str_sub!
+ combination(STRINGS, STRINGS, STRINGS) {|s1, s2, s3|
+ if !s2.valid_encoding?
+ assert_raise(RegexpError) { Regexp.new(Regexp.escape(s2)) }
+ next
+ end
+ r2 = Regexp.new(Regexp.escape(s2))
+ [
+ [
+ "t=#{encdump s1}.dup;t.sub!(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { t=s1.dup; [t, t.sub!(r2, s3)] }
+ ],
+ [
+ "t=#{encdump s1}.dup;t.sub!(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { t=s1.dup; [t, t.sub!(r2) { s3 }] }
+ ],
+ [
+ "t=#{encdump s1}.dup;t.gsub!(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { t=s1.dup; [t, t.gsub!(r2, s3)] }
+ ],
+ [
+ "t=#{encdump s1}.dup;t.gsub!(Regexp.new(#{encdump s2}), #{encdump s3})",
+ lambda { t=s1.dup; [t, t.gsub!(r2) { s3 }] }
+ ]
+ ].each {|desc, doit|
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError, desc) { doit.call }
+ next
+ end
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(ArgumentError, desc) { doit.call }
+ next
+ end
+ if !enccall(s1, :include?, s2)
+ assert_equal([s1, nil], doit.call)
+ next
+ end
+ if !str_enc_compatible?(s1.gsub(r2, ''), s3)
+ assert_raise(EncodingCompatibilityError, desc) { doit.call }
+ next
+ end
+ t = ret = nil
+ assert_nothing_raised(desc) {
+ t, ret = doit.call
+ }
+ assert(ret)
+ if s2 == s3
+ assert_equal(s1, t, desc)
+ else
+ assert_not_equal(s1, t, desc)
+ end
+ }
+ }
+ end
+
+ def test_str_bytes
+ STRINGS.each {|s1|
+ ary = []
+ s1.bytes.each {|b|
+ ary << b
+ }
+ assert_equal(s1.unpack("C*"), ary)
+ }
+ end
+
+ def test_str_bytesize
+ STRINGS.each {|s1|
+ assert_equal(s1.unpack("C*").length, s1.bytesize)
+ }
+ end
+
+ def test_str_chars
+ STRINGS.each {|s1|
+ ary = []
+ s1.chars.each {|c|
+ ary << c
+ }
+ expected = []
+ s1.length.times {|i|
+ expected << s1[i]
+ }
+ assert_equal(expected, ary)
+ }
+ end
+
+ def test_str_chr
+ STRINGS.each {|s1|
+ if s1.empty?
+ assert_equal("", s1.chr)
+ next
+ end
+ assert_equal(s1[0], s1.chr)
+ }
+ end
+
+ def test_str_end_with?
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1}.end_with?(#{encdump s2})"
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(EncodingCompatibilityError, desc) { s1.end_with?(s2) }
+ next
+ end
+ if s1.length < s2.length
+ assert_equal(false, enccall(s1, :end_with?, s2), desc)
+ next
+ end
+ if s1[s1.length-s2.length, s2.length] == s2
+ assert_equal(true, enccall(s1, :end_with?, s2), desc)
+ next
+ end
+ assert_equal(false, enccall(s1, :end_with?, s2), desc)
+ }
+ end
+
+ def test_str_start_with?
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1}.start_with?(#{encdump s2})"
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(EncodingCompatibilityError, desc) { s1.start_with?(s2) }
+ next
+ end
+ s1 = s1.dup.force_encoding("ASCII-8BIT")
+ s2 = s2.dup.force_encoding("ASCII-8BIT")
+ if s1.length < s2.length
+ assert_equal(false, enccall(s1, :start_with?, s2), desc)
+ next
+ end
+ if s1[0, s2.length] == s2
+ assert_equal(true, enccall(s1, :start_with?, s2), desc)
+ next
+ end
+ assert_equal(false, enccall(s1, :start_with?, s2), desc)
+ }
+ end
+
+ def test_str_ord
+ STRINGS.each {|s1|
+ if s1.empty?
+ assert_raise(ArgumentError) { s1.ord }
+ next
+ end
+ if !s1.valid_encoding?
+ assert_raise(ArgumentError) { s1.ord }
+ next
+ end
+ assert_equal(s1[0].ord, s1.ord)
+ }
+ end
+
+ def test_str_partition
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1}.partition(#{encdump s2})"
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(EncodingCompatibilityError, desc) { s1.partition(s2) }
+ next
+ end
+ i = enccall(s1, :index, s2)
+ if !i
+ assert_equal([s1, "", ""], s1.partition(s2), desc)
+ next
+ end
+ assert_equal([s1[0,i], s2, s1[(i+s2.length)..-1]], s1.partition(s2), desc)
+ }
+ end
+
+ def test_str_rpartition
+ combination(STRINGS, STRINGS) {|s1, s2|
+ desc = "#{encdump s1}.rpartition(#{encdump s2})"
+ if !str_enc_compatible?(s1, s2)
+ assert_raise(EncodingCompatibilityError, desc) { s1.rpartition(s2) }
+ next
+ end
+ i = enccall(s1, :rindex, s2)
+ if !i
+ assert_equal(["", "", s1], s1.rpartition(s2), desc)
+ next
+ end
+ assert_equal([s1[0,i], s2, s1[(i+s2.length)..-1]], s1.rpartition(s2), desc)
+ }
+ end
+
+end
diff --git a/trunk/test/ruby/test_marshal.rb b/trunk/test/ruby/test_marshal.rb
new file mode 100644
index 0000000000..af389d2b2d
--- /dev/null
+++ b/trunk/test/ruby/test_marshal.rb
@@ -0,0 +1,194 @@
+require 'test/unit'
+require_relative 'marshaltestlib'
+
+class TestMarshal < Test::Unit::TestCase
+ include MarshalTestLib
+
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def encode(o)
+ Marshal.dump(o)
+ end
+
+ def decode(s)
+ Marshal.load(s)
+ end
+
+ def fact(n)
+ return 1 if n == 0
+ f = 1
+ while n>0
+ f *= n
+ n -= 1
+ end
+ return f
+ end
+
+ def test_marshal
+ x = [1, 2, 3, [4,5,"foo"], {1=>"bar"}, 2.5, fact(30)]
+ assert_equal x, Marshal.load(Marshal.dump(x))
+
+ [[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z|
+ obj = (x.to_f + y.to_f / z.to_f) * Math.exp(w.to_f / (x.to_f + y.to_f / z.to_f))
+ assert_equal obj, Marshal.load(Marshal.dump(obj))
+ }
+ end
+
+ StrClone = String.clone
+ def test_marshal_cloned_class
+ assert_instance_of(StrClone, Marshal.load(Marshal.dump(StrClone.new("abc"))))
+ end
+
+ def test_inconsistent_struct
+ TestMarshal.const_set :StructOrNot, Struct.new(:a)
+ s = Marshal.dump(StructOrNot.new(1))
+ TestMarshal.instance_eval { remove_const :StructOrNot }
+ TestMarshal.const_set :StructOrNot, Class.new
+ assert_raise(TypeError, "[ruby-dev:31709]") { Marshal.load(s) }
+ end
+
+ def test_struct_invalid_members
+ TestMarshal.const_set :StructInvalidMembers, Struct.new(:a)
+ Marshal.load("\004\bIc&TestMarshal::StructInvalidMembers\006:\020__members__\"\bfoo")
+ assert_raise(TypeError, "[ruby-dev:31759]") {
+ TestMarshal::StructInvalidMembers.members
+ }
+ end
+
+ class C
+ def initialize(str)
+ @str = str
+ end
+ attr_reader :str
+ def _dump(limit)
+ @str
+ end
+ def self._load(s)
+ new(s)
+ end
+ end
+
+ def test_too_long_string
+ data = Marshal.dump(C.new("a".force_encoding("ascii-8bit")))
+ data[-2, 1] = "\003\377\377\377"
+ e = assert_raise(ArgumentError, "[ruby-dev:32054]") {
+ Marshal.load(data)
+ }
+ assert_equal("marshal data too short", e.message)
+ end
+
+
+ def test_userdef_encoding
+ s1 = "\xa4\xa4".force_encoding("euc-jp")
+ o1 = C.new(s1)
+ m = Marshal.dump(o1)
+ o2 = Marshal.load(m)
+ s2 = o2.str
+ assert_equal(s1, s2)
+ end
+
+ def test_pipe
+ o1 = C.new("a" * 10000)
+
+ r, w = IO.pipe
+ t = Thread.new { Marshal.load(r) }
+ Marshal.dump(o1, w)
+ o2 = t.value
+ assert_equal(o1.str, o2.str)
+
+ r, w = IO.pipe
+ t = Thread.new { Marshal.load(r) }
+ Marshal.dump(o1, w, 2)
+ o2 = t.value
+ assert_equal(o1.str, o2.str)
+
+ assert_raise(TypeError) { Marshal.dump("foo", Object.new) }
+ assert_raise(TypeError) { Marshal.load(Object.new) }
+ end
+
+ def test_limit
+ assert_equal([[[]]], Marshal.load(Marshal.dump([[[]]], 3)))
+ assert_raise(ArgumentError) { Marshal.dump([[[]]], 2) }
+ end
+
+ def test_userdef_invalid
+ o = C.new(nil)
+ assert_raise(TypeError) { Marshal.dump(o) }
+ end
+
+ def test_class
+ o = class << Object.new; self; end
+ assert_raise(TypeError) { Marshal.dump(o) }
+ assert_equal(Object, Marshal.load(Marshal.dump(Object)))
+ assert_equal(Enumerable, Marshal.load(Marshal.dump(Enumerable)))
+ end
+
+ class C2
+ def initialize(ary)
+ @ary = ary
+ end
+ def _dump(s)
+ @ary.clear
+ "foo"
+ end
+ end
+
+ def test_modify_array_during_dump
+ a = []
+ o = C2.new(a)
+ a << o << nil
+ assert_raise(RuntimeError) { Marshal.dump(a) }
+ end
+
+ def test_change_class_name
+ eval("class C3; def _dump(s); 'foo'; end; end")
+ m = Marshal.dump(C3.new)
+ assert_raise(TypeError) { Marshal.load(m) }
+ eval("C3 = nil")
+ assert_raise(TypeError) { Marshal.load(m) }
+ end
+
+ def test_change_struct
+ eval("C3 = Struct.new(:foo, :bar)")
+ m = Marshal.dump(C3.new("FOO", "BAR"))
+ eval("C3 = Struct.new(:foo)")
+ assert_raise(TypeError) { Marshal.load(m) }
+ eval("C3 = Struct.new(:foo, :baz)")
+ assert_raise(TypeError) { Marshal.load(m) }
+ end
+
+ class C4
+ def initialize(gc)
+ @gc = gc
+ end
+ def _dump(s)
+ GC.start if @gc
+ "foo"
+ end
+ end
+
+ def test_gc
+ assert_nothing_raised do
+ Marshal.dump((0..1000).map {|x| C4.new(x % 50 == 25) })
+ end
+ end
+
+ def test_taint_and_untrust
+ x = Object.new
+ x.taint
+ x.untrust
+ s = Marshal.dump(x)
+ assert_equal(true, s.tainted?)
+ assert_equal(true, s.untrusted?)
+ y = Marshal.load(s)
+ assert_equal(true, y.tainted?)
+ assert_equal(true, y.untrusted?)
+ end
+end
diff --git a/trunk/test/ruby/test_math.rb b/trunk/test/ruby/test_math.rb
new file mode 100644
index 0000000000..55f354664c
--- /dev/null
+++ b/trunk/test/ruby/test_math.rb
@@ -0,0 +1,239 @@
+require 'test/unit'
+
+class TestMath < Test::Unit::TestCase
+ def check(a, b)
+ err = [Float::EPSILON * 4, [a.abs, b.abs].max * Float::EPSILON * 256].max
+ assert_in_delta(a, b, err)
+ end
+
+ def test_atan2
+ check(0, Math.atan2(0, 1))
+ check(Math::PI / 4, Math.atan2(1, 1))
+ check(Math::PI / 2, Math.atan2(1, 0))
+ end
+
+ def test_cos
+ check(1.0, Math.cos(0 * Math::PI / 4))
+ check(1.0 / Math.sqrt(2), Math.cos(1 * Math::PI / 4))
+ check(0.0, Math.cos(2 * Math::PI / 4))
+ check(-1.0, Math.cos(4 * Math::PI / 4))
+ check(0.0, Math.cos(6 * Math::PI / 4))
+ end
+
+ def test_sin
+ check(0.0, Math.sin(0 * Math::PI / 4))
+ check(1.0 / Math.sqrt(2), Math.sin(1 * Math::PI / 4))
+ check(1.0, Math.sin(2 * Math::PI / 4))
+ check(0.0, Math.sin(4 * Math::PI / 4))
+ check(-1.0, Math.sin(6 * Math::PI / 4))
+ end
+
+ def test_tan
+ check(0.0, Math.tan(0 * Math::PI / 4))
+ check(1.0, Math.tan(1 * Math::PI / 4))
+ assert(Math.tan(2 * Math::PI / 4).abs > 1024)
+ check(0.0, Math.tan(4 * Math::PI / 4))
+ assert(Math.tan(6 * Math::PI / 4).abs > 1024)
+ end
+
+ def test_acos
+ check(0 * Math::PI / 4, Math.acos( 1.0))
+ check(1 * Math::PI / 4, Math.acos( 1.0 / Math.sqrt(2)))
+ check(2 * Math::PI / 4, Math.acos( 0.0))
+ check(4 * Math::PI / 4, Math.acos(-1.0))
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.acos(2.0) }
+ end
+
+ def test_asin
+ check( 0 * Math::PI / 4, Math.asin( 0.0))
+ check( 1 * Math::PI / 4, Math.asin( 1.0 / Math.sqrt(2)))
+ check( 2 * Math::PI / 4, Math.asin( 1.0))
+ check(-2 * Math::PI / 4, Math.asin(-1.0))
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.asin(2.0) }
+ end
+
+ def test_atan
+ check( 0 * Math::PI / 4, Math.atan( 0.0))
+ check( 1 * Math::PI / 4, Math.atan( 1.0))
+ check( 2 * Math::PI / 4, Math.atan(1.0 / 0.0))
+ check(-1 * Math::PI / 4, Math.atan(-1.0))
+ end
+
+ def test_cosh
+ check(1, Math.cosh(0))
+ check((Math::E ** 1 + Math::E ** -1) / 2, Math.cosh(1))
+ check((Math::E ** 2 + Math::E ** -2) / 2, Math.cosh(2))
+ end
+
+ def test_sinh
+ check(0, Math.sinh(0))
+ check((Math::E ** 1 - Math::E ** -1) / 2, Math.sinh(1))
+ check((Math::E ** 2 - Math::E ** -2) / 2, Math.sinh(2))
+ end
+
+ def test_tanh
+ check(Math.sinh(0) / Math.cosh(0), Math.tanh(0))
+ check(Math.sinh(1) / Math.cosh(1), Math.tanh(1))
+ check(Math.sinh(2) / Math.cosh(2), Math.tanh(2))
+ end
+
+ def test_acosh
+ check(0, Math.acosh(1))
+ check(1, Math.acosh((Math::E ** 1 + Math::E ** -1) / 2))
+ check(2, Math.acosh((Math::E ** 2 + Math::E ** -2) / 2))
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.acosh(0) }
+ end
+
+ def test_asinh
+ check(0, Math.asinh(0))
+ check(1, Math.asinh((Math::E ** 1 - Math::E ** -1) / 2))
+ check(2, Math.asinh((Math::E ** 2 - Math::E ** -2) / 2))
+ end
+
+ def test_atanh
+ check(0, Math.atanh(Math.sinh(0) / Math.cosh(0)))
+ check(1, Math.atanh(Math.sinh(1) / Math.cosh(1)))
+ check(2, Math.atanh(Math.sinh(2) / Math.cosh(2)))
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.atanh(-1) }
+ end
+
+ def test_exp
+ check(1, Math.exp(0))
+ check(Math.sqrt(Math::E), Math.exp(0.5))
+ check(Math::E, Math.exp(1))
+ check(Math::E ** 2, Math.exp(2))
+ end
+
+ def test_log
+ check(0, Math.log(1))
+ check(1, Math.log(Math::E))
+ check(0, Math.log(1, 10))
+ check(1, Math.log(10, 10))
+ check(2, Math.log(100, 10))
+ assert_equal(1.0/0, Math.log(1.0/0))
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log(0) }
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log(-1) }
+ end
+
+ def test_log2
+ check(0, Math.log2(1))
+ check(1, Math.log2(2))
+ check(2, Math.log2(4))
+ assert_equal(1.0/0, Math.log2(1.0/0))
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log2(0) }
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log2(-1) }
+ end
+
+ def test_log10
+ check(0, Math.log10(1))
+ check(1, Math.log10(10))
+ check(2, Math.log10(100))
+ assert_equal(1.0/0, Math.log10(1.0/0))
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log10(0) }
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.log10(-1) }
+ end
+
+ def test_sqrt
+ check(0, Math.sqrt(0))
+ check(1, Math.sqrt(1))
+ check(2, Math.sqrt(4))
+ assert_equal(1.0/0, Math.sqrt(1.0/0))
+ assert_raise(Errno::EDOM, Errno::ERANGE) { Math.sqrt(-1) }
+ end
+
+ def test_frexp
+ check(0.0, Math.frexp(0.0).first)
+ assert_equal(0, Math.frexp(0).last)
+ check(0.5, Math.frexp(0.5).first)
+ assert_equal(0, Math.frexp(0.5).last)
+ check(0.5, Math.frexp(1.0).first)
+ assert_equal(1, Math.frexp(1.0).last)
+ check(0.5, Math.frexp(2.0).first)
+ assert_equal(2, Math.frexp(2.0).last)
+ check(0.75, Math.frexp(3.0).first)
+ assert_equal(2, Math.frexp(3.0).last)
+ end
+
+ def test_ldexp
+ check(0.0, Math.ldexp(0.0, 0.0))
+ check(0.5, Math.ldexp(0.5, 0.0))
+ check(1.0, Math.ldexp(0.5, 1.0))
+ check(2.0, Math.ldexp(0.5, 2.0))
+ check(3.0, Math.ldexp(0.75, 2.0))
+ end
+
+ def test_hypot
+ check(5, Math.hypot(3, 4))
+ end
+
+ def test_erf
+ check(0, Math.erf(0))
+ check(1, Math.erf(1.0 / 0.0))
+ end
+
+ def test_erfc
+ check(1, Math.erfc(0))
+ check(0, Math.erfc(1.0 / 0.0))
+ end
+
+ def test_gamma
+ sqrt_pi = Math.sqrt(Math::PI)
+ check(4 * sqrt_pi / 3, Math.gamma(-1.5))
+ check(-2 * sqrt_pi, Math.gamma(-0.5))
+ check(sqrt_pi, Math.gamma(0.5))
+ check(1, Math.gamma(1))
+ check(sqrt_pi / 2, Math.gamma(1.5))
+ check(1, Math.gamma(2))
+ check(3 * sqrt_pi / 4, Math.gamma(2.5))
+ check(2, Math.gamma(3))
+ check(15 * sqrt_pi / 8, Math.gamma(3.5))
+ check(6, Math.gamma(4))
+ end
+
+ def test_lgamma
+ sqrt_pi = Math.sqrt(Math::PI)
+
+ g, s = Math.lgamma(-1.5)
+ check(Math.log(4 * sqrt_pi / 3), g)
+ assert_equal(s, 1)
+
+ g, s = Math.lgamma(-0.5)
+ check(Math.log(2 * sqrt_pi), g)
+ assert_equal(s, -1)
+
+ g, s = Math.lgamma(0.5)
+ check(Math.log(sqrt_pi), g)
+ assert_equal(s, 1)
+
+ assert_equal([0, 1], Math.lgamma(1))
+
+ g, s = Math.lgamma(1.5)
+ check(Math.log(sqrt_pi / 2), g)
+ assert_equal(s, 1)
+
+ assert_equal([0, 1], Math.lgamma(2))
+
+ g, s = Math.lgamma(2.5)
+ check(Math.log(3 * sqrt_pi / 4), g)
+ assert_equal(s, 1)
+
+ g, s = Math.lgamma(3)
+ check(Math.log(2), g)
+ assert_equal(s, 1)
+
+ g, s = Math.lgamma(3.5)
+ check(Math.log(15 * sqrt_pi / 8), g)
+ assert_equal(s, 1)
+
+ g, s = Math.lgamma(4)
+ check(Math.log(6), g)
+ assert_equal(s, 1)
+ end
+
+ def test_cbrt
+ check(1, Math.cbrt(1))
+ check(-2, Math.cbrt(-8))
+ check(3, Math.cbrt(27))
+ check(-0.1, Math.cbrt(-0.001))
+ end
+end
diff --git a/trunk/test/ruby/test_method.rb b/trunk/test/ruby/test_method.rb
new file mode 100644
index 0000000000..d978050dc8
--- /dev/null
+++ b/trunk/test/ruby/test_method.rb
@@ -0,0 +1,224 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestMethod < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def m0() end
+ def m1(a) end
+ def m2(a, b) end
+ def mo1(a = nil, &b) end
+ def mo2(a, b = nil) end
+ def mo3(*a) end
+ def mo4(a, *b, &c) end
+ def mo5(a, *b, c) end
+ def mo6(a, *b, c, &d) end
+
+ class Base
+ def foo() :base end
+ end
+ class Derived < Base
+ def foo() :derived end
+ end
+
+ def test_arity
+ assert_equal(0, method(:m0).arity)
+ assert_equal(1, method(:m1).arity)
+ assert_equal(2, method(:m2).arity)
+ assert_equal(-1, method(:mo1).arity)
+ assert_equal(-2, method(:mo2).arity)
+ assert_equal(-1, method(:mo3).arity)
+ assert_equal(-2, method(:mo4).arity)
+ assert_equal(-3, method(:mo5).arity)
+ assert_equal(-3, method(:mo6).arity)
+ end
+
+ def test_unbind
+ assert_equal(:derived, Derived.new.foo)
+ um = Derived.new.method(:foo).unbind
+ assert_instance_of(UnboundMethod, um)
+ Derived.class_eval do
+ def foo() :changed end
+ end
+ assert_equal(:changed, Derived.new.foo)
+ assert_equal(:derived, um.bind(Derived.new).call)
+ assert_raise(TypeError) do
+ um.bind(Base.new)
+ end
+ end
+
+ def test_callee
+ assert_equal(:test_callee, __method__)
+ assert_equal(:m, Class.new {def m; __method__; end}.new.m)
+ assert_equal(:m, Class.new {def m; tap{return __method__}; end}.new.m)
+ assert_equal(:m, Class.new {define_method(:m) {__method__}}.new.m)
+ assert_equal(:m, Class.new {define_method(:m) {tap{return __method__}}}.new.m)
+ assert_nil(eval("class TestCallee; __method__; end"))
+ end
+
+ def test_body
+ o = Object.new
+ def o.foo; end
+ assert_nothing_raised { RubyVM::InstructionSequence.disasm(o.method(:foo)) }
+ end
+
+ def test_new
+ c1 = Class.new
+ c1.class_eval { def foo; :foo; end }
+ c2 = Class.new(c1)
+ c2.class_eval { private :foo }
+ o = c2.new
+ o.extend(Module.new)
+ assert_raise(NameError) { o.method(:bar) }
+ assert_raise(NameError) { o.public_method(:foo) }
+ assert_equal(:foo, o.method(:foo).call)
+ end
+
+ def test_eq
+ o = Object.new
+ class << o
+ def foo; end
+ alias bar foo
+ def baz; end
+ end
+ assert_not_equal(o.method(:foo), nil)
+ m = o.method(:foo)
+ def m.foo; end
+ assert_not_equal(o.method(:foo), m)
+ assert_equal(o.method(:foo), o.method(:foo))
+ assert_equal(o.method(:foo), o.method(:bar))
+ assert_not_equal(o.method(:foo), o.method(:baz))
+ end
+
+ def test_hash
+ o = Object.new
+ def o.foo; end
+ assert_kind_of(Integer, o.method(:foo).hash)
+ end
+
+ def test_receiver_name_owner
+ o = Object.new
+ def o.foo; end
+ m = o.method(:foo)
+ assert_equal(o, m.receiver)
+ assert_equal(:foo, m.name)
+ assert_equal(class << o; self; end, m.owner)
+ assert_equal(:foo, m.unbind.name)
+ assert_equal(class << o; self; end, m.unbind.owner)
+ end
+
+ def test_instance_method
+ c = Class.new
+ c.class_eval do
+ def foo; :foo; end
+ private :foo
+ end
+ o = c.new
+ o.method(:foo).unbind
+ assert_raise(NoMethodError) { o.foo }
+ c.instance_method(:foo).bind(o)
+ assert_equal(:foo, o.instance_eval { foo })
+ assert_raise(NameError) { c.public_instance_method(:foo) }
+ def o.bar; end
+ m = o.method(:bar).unbind
+ assert_raise(TypeError) { m.bind(Object.new) }
+ end
+
+ def test_define_method
+ c = Class.new
+ c.class_eval { def foo; :foo; end }
+ o = c.new
+ def o.bar; :bar; end
+ assert_raise(TypeError) do
+ c.class_eval { define_method(:foo, :foo) }
+ end
+ assert_raise(ArgumentError) do
+ c.class_eval { define_method }
+ end
+ c2 = Class.new(c)
+ c2.class_eval { define_method(:baz, o.method(:foo)) }
+ assert_equal(:foo, c2.new.baz)
+ assert_raise(TypeError) do
+ Class.new.class_eval { define_method(:foo, o.method(:foo)) }
+ end
+ assert_raise(TypeError) do
+ Class.new.class_eval { define_method(:bar, o.method(:bar)) }
+ end
+
+ o = Object.new
+ def o.foo(c)
+ c.class_eval { define_method(:foo) }
+ end
+ c = Class.new
+ o.foo(c) { :foo }
+ assert_equal(:foo, c.new.foo)
+
+ o = Object.new
+ o.instance_eval { define_singleton_method(:foo) { :foo } }
+ assert_equal(:foo, o.foo)
+ end
+
+ def test_clone
+ o = Object.new
+ def o.foo; :foo; end
+ m = o.method(:foo)
+ def m.bar; :bar; end
+ assert_equal(:foo, m.clone.call)
+ assert_equal(:bar, m.clone.bar)
+ end
+
+ def test_call
+ o = Object.new
+ def o.foo; p 1; end
+ def o.bar(x); x; end
+ m = o.method(:foo)
+ m.taint
+ assert_raise(SecurityError) { m.call }
+ end
+
+ def test_inspect
+ o = Object.new
+ def o.foo; end
+ m = o.method(:foo)
+ assert_equal("#<Method: #{ o.inspect }.foo>", m.inspect)
+ m = o.method(:foo)
+ assert_equal("#<UnboundMethod: #{ class << o; self; end.inspect }#foo>", m.unbind.inspect)
+
+ c = Class.new
+ c.class_eval { def foo; end; }
+ m = c.new.method(:foo)
+ assert_equal("#<Method: #{ c.inspect }#foo>", m.inspect)
+ m = c.instance_method(:foo)
+ assert_equal("#<UnboundMethod: #{ c.inspect }#foo>", m.inspect)
+
+ c2 = Class.new(c)
+ c2.class_eval { private :foo }
+ m2 = c2.new.method(:foo)
+ assert_equal("#<Method: #{ c2.inspect }(#{ c.inspect })#foo>", m2.inspect)
+ end
+
+ def test_callee_top_level
+ assert_in_out_err([], "p __callee__", %w(nil), [])
+ end
+
+ def test_caller_negative_level
+ assert_raise(ArgumentError) { caller(-1) }
+ end
+
+ def test_attrset_ivar
+ c = Class.new
+ c.class_eval { attr_accessor :foo }
+ o = c.new
+ o.method(:foo=).call(42)
+ assert_equal(42, o.foo)
+ assert_raise(ArgumentError) { o.method(:foo=).call(1, 2, 3) }
+ assert_raise(ArgumentError) { o.method(:foo).call(1) }
+ end
+end
diff --git a/trunk/test/ruby/test_mixed_unicode_escapes.rb b/trunk/test/ruby/test_mixed_unicode_escapes.rb
new file mode 100644
index 0000000000..f274ae7090
--- /dev/null
+++ b/trunk/test/ruby/test_mixed_unicode_escapes.rb
@@ -0,0 +1,25 @@
+# -*- coding: sjis -*-
+# This test is in a differnt file than TestUnicodeEscapes
+# So that we can have a different coding comment above
+
+require 'test/unit'
+
+class TestMixedUnicodeEscape < Test::Unit::TestCase
+ def test_basic
+ # Unicode escapes do work in an sjis encoded file, but only
+ # if they don't contain other multi-byte chars
+ assert_equal("A", "\u0041")
+ # 8-bit character escapes are okay.
+ assert_equal("B\xFF", "\u0042\xFF")
+
+ # sjis mb chars mixed with Unicode shound not work
+ assert_raise(SyntaxError) { eval %q("\u1234")}
+ assert_raise(SyntaxError) { eval %q("\u{1234}")}
+
+ # String interpolation turns into an expression and we get
+ # a different kind of error, but we still can't mix these
+ assert_raise(EncodingCompatibilityError) { eval %q("\u{1234}#{nil}")}
+ assert_raise(EncodingCompatibilityError) { eval %q("#{nil}\u1234")}
+
+ end
+end
diff --git a/trunk/test/ruby/test_module.rb b/trunk/test/ruby/test_module.rb
new file mode 100644
index 0000000000..edbbf250dd
--- /dev/null
+++ b/trunk/test/ruby/test_module.rb
@@ -0,0 +1,720 @@
+require 'test/unit'
+require 'pp'
+require_relative 'envutil'
+
+$m0 = Module.nesting
+
+class TestModule < Test::Unit::TestCase
+ def assert_method_defined?(klass, mid, message="")
+ message = build_message(message, "#{klass}\##{mid} expected to be defined.")
+ _wrap_assertion do
+ klass.method_defined?(mid) or
+ raise Test::Unit::AssertionFailedError, message, caller(3)
+ end
+ end
+
+ def assert_method_not_defined?(klass, mid, message="")
+ message = build_message(message, "#{klass}\##{mid} expected to not be defined.")
+ _wrap_assertion do
+ klass.method_defined?(mid) and
+ raise Test::Unit::AssertionFailedError, message, caller(3)
+ end
+ end
+
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_LT_0
+ assert_equal true, String < Object
+ assert_equal false, Object < String
+ assert_nil String < Array
+ assert_equal true, Array < Enumerable
+ assert_equal false, Enumerable < Array
+ assert_nil Proc < Comparable
+ assert_nil Comparable < Proc
+ end
+
+ def test_GT_0
+ assert_equal false, String > Object
+ assert_equal true, Object > String
+ assert_nil String > Array
+ assert_equal false, Array > Enumerable
+ assert_equal true, Enumerable > Array
+ assert_nil Comparable > Proc
+ assert_nil Proc > Comparable
+ end
+
+ def test_CMP_0
+ assert_equal -1, (String <=> Object)
+ assert_equal 1, (Object <=> String)
+ assert_nil(Array <=> String)
+ end
+
+ ExpectedException = NoMethodError
+
+ # Support stuff
+
+ def remove_pp_mixins(list)
+ list.reject {|c| c == PP::ObjectMixin }
+ end
+
+ def remove_json_mixins(list)
+ list.reject {|c| c.to_s.start_with?("JSON") }
+ end
+
+ module Mixin
+ MIXIN = 1
+ def mixin
+ end
+ end
+
+ module User
+ USER = 2
+ include Mixin
+ def user
+ end
+ end
+
+ module Other
+ def other
+ end
+ end
+
+ class AClass
+ def AClass.cm1
+ "cm1"
+ end
+ def AClass.cm2
+ cm1 + "cm2" + cm3
+ end
+ def AClass.cm3
+ "cm3"
+ end
+
+ private_class_method :cm1, "cm3"
+
+ def aClass
+ end
+
+ def aClass1
+ end
+
+ def aClass2
+ end
+
+ private :aClass1
+ protected :aClass2
+ end
+
+ class BClass < AClass
+ def bClass1
+ end
+
+ private
+
+ def bClass2
+ end
+
+ protected
+ def bClass3
+ end
+ end
+
+ MyClass = AClass.clone
+ class MyClass
+ public_class_method :cm1
+ end
+
+ # -----------------------------------------------------------
+
+ def test_CMP # '<=>'
+ assert_equal( 0, Mixin <=> Mixin)
+ assert_equal(-1, User <=> Mixin)
+ assert_equal( 1, Mixin <=> User)
+
+ assert_equal( 0, Object <=> Object)
+ assert_equal(-1, String <=> Object)
+ assert_equal( 1, Object <=> String)
+ end
+
+ def test_GE # '>='
+ assert(Mixin >= User)
+ assert(Mixin >= Mixin)
+ assert(!(User >= Mixin))
+
+ assert(Object >= String)
+ assert(String >= String)
+ assert(!(String >= Object))
+ end
+
+ def test_GT # '>'
+ assert(Mixin > User)
+ assert(!(Mixin > Mixin))
+ assert(!(User > Mixin))
+
+ assert(Object > String)
+ assert(!(String > String))
+ assert(!(String > Object))
+ end
+
+ def test_LE # '<='
+ assert(User <= Mixin)
+ assert(Mixin <= Mixin)
+ assert(!(Mixin <= User))
+
+ assert(String <= Object)
+ assert(String <= String)
+ assert(!(Object <= String))
+ end
+
+ def test_LT # '<'
+ assert(User < Mixin)
+ assert(!(Mixin < Mixin))
+ assert(!(Mixin < User))
+
+ assert(String < Object)
+ assert(!(String < String))
+ assert(!(Object < String))
+ end
+
+ def test_VERY_EQUAL # '==='
+ assert(Object === self)
+ assert(Test::Unit::TestCase === self)
+ assert(TestModule === self)
+ assert(!(String === self))
+ end
+
+ def test_ancestors
+ assert_equal([User, Mixin], User.ancestors)
+ assert_equal([Mixin], Mixin.ancestors)
+
+ assert_equal([Object, Kernel, BasicObject],
+ remove_json_mixins(remove_pp_mixins(Object.ancestors)))
+ assert_equal([String, Comparable, Object, Kernel, BasicObject],
+ remove_json_mixins(remove_pp_mixins(String.ancestors)))
+ end
+
+ def test_class_eval
+ Other.class_eval("CLASS_EVAL = 1")
+ assert_equal(1, Other::CLASS_EVAL)
+ assert(Other.constants.include?(:CLASS_EVAL))
+ end
+
+ def test_class_variable_set
+ # TODO
+ end
+
+ def test_class_variable_get
+ # TODO
+ end
+
+ def test_const_defined?
+ assert(Math.const_defined?(:PI))
+ assert(Math.const_defined?("PI"))
+ assert(!Math.const_defined?(:IP))
+ assert(!Math.const_defined?("IP"))
+ end
+
+ def test_const_get
+ assert_equal(Math::PI, Math.const_get("PI"))
+ assert_equal(Math::PI, Math.const_get(:PI))
+ end
+
+ def test_const_set
+ assert(!Other.const_defined?(:KOALA))
+ Other.const_set(:KOALA, 99)
+ assert(Other.const_defined?(:KOALA))
+ assert_equal(99, Other::KOALA)
+ Other.const_set("WOMBAT", "Hi")
+ assert_equal("Hi", Other::WOMBAT)
+ end
+
+ def test_constants
+ assert_equal([:MIXIN], Mixin.constants)
+ assert_equal([:MIXIN, :USER], User.constants.sort)
+ end
+
+ def test_included_modules
+ assert_equal([], Mixin.included_modules)
+ assert_equal([Mixin], User.included_modules)
+ assert_equal([Kernel],
+ remove_json_mixins(remove_pp_mixins(Object.included_modules)))
+ assert_equal([Comparable, Kernel],
+ remove_json_mixins(remove_pp_mixins(String.included_modules)))
+ end
+
+ def test_instance_methods
+ assert_equal([:user], User.instance_methods(false))
+ assert_equal([:user, :mixin].sort, User.instance_methods(true).sort)
+ assert_equal([:mixin], Mixin.instance_methods)
+ assert_equal([:mixin], Mixin.instance_methods(true))
+ # Ruby 1.8 feature change:
+ # #instance_methods includes protected methods.
+ #assert_equal([:aClass], AClass.instance_methods(false))
+ assert_equal([:aClass, :aClass2], AClass.instance_methods(false).sort)
+ assert_equal([:aClass, :aClass2],
+ (AClass.instance_methods(true) - Object.instance_methods(true)).sort)
+ end
+
+ def test_method_defined?
+ assert_method_not_defined?(User, :wombat)
+ assert_method_defined?(User, :user)
+ assert_method_defined?(User, :mixin)
+ assert_method_not_defined?(User, :wombat)
+ assert_method_defined?(User, :user)
+ assert_method_defined?(User, :mixin)
+ end
+
+ def module_exec_aux
+ Proc.new do
+ def dynamically_added_method_3; end
+ end
+ end
+ def module_exec_aux_2(&block)
+ User.module_exec(&block)
+ end
+
+ def test_module_exec
+ User.module_exec do
+ def dynamically_added_method_1; end
+ end
+ assert_method_defined?(User, :dynamically_added_method_1)
+
+ block = Proc.new do
+ def dynamically_added_method_2; end
+ end
+ User.module_exec(&block)
+ assert_method_defined?(User, :dynamically_added_method_2)
+
+ User.module_exec(&module_exec_aux)
+ assert_method_defined?(User, :dynamically_added_method_3)
+
+ module_exec_aux_2 do
+ def dynamically_added_method_4; end
+ end
+ assert_method_defined?(User, :dynamically_added_method_4)
+ end
+
+ def test_module_eval
+ User.module_eval("MODULE_EVAL = 1")
+ assert_equal(1, User::MODULE_EVAL)
+ assert(User.constants.include?(:MODULE_EVAL))
+ User.instance_eval("remove_const(:MODULE_EVAL)")
+ assert(!User.constants.include?(:MODULE_EVAL))
+ end
+
+ def test_name
+ assert_equal("Fixnum", Fixnum.name)
+ assert_equal("TestModule::Mixin", Mixin.name)
+ assert_equal("TestModule::User", User.name)
+ end
+
+ def test_private_class_method
+ assert_raise(ExpectedException) { AClass.cm1 }
+ assert_raise(ExpectedException) { AClass.cm3 }
+ assert_equal("cm1cm2cm3", AClass.cm2)
+ end
+
+ def test_private_instance_methods
+ assert_equal([:aClass1], AClass.private_instance_methods(false))
+ assert_equal([:bClass2], BClass.private_instance_methods(false))
+ assert_equal([:aClass1, :bClass2],
+ (BClass.private_instance_methods(true) -
+ Object.private_instance_methods(true)).sort)
+ end
+
+ def test_protected_instance_methods
+ assert_equal([:aClass2], AClass.protected_instance_methods)
+ assert_equal([:bClass3], BClass.protected_instance_methods(false))
+ assert_equal([:bClass3, :aClass2].sort,
+ (BClass.protected_instance_methods(true) -
+ Object.protected_instance_methods(true)).sort)
+ end
+
+ def test_public_class_method
+ assert_equal("cm1", MyClass.cm1)
+ assert_equal("cm1cm2cm3", MyClass.cm2)
+ assert_raise(ExpectedException) { eval "MyClass.cm3" }
+ end
+
+ def test_public_instance_methods
+ assert_equal([:aClass], AClass.public_instance_methods(false))
+ assert_equal([:bClass1], BClass.public_instance_methods(false))
+ end
+
+ def test_s_constants
+ c1 = Module.constants
+ Object.module_eval "WALTER = 99"
+ c2 = Module.constants
+ assert_equal([:WALTER], c2 - c1)
+ end
+
+ module M1
+ $m1 = Module.nesting
+ module M2
+ $m2 = Module.nesting
+ end
+ end
+
+ def test_s_nesting
+ assert_equal([], $m0)
+ assert_equal([TestModule::M1, TestModule], $m1)
+ assert_equal([TestModule::M1::M2,
+ TestModule::M1, TestModule], $m2)
+ end
+
+ def test_s_new
+ m = Module.new
+ assert_instance_of(Module, m)
+ end
+
+ def test_freeze
+ m = Module.new
+ m.freeze
+ assert_raise(RuntimeError) do
+ m.module_eval do
+ def foo; end
+ end
+ end
+ end
+
+ def test_attr_obsoleted_flag
+ c = Class.new
+ c.class_eval do
+ def initialize
+ @foo = :foo
+ @bar = :bar
+ end
+ attr :foo, true
+ attr :bar, false
+ end
+ o = c.new
+ assert_equal(true, o.respond_to?(:foo))
+ assert_equal(true, o.respond_to?(:foo=))
+ assert_equal(true, o.respond_to?(:bar))
+ assert_equal(false, o.respond_to?(:bar=))
+ end
+
+ def test_const_get2
+ c1 = Class.new
+ c2 = Class.new(c1)
+
+ eval("c1::Foo = :foo")
+ assert_equal(:foo, c1::Foo)
+ assert_equal(:foo, c2::Foo)
+ assert_equal(:foo, c2.const_get(:Foo))
+ assert_raise(NameError) { c2.const_get(:Foo, false) }
+
+ eval("c1::Foo = :foo")
+ assert_raise(NameError) { c1::Bar }
+ assert_raise(NameError) { c2::Bar }
+ assert_raise(NameError) { c2.const_get(:Bar) }
+ assert_raise(NameError) { c2.const_get(:Bar, false) }
+
+ c1.instance_eval do
+ def const_missing(x)
+ x
+ end
+ end
+
+ assert_equal(:Bar, c1::Bar)
+ assert_equal(:Bar, c2::Bar)
+ assert_equal(:Bar, c2.const_get(:Bar))
+ assert_equal(:Bar, c2.const_get(:Bar, false))
+
+ assert_raise(NameError) { c1.const_get(:foo) }
+ end
+
+ def test_const_set2
+ c1 = Class.new
+ assert_raise(NameError) { c1.const_set(:foo, :foo) }
+ end
+
+ def test_const_get3
+ c1 = Class.new
+ assert_raise(NameError) { c1.const_defined?(:foo) }
+ end
+
+ def test_class_variable_get2
+ c = Class.new
+ c.class_eval { @@foo = :foo }
+ assert_equal(:foo, c.class_variable_get(:@@foo))
+ assert_raise(NameError) { c.class_variable_get(:@@bar) } # c.f. instance_variable_get
+ assert_raise(NameError) { c.class_variable_get(:foo) }
+ end
+
+ def test_class_variable_set2
+ c = Class.new
+ c.class_variable_set(:@@foo, :foo)
+ assert_equal(:foo, c.class_eval { @@foo })
+ assert_raise(NameError) { c.class_variable_set(:foo, 1) }
+ end
+
+ def test_class_variable_defined
+ c = Class.new
+ c.class_eval { @@foo = :foo }
+ assert_equal(true, c.class_variable_defined?(:@@foo))
+ assert_equal(false, c.class_variable_defined?(:@@bar))
+ assert_raise(NameError) { c.class_variable_defined?(:foo) }
+ end
+
+ def test_export_method
+ m = Module.new
+ assert_raise(NameError) do
+ m.instance_eval { public(:foo) }
+ end
+ end
+
+ def test_attr
+ assert_in_out_err([], <<-INPUT, %w(:ok nil), /warning: private attribute\?$/)
+ $VERBOSE = true
+ c = Class.new
+ c.instance_eval do
+ private
+ attr_reader :foo
+ end
+ o = c.new
+ o.foo rescue p(:ok)
+ p(o.instance_eval { foo })
+ INPUT
+
+ c = Class.new
+ assert_raise(NameError) do
+ c.instance_eval { attr_reader :"$" }
+ end
+ end
+
+ def test_undef
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ Class.instance_eval { undef_method(:foo) }
+ end.join
+ end
+
+ c = Class.new
+ assert_raise(NameError) do
+ c.instance_eval { undef_method(:foo) }
+ end
+
+ m = Module.new
+ assert_raise(NameError) do
+ m.instance_eval { undef_method(:foo) }
+ end
+
+ o = Object.new
+ assert_raise(NameError) do
+ class << o; self; end.instance_eval { undef_method(:foo) }
+ end
+
+ %w(object_id __send__ initialize).each do |m|
+ assert_in_out_err([], <<-INPUT, [], /warning: undefining `#{m}' may cause serious problem$/)
+ $VERBOSE = false
+ Class.new.instance_eval { undef_method(:#{m}) }
+ INPUT
+ end
+ end
+
+ def test_alias
+ m = Module.new
+ assert_raise(NameError) do
+ m.class_eval { alias foo bar }
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(2), /warning: discarding old foo$/)
+ $VERBOSE = true
+ c = Class.new
+ c.class_eval do
+ def foo; 1; end
+ def bar; 2; end
+ end
+ c.class_eval { alias foo bar }
+ p c.new.foo
+ INPUT
+ end
+
+ def test_mod_constants
+ Module.const_set(:Foo, :foo)
+ assert_equal([:Foo], Module.constants(true))
+ assert_equal([:Foo], Module.constants(false))
+ Module.instance_eval { remove_const(:Foo) }
+ end
+
+ def test_frozen_class
+ m = Module.new
+ m.freeze
+ assert_raise(RuntimeError) do
+ m.instance_eval { undef_method(:foo) }
+ end
+
+ c = Class.new
+ c.freeze
+ assert_raise(RuntimeError) do
+ c.instance_eval { undef_method(:foo) }
+ end
+
+ o = Object.new
+ c = class << o; self; end
+ c.freeze
+ assert_raise(RuntimeError) do
+ c.instance_eval { undef_method(:foo) }
+ end
+ end
+
+ def test_method_defined
+ c = Class.new
+ c.class_eval do
+ def foo; end
+ def bar; end
+ def baz; end
+ public :foo
+ protected :bar
+ private :baz
+ end
+
+ assert_equal(true, c.public_method_defined?(:foo))
+ assert_equal(false, c.public_method_defined?(:bar))
+ assert_equal(false, c.public_method_defined?(:baz))
+
+ assert_equal(false, c.protected_method_defined?(:foo))
+ assert_equal(true, c.protected_method_defined?(:bar))
+ assert_equal(false, c.protected_method_defined?(:baz))
+
+ assert_equal(false, c.private_method_defined?(:foo))
+ assert_equal(false, c.private_method_defined?(:bar))
+ assert_equal(true, c.private_method_defined?(:baz))
+ end
+
+ def test_change_visibility_under_safe4
+ c = Class.new
+ c.class_eval do
+ def foo; end
+ end
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ c.class_eval { private :foo }
+ end.join
+ end
+ end
+
+ def test_top_public_private
+ assert_in_out_err([], <<-INPUT, %w([:foo] [:bar]), [])
+ private
+ def foo; :foo; end
+ public
+ def bar; :bar; end
+ p self.private_methods.grep(/^foo$|^bar$/)
+ p self.methods.grep(/^foo$|^bar$/)
+ INPUT
+ end
+
+ def test_append_features
+ t = nil
+ m = Module.new
+ m.module_eval do
+ def foo; :foo; end
+ end
+ class << m; self; end.class_eval do
+ define_method(:append_features) do |mod|
+ t = mod
+ super(mod)
+ end
+ end
+
+ m2 = Module.new
+ m2.module_eval { include(m) }
+ assert_equal(m2, t)
+
+ o = Object.new
+ o.extend(m2)
+ assert_equal(true, o.respond_to?(:foo))
+ end
+
+ def test_append_features_raise
+ m = Module.new
+ m.module_eval do
+ def foo; :foo; end
+ end
+ class << m; self; end.class_eval do
+ define_method(:append_features) {|mod| raise }
+ end
+
+ m2 = Module.new
+ assert_raise(RuntimeError) do
+ m2.module_eval { include(m) }
+ end
+
+ o = Object.new
+ o.extend(m2)
+ assert_equal(false, o.respond_to?(:foo))
+ end
+
+ def test_append_features_type_error
+ assert_raise(TypeError) do
+ Module.new.instance_eval { append_features(1) }
+ end
+ end
+
+ def test_included
+ m = Module.new
+ m.module_eval do
+ def foo; :foo; end
+ end
+ class << m; self; end.class_eval do
+ define_method(:included) {|mod| raise }
+ end
+
+ m2 = Module.new
+ assert_raise(RuntimeError) do
+ m2.module_eval { include(m) }
+ end
+
+ o = Object.new
+ o.extend(m2)
+ assert_equal(true, o.respond_to?(:foo))
+ end
+
+ def test_cyclic_include
+ m1 = Module.new
+ m2 = Module.new
+ m1.instance_eval { include(m2) }
+ assert_raise(ArgumentError) do
+ m2.instance_eval { include(m1) }
+ end
+ end
+
+ def test_include_p
+ m = Module.new
+ c1 = Class.new
+ c1.instance_eval { include(m) }
+ c2 = Class.new(c1)
+ assert_equal(true, c1.include?(m))
+ assert_equal(true, c2.include?(m))
+ assert_equal(false, m.include?(m))
+ end
+
+ def test_include_under_safe4
+ m = Module.new
+ c1 = Class.new
+ assert_raise(SecurityError) do
+ lambda {
+ $SAFE = 4
+ c1.instance_eval { include(m) }
+ }.call
+ end
+ assert_nothing_raised do
+ lambda {
+ $SAFE = 4
+ c2 = Class.new
+ c2.instance_eval { include(m) }
+ }.call
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_numeric.rb b/trunk/test/ruby/test_numeric.rb
new file mode 100644
index 0000000000..3db054fdae
--- /dev/null
+++ b/trunk/test/ruby/test_numeric.rb
@@ -0,0 +1,217 @@
+require 'test/unit'
+
+class TestNumeric < Test::Unit::TestCase
+ class DummyNumeric < Numeric
+ end
+
+ def test_coerce
+ a, b = 1.coerce(2)
+ assert_equal(Fixnum, a.class)
+ assert_equal(Fixnum, b.class)
+
+ a, b = 1.coerce(2.0)
+ assert_equal(Float, a.class)
+ assert_equal(Float, b.class)
+
+ assert_raise(TypeError) { -Numeric.new }
+ end
+
+ def test_dummynumeric
+ a = DummyNumeric.new
+
+ DummyNumeric.class_eval do
+ def coerce(x); nil; end
+ end
+ assert_raise(TypeError) { -a }
+ assert_nil(1 <=> a)
+ assert_raise(ArgumentError) { 1 <= a }
+
+ DummyNumeric.class_eval do
+ def coerce(x); 1.coerce(x); end
+ end
+ assert_equal(2, 1 + a)
+ assert_equal(0, 1 <=> a)
+ assert(1 <= a)
+
+ DummyNumeric.class_eval do
+ def coerce(x); [x, 1]; end
+ end
+ assert_equal(-1, -a)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :coerce
+ end
+ end
+
+ def test_numeric
+ a = Numeric.new
+ assert_raise(TypeError) { def a.foo; end }
+ assert_raise(TypeError) { a.dup }
+ end
+
+ def test_quo
+ assert_raise(ArgumentError) {DummyNumeric.new.quo(1)}
+ end
+
+ def test_divmod
+ DummyNumeric.class_eval do
+ def /(x); 42.0; end
+ def %(x); :mod; end
+ end
+
+ assert_equal(42, DummyNumeric.new.div(1))
+ assert_equal(:mod, DummyNumeric.new.modulo(1))
+ assert_equal([42, :mod], DummyNumeric.new.divmod(1))
+
+ assert_kind_of(Integer, 11.divmod(3.5).first, '[ruby-dev:34006]')
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :/, :%
+ end
+ end
+
+ def test_scalar_p
+ assert(Numeric.new.scalar?)
+ end
+
+ def test_integer_p
+ assert(!Numeric.new.integer?)
+ end
+
+ def test_abs
+ a = DummyNumeric.new
+ DummyNumeric.class_eval do
+ def -@; :ok; end
+ def <(x); true; end
+ end
+
+ assert_equal(:ok, a.abs)
+
+ DummyNumeric.class_eval do
+ def <(x); false; end
+ end
+
+ assert_equal(a, a.abs)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :-@, :<
+ end
+ end
+
+ def test_zero_p
+ DummyNumeric.class_eval do
+ def ==(x); true; end
+ end
+
+ assert(DummyNumeric.new.zero?)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :==
+ end
+ end
+
+ def test_to_int
+ DummyNumeric.class_eval do
+ def to_i; :ok; end
+ end
+
+ assert_equal(:ok, DummyNumeric.new.to_int)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :to_i
+ end
+ end
+
+ def test_cmp
+ a = Numeric.new
+ assert_equal(0, a <=> a)
+ assert_nil(a <=> :foo)
+ end
+
+ def test_floor_ceil_round_truncate
+ DummyNumeric.class_eval do
+ def to_f; 1.5; end
+ end
+
+ a = DummyNumeric.new
+ assert_equal(1, a.floor)
+ assert_equal(2, a.ceil)
+ assert_equal(2, a.round)
+ assert_equal(1, a.truncate)
+
+ DummyNumeric.class_eval do
+ def to_f; 1.4; end
+ end
+
+ a = DummyNumeric.new
+ assert_equal(1, a.floor)
+ assert_equal(2, a.ceil)
+ assert_equal(1, a.round)
+ assert_equal(1, a.truncate)
+
+ DummyNumeric.class_eval do
+ def to_f; -1.5; end
+ end
+
+ a = DummyNumeric.new
+ assert_equal(-2, a.floor)
+ assert_equal(-1, a.ceil)
+ assert_equal(-2, a.round)
+ assert_equal(-1, a.truncate)
+
+ ensure
+ DummyNumeric.class_eval do
+ remove_method :to_f
+ end
+ end
+
+ def test_step
+ a = []
+ 1.step(10) {|x| a << x }
+ assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a)
+
+ a = []
+ 1.step(10, 2) {|x| a << x }
+ assert_equal([1, 3, 5, 7, 9], a)
+
+ assert_raise(ArgumentError) { 1.step(10, 1, 0) { } }
+ assert_raise(ArgumentError) { 1.step(10, 0) { } }
+
+ a = []
+ 10.step(1, -2) {|x| a << x }
+ assert_equal([10, 8, 6, 4, 2], a)
+
+ a = []
+ 1.0.step(10.0, 2.0) {|x| a << x }
+ assert_equal([1.0, 3.0, 5.0, 7.0, 9.0], a)
+
+ a = []
+ 1.step(10, 2**32) {|x| a << x }
+ assert_equal([1], a)
+
+ a = []
+ 10.step(1, -(2**32)) {|x| a << x }
+ assert_equal([10], a)
+ end
+
+ def test_num2long
+ assert_raise(TypeError) { 1 & nil }
+ assert_raise(TypeError) { 1 & 1.0 }
+ assert_raise(TypeError) { 1 & 2147483648.0 }
+ assert_raise(TypeError) { 1 & 9223372036854777856.0 }
+ o = Object.new
+ def o.to_int; 1; end
+ assert_equal(1, 1 & o)
+ end
+
+ def test_eql
+ assert(1 == 1.0)
+ assert(!(1.eql?(1.0)))
+ assert(!(1.eql?(2)))
+ end
+end
diff --git a/trunk/test/ruby/test_object.rb b/trunk/test/ruby/test_object.rb
new file mode 100644
index 0000000000..5190eb69e5
--- /dev/null
+++ b/trunk/test/ruby/test_object.rb
@@ -0,0 +1,401 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestObject < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_dup
+ assert_raise(TypeError) { 1.dup }
+ assert_raise(TypeError) { true.dup }
+ assert_raise(TypeError) { nil.dup }
+
+ assert_raise(TypeError) do
+ Object.new.instance_eval { initialize_copy(1) }
+ end
+ end
+
+ def test_instance_of
+ assert_raise(TypeError) { 1.instance_of?(1) }
+ end
+
+ def test_kind_of
+ assert_raise(TypeError) { 1.kind_of?(1) }
+ end
+
+ def test_taint_frozen_obj
+ o = Object.new
+ o.freeze
+ assert_raise(RuntimeError) { o.taint }
+
+ o = Object.new
+ o.taint
+ o.freeze
+ assert_raise(RuntimeError) { o.untaint }
+ end
+
+ def test_freeze_under_safe_4
+ o = Object.new
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ o.freeze
+ end.join
+ end
+ end
+
+ def test_freeze_immediate
+ assert_equal(false, 1.frozen?)
+ 1.freeze
+ assert_equal(true, 1.frozen?)
+ assert_equal(false, 2.frozen?)
+ end
+
+ def test_nil_to_f
+ assert_equal(0.0, nil.to_f)
+ end
+
+ def test_not
+ assert_equal(false, Object.new.send(:!))
+ assert_equal(true, nil.send(:!))
+ end
+
+ def test_true_and
+ assert_equal(true, true & true)
+ assert_equal(true, true & 1)
+ assert_equal(false, true & false)
+ assert_equal(false, true & nil)
+ end
+
+ def test_true_or
+ assert_equal(true, true | true)
+ assert_equal(true, true | 1)
+ assert_equal(true, true | false)
+ assert_equal(true, true | nil)
+ end
+
+ def test_true_xor
+ assert_equal(false, true ^ true)
+ assert_equal(false, true ^ 1)
+ assert_equal(true, true ^ false)
+ assert_equal(true, true ^ nil)
+ end
+
+ def test_false_and
+ assert_equal(false, false & true)
+ assert_equal(false, false & 1)
+ assert_equal(false, false & false)
+ assert_equal(false, false & nil)
+ end
+
+ def test_false_or
+ assert_equal(true, false | true)
+ assert_equal(true, false | 1)
+ assert_equal(false, false | false)
+ assert_equal(false, false | nil)
+ end
+
+ def test_false_xor
+ assert_equal(true, false ^ true)
+ assert_equal(true, false ^ 1)
+ assert_equal(false, false ^ false)
+ assert_equal(false, false ^ nil)
+ end
+
+ def test_methods
+ o = Object.new
+ a1 = o.methods
+ a2 = o.methods(false)
+
+ def o.foo; end
+
+ assert_equal([:foo], o.methods(true) - a1)
+ assert_equal([:foo], o.methods(false) - a2)
+ end
+
+ def test_methods2
+ c0 = Class.new
+ c1 = Class.new(c0)
+ c1.module_eval do
+ public ; def foo; end
+ protected; def bar; end
+ private ; def baz; end
+ end
+ c2 = Class.new(c1)
+ c2.module_eval do
+ public ; def foo2; end
+ protected; def bar2; end
+ private ; def baz2; end
+ end
+
+ o0 = c0.new
+ o2 = c2.new
+
+ assert_equal([:baz, :baz2], (o2.private_methods - o0.private_methods).sort)
+ assert_equal([:baz2], (o2.private_methods(false) - o0.private_methods(false)).sort)
+
+ assert_equal([:bar, :bar2], (o2.protected_methods - o0.protected_methods).sort)
+ assert_equal([:bar2], (o2.protected_methods(false) - o0.protected_methods(false)).sort)
+
+ assert_equal([:foo, :foo2], (o2.public_methods - o0.public_methods).sort)
+ assert_equal([:foo2], (o2.public_methods(false) - o0.public_methods(false)).sort)
+ end
+
+ def test_instance_variable_get
+ o = Object.new
+ o.instance_eval { @foo = :foo }
+ assert_equal(:foo, o.instance_variable_get(:@foo))
+ assert_equal(nil, o.instance_variable_get(:@bar))
+ assert_raise(NameError) { o.instance_variable_get(:foo) }
+ end
+
+ def test_instance_variable_set
+ o = Object.new
+ o.instance_variable_set(:@foo, :foo)
+ assert_equal(:foo, o.instance_eval { @foo })
+ assert_raise(NameError) { o.instance_variable_set(:foo, 1) }
+ end
+
+ def test_instance_variable_defined
+ o = Object.new
+ o.instance_eval { @foo = :foo }
+ assert_equal(true, o.instance_variable_defined?(:@foo))
+ assert_equal(false, o.instance_variable_defined?(:@bar))
+ assert_raise(NameError) { o.instance_variable_defined?(:foo) }
+ end
+
+ def test_convert_type
+ o = Object.new
+ def o.to_s; 1; end
+ assert_raise(TypeError) { String(o) }
+ end
+
+ def test_check_convert_type
+ o = Object.new
+ def o.to_a; 1; end
+ assert_raise(TypeError) { Array(o) }
+ end
+
+ def test_to_integer
+ o = Object.new
+ def o.to_i; nil; end
+ assert_raise(TypeError) { Integer(o) }
+ end
+
+ class MyInteger
+ def initialize(n); @num = n; end
+ def to_int; @num; end
+ def <=>(n); @num <=> n.to_int; end
+ def <=(n); @num <= n.to_int; end
+ def +(n); MyInteger.new(@num + n.to_int); end
+ end
+
+ def test_check_to_integer
+ o1 = MyInteger.new(1)
+ o9 = MyInteger.new(9)
+ n = 0
+ Range.new(o1, o9).step(2) {|x| n += x.to_int }
+ assert_equal(1+3+5+7+9, n)
+ end
+
+ def test_add_method_under_safe4
+ o = Object.new
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ def o.foo
+ end
+ end.join
+ end
+ end
+
+ def test_redefine_method_under_verbose
+ assert_in_out_err([], <<-INPUT, %w(2), /warning: method redefined; discarding old foo$/)
+ $VERBOSE = true
+ o = Object.new
+ def o.foo; 1; end
+ def o.foo; 2; end
+ p o.foo
+ INPUT
+ end
+
+ def test_redefine_method_which_may_case_serious_problem
+ assert_in_out_err([], <<-INPUT, [], /warning: redefining `object_id' may cause serious problem$/)
+ $VERBOSE = false
+ def (Object.new).object_id; end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, [], /warning: redefining `__send__' may cause serious problem$/)
+ $VERBOSE = false
+ def (Object.new).__send__; end
+ INPUT
+ end
+
+ def test_remove_method
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ Object.instance_eval { remove_method(:foo) }
+ end.join
+ end
+
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ Class.instance_eval { remove_method(:foo) }
+ end.join
+ end
+
+ c = Class.new
+ c.freeze
+ assert_raise(RuntimeError) do
+ c.instance_eval { remove_method(:foo) }
+ end
+
+ %w(object_id __send__ initialize).each do |m|
+ assert_in_out_err([], <<-INPUT, %w(:ok), /warning: removing `#{m}' may cause serious problem$/)
+ $VERBOSE = false
+ begin
+ Class.new.instance_eval { remove_method(:#{m}) }
+ rescue NameError
+ p :ok
+ end
+ INPUT
+ end
+ end
+
+ def test_method_missing
+ assert_raise(ArgumentError) do
+ 1.instance_eval { method_missing }
+ end
+
+ c = Class.new
+ c.class_eval do
+ protected
+ def foo; end
+ end
+ assert_raise(NoMethodError) do
+ c.new.foo
+ end
+
+ assert_raise(NoMethodError) do
+ 1.instance_eval { method_missing(:method_missing) }
+ end
+ end
+
+ def test_send_with_no_arguments
+ assert_raise(ArgumentError) { 1.send }
+ end
+
+ def test_specific_eval_with_wrong_arguments
+ assert_raise(ArgumentError) do
+ 1.instance_eval("foo") { foo }
+ end
+
+ assert_raise(ArgumentError) do
+ 1.instance_eval
+ end
+
+ assert_raise(ArgumentError) do
+ 1.instance_eval("", 1, 1, 1)
+ end
+ end
+
+ def test_instance_exec
+ x = 1.instance_exec(42) {|a| self + a }
+ assert_equal(43, x)
+
+ x = "foo".instance_exec("bar") {|a| self + a }
+ assert_equal("foobar", x)
+ end
+
+ def test_extend
+ assert_raise(ArgumentError) do
+ 1.extend
+ end
+ end
+
+ def test_untrusted
+ obj = lambda {
+ $SAFE = 4
+ x = Object.new
+ x.instance_eval { @foo = 1 }
+ x
+ }.call
+ assert_equal(true, obj.untrusted?)
+ assert_equal(true, obj.tainted?)
+
+ x = Object.new
+ assert_equal(false, x.untrusted?)
+ assert_raise(SecurityError) do
+ lambda {
+ $SAFE = 4
+ x.instance_eval { @foo = 1 }
+ }.call
+ end
+
+ x = Object.new
+ x.taint
+ assert_raise(SecurityError) do
+ lambda {
+ $SAFE = 4
+ x.instance_eval { @foo = 1 }
+ }.call
+ end
+
+ x.untrust
+ assert_equal(true, x.untrusted?)
+ assert_nothing_raised do
+ lambda {
+ $SAFE = 4
+ x.instance_eval { @foo = 1 }
+ }.call
+ end
+
+ x.trust
+ assert_equal(false, x.untrusted?)
+ assert_raise(SecurityError) do
+ lambda {
+ $SAFE = 4
+ x.instance_eval { @foo = 1 }
+ }.call
+ end
+
+ a = Object.new
+ a.untrust
+ assert_equal(true, a.untrusted?)
+ b = a.dup
+ assert_equal(true, b.untrusted?)
+ c = a.clone
+ assert_equal(true, c.untrusted?)
+
+ a = Object.new
+ b = lambda {
+ $SAFE = 4
+ a.dup
+ }.call
+ assert_equal(true, b.untrusted?)
+
+ a = Object.new
+ b = lambda {
+ $SAFE = 4
+ a.clone
+ }.call
+ assert_equal(true, b.untrusted?)
+ end
+
+ def test_to_s
+ x = Object.new
+ x.taint
+ x.untrust
+ s = x.to_s
+ assert_equal(true, s.untrusted?)
+ assert_equal(true, s.tainted?)
+ end
+end
diff --git a/trunk/test/ruby/test_objectspace.rb b/trunk/test/ruby/test_objectspace.rb
new file mode 100644
index 0000000000..571c725986
--- /dev/null
+++ b/trunk/test/ruby/test_objectspace.rb
@@ -0,0 +1,67 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestObjectSpace < Test::Unit::TestCase
+ def self.deftest_id2ref(obj)
+ /:(\d+)/ =~ caller[0]
+ file = $`
+ line = $1.to_i
+ code = <<"End"
+ define_method("test_id2ref_#{line}") {\
+ o = ObjectSpace._id2ref(obj.object_id);\
+ assert_same(obj, o, "didn't round trip: \#{obj.inspect}");\
+ }
+End
+ eval code, binding, file, line
+ end
+
+ deftest_id2ref(-0x4000000000000001)
+ deftest_id2ref(-0x4000000000000000)
+ deftest_id2ref(-0x40000001)
+ deftest_id2ref(-0x40000000)
+ deftest_id2ref(-1)
+ deftest_id2ref(0)
+ deftest_id2ref(1)
+ deftest_id2ref(0x3fffffff)
+ deftest_id2ref(0x40000000)
+ deftest_id2ref(0x3fffffffffffffff)
+ deftest_id2ref(0x4000000000000000)
+ deftest_id2ref(:a)
+ deftest_id2ref(:abcdefghijilkjl)
+ deftest_id2ref(:==)
+ deftest_id2ref(Object.new)
+ deftest_id2ref(self)
+ deftest_id2ref(true)
+ deftest_id2ref(false)
+ deftest_id2ref(nil)
+
+ def test_count_objects
+ h = {}
+ ObjectSpace.count_objects(h)
+ assert_kind_of(Hash, h)
+ assert(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
+ assert(h.values.all? {|x| x.is_a?(Integer) })
+
+ h = ObjectSpace.count_objects
+ assert_kind_of(Hash, h)
+ assert(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
+ assert(h.values.all? {|x| x.is_a?(Integer) })
+
+ assert_raise(TypeError) { ObjectSpace.count_objects(1) }
+
+ h0 = {:T_FOO=>1000}
+ h = ObjectSpace.count_objects(h0)
+ assert_same(h0, h)
+ assert_equal(0, h0[:T_FOO])
+ end
+
+ def test_finalizer
+ assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok :ok), [])
+ a = []
+ ObjectSpace.define_finalizer(a) { p :ok }
+ b = a.dup
+ ObjectSpace.define_finalizer(a) { p :ok }
+ END
+ assert_raise(ArgumentError) { ObjectSpace.define_finalizer([], Object.new) }
+ end
+end
diff --git a/trunk/test/ruby/test_optimization.rb b/trunk/test/ruby/test_optimization.rb
new file mode 100644
index 0000000000..8e8311e6ef
--- /dev/null
+++ b/trunk/test/ruby/test_optimization.rb
@@ -0,0 +1,140 @@
+require 'test/unit'
+
+class TestRubyOptimization < Test::Unit::TestCase
+
+ BIGNUM_POS_MIN_32 = 1073741824 # 2 ** 30
+ if BIGNUM_POS_MIN_32.kind_of?(Fixnum)
+ FIXNUM_MAX = 4611686018427387903 # 2 ** 62 - 1
+ else
+ FIXNUM_MAX = 1073741823 # 2 ** 30 - 1
+ end
+
+ BIGNUM_NEG_MAX_32 = -1073741825 # -2 ** 30 - 1
+ if BIGNUM_NEG_MAX_32.kind_of?(Fixnum)
+ FIXNUM_MIN = -4611686018427387904 # -2 ** 62
+ else
+ FIXNUM_MIN = -1073741824 # -2 ** 30
+ end
+
+ def redefine_method(klass, method)
+ (@redefine_method_seq ||= 0)
+ seq = (@redefine_method_seq += 1)
+ eval(<<-End, ::TOPLEVEL_BINDING)
+ class #{klass}
+ alias redefine_method_orig_#{seq} #{method}
+ undef #{method}
+ def #{method}(*args)
+ args[0]
+ end
+ end
+ End
+ begin
+ return yield
+ ensure
+ eval(<<-End, ::TOPLEVEL_BINDING)
+ class #{klass}
+ undef #{method}
+ alias #{method} redefine_method_orig_#{seq}
+ end
+ End
+ end
+ end
+
+ def test_fixnum_plus
+ a, b = 1, 2
+ assert_equal 3, a + b
+ assert_instance_of Fixnum, FIXNUM_MAX
+ assert_instance_of Bignum, FIXNUM_MAX + 1
+
+ assert_equal 21, 10 + 11
+ assert_equal 11, redefine_method('Fixnum', '+') { 10 + 11 }
+ assert_equal 21, 10 + 11
+ end
+
+ def test_fixnum_minus
+ assert_equal 5, 8 - 3
+ assert_instance_of Fixnum, FIXNUM_MIN
+ assert_instance_of Bignum, FIXNUM_MIN - 1
+
+ assert_equal 5, 8 - 3
+ assert_equal 3, redefine_method('Fixnum', '-') { 8 - 3 }
+ assert_equal 5, 8 - 3
+ end
+
+ def test_fixnum_mul
+ assert_equal 15, 3 * 5
+ end
+
+ def test_fixnum_div
+ assert_equal 3, 15 / 5
+ end
+
+ def test_fixnum_mod
+ assert_equal 1, 8 % 7
+ end
+
+ def test_float_plus
+ assert_equal 4.0, 2.0 + 2.0
+ assert_equal 2.0, redefine_method('Float', '+') { 2.0 + 2.0 }
+ assert_equal 4.0, 2.0 + 2.0
+ end
+
+ def test_string_length
+ assert_equal 6, "string".length
+ assert_nil redefine_method('String', 'length') { "string".length }
+ assert_equal 6, "string".length
+ end
+
+ def test_string_plus
+ assert_equal "", "" + ""
+ assert_equal "x", "x" + ""
+ assert_equal "x", "" + "x"
+ assert_equal "ab", "a" + "b"
+ assert_equal 'b', redefine_method('String', '+') { "a" + "b" }
+ assert_equal "ab", "a" + "b"
+ end
+
+ def test_string_succ
+ assert_equal 'b', 'a'.succ
+ assert_equal 'B', 'A'.succ
+ end
+
+ def test_string_format
+ assert_equal '2', '%d' % 2
+ end
+
+ def test_array_plus
+ assert_equal [1,2], [1]+[2]
+ end
+
+ def test_array_minus
+ assert_equal [2], [1,2] - [1]
+ end
+
+ def test_array_length
+ assert_equal 0, [].length
+ assert_equal 3, [1,2,3].length
+ end
+
+ def test_hash_length
+ assert_equal 0, {}.length
+ assert_equal 1, {1=>1}.length
+ end
+
+ class MyObj
+ def ==(other)
+ true
+ end
+ end
+
+ def test_eq
+ assert_equal true, nil == nil
+ assert_equal true, 1 == 1
+ assert_equal true, 'string' == 'string'
+ assert_equal true, 1 == MyObj.new
+ assert_equal false, nil == MyObj.new
+ assert_equal true, MyObj.new == 1
+ assert_equal true, MyObj.new == nil
+ end
+
+end
diff --git a/trunk/test/ruby/test_pack.rb b/trunk/test/ruby/test_pack.rb
new file mode 100644
index 0000000000..30ffe13426
--- /dev/null
+++ b/trunk/test/ruby/test_pack.rb
@@ -0,0 +1,448 @@
+require 'test/unit'
+
+class TestPack < Test::Unit::TestCase
+ def test_pack
+ $format = "c2x5CCxsdils_l_a6";
+ # Need the expression in here to force ary[5] to be numeric. This avoids
+ # test2 failing because ary2 goes str->numeric->str and ary does not.
+ ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,-32767,-123456,"abcdef"]
+ $x = ary.pack($format)
+ ary2 = $x.unpack($format)
+
+ assert_equal(ary.length, ary2.length)
+ assert_equal(ary.join(':'), ary2.join(':'))
+ assert_match(/def/, $x)
+
+ $x = [-1073741825]
+ assert_equal($x, $x.pack("q").unpack("q"))
+
+ $x = [-1]
+ assert_equal($x, $x.pack("l").unpack("l"))
+ end
+
+ def test_pack_N
+ assert_equal "\000\000\000\000", [0].pack('N')
+ assert_equal "\000\000\000\001", [1].pack('N')
+ assert_equal "\000\000\000\002", [2].pack('N')
+ assert_equal "\000\000\000\003", [3].pack('N')
+ assert_equal "\377\377\377\376", [4294967294].pack('N')
+ assert_equal "\377\377\377\377", [4294967295].pack('N')
+
+ assert_equal "\200\000\000\000", [2**31].pack('N')
+ assert_equal "\177\377\377\377", [-2**31-1].pack('N')
+ assert_equal "\377\377\377\377", [-1].pack('N')
+
+ assert_equal "\000\000\000\001\000\000\000\001", [1,1].pack('N*')
+ assert_equal "\000\000\000\001\000\000\000\001\000\000\000\001", [1,1,1].pack('N*')
+ end
+
+ def test_unpack_N
+ assert_equal 1, "\000\000\000\001".unpack('N')[0]
+ assert_equal 2, "\000\000\000\002".unpack('N')[0]
+ assert_equal 3, "\000\000\000\003".unpack('N')[0]
+ assert_equal 3, "\000\000\000\003".unpack('N')[0]
+ assert_equal 4294967295, "\377\377\377\377".unpack('N')[0]
+ assert_equal [1,1], "\000\000\000\001\000\000\000\001".unpack('N*')
+ assert_equal [1,1,1], "\000\000\000\001\000\000\000\001\000\000\000\001".unpack('N*')
+ end
+
+ def test_pack_U
+ assert_raises(RangeError) { [-0x40000001].pack("U") }
+ assert_raises(RangeError) { [-0x40000000].pack("U") }
+ assert_raises(RangeError) { [-1].pack("U") }
+ assert_equal "\000", [0].pack("U")
+ assert_equal "\374\277\277\277\277\277", [0x3fffffff].pack("U")
+ assert_equal "\375\200\200\200\200\200", [0x40000000].pack("U")
+ assert_equal "\375\277\277\277\277\277", [0x7fffffff].pack("U")
+ assert_raises(RangeError) { [0x80000000].pack("U") }
+ assert_raises(RangeError) { [0x100000000].pack("U") }
+ end
+
+ def test_pack_P
+ a = ["abc"]
+ assert_equal a, a.pack("P").unpack("P*")
+ assert_equal "a", a.pack("P").unpack("P")[0]
+ assert_equal a, a.pack("P").freeze.unpack("P*")
+ assert_raise(ArgumentError) { (a.pack("P") + "").unpack("P*") }
+ end
+
+ def test_pack_p
+ a = ["abc"]
+ assert_equal a, a.pack("p").unpack("p*")
+ assert_equal a[0], a.pack("p").unpack("p")[0]
+ assert_equal a, a.pack("p").freeze.unpack("p*")
+ assert_raise(ArgumentError) { (a.pack("p") + "").unpack("p*") }
+ end
+
+ def test_format_string_modified
+ fmt = "CC"
+ o = Object.new
+ class << o; self; end.class_eval do
+ define_method(:to_int) { fmt.clear; 0 }
+ end
+ assert_raise(RuntimeError) do
+ [o, o].pack(fmt)
+ end
+ end
+
+ def test_comment
+ assert_equal("\0\1", [0,1].pack(" C #foo \n C "))
+ assert_equal([0,1], "\0\1".unpack(" C #foo \n C "))
+ end
+
+ def test_illegal_bang
+ assert_raise(ArgumentError) { [].pack("a!") }
+ assert_raise(ArgumentError) { "".unpack("a!") }
+ end
+
+ def test_pack_unpack_aA
+ assert_equal("f", ["foo"].pack("A"))
+ assert_equal("f", ["foo"].pack("a"))
+ assert_equal("foo", ["foo"].pack("A*"))
+ assert_equal("foo", ["foo"].pack("a*"))
+ assert_equal("fo", ["foo"].pack("A2"))
+ assert_equal("fo", ["foo"].pack("a2"))
+ assert_equal("foo ", ["foo"].pack("A4"))
+ assert_equal("foo\0", ["foo"].pack("a4"))
+ assert_equal(" ", [nil].pack("A"))
+ assert_equal("\0", [nil].pack("a"))
+ assert_equal("", [nil].pack("A*"))
+ assert_equal("", [nil].pack("a*"))
+ assert_equal(" ", [nil].pack("A2"))
+ assert_equal("\0\0", [nil].pack("a2"))
+
+ assert_equal("foo" + "\0" * 27, ["foo"].pack("a30"))
+
+ assert_equal(["f"], "foo\0".unpack("A"))
+ assert_equal(["f"], "foo\0".unpack("a"))
+ assert_equal(["foo"], "foo\0".unpack("A4"))
+ assert_equal(["foo\0"], "foo\0".unpack("a4"))
+ assert_equal(["foo"], "foo ".unpack("A4"))
+ assert_equal(["foo "], "foo ".unpack("a4"))
+ assert_equal(["foo"], "foo".unpack("A4"))
+ assert_equal(["foo"], "foo".unpack("a4"))
+ end
+
+ def test_pack_unpack_Z
+ assert_equal("f", ["foo"].pack("Z"))
+ assert_equal("foo\0", ["foo"].pack("Z*"))
+ assert_equal("fo", ["foo"].pack("Z2"))
+ assert_equal("foo\0\0", ["foo"].pack("Z5"))
+ assert_equal("\0", [nil].pack("Z"))
+ assert_equal("\0", [nil].pack("Z*"))
+ assert_equal("\0\0", [nil].pack("Z2"))
+
+ assert_equal(["f"], "foo\0".unpack("Z"))
+ assert_equal(["foo"], "foo".unpack("Z*"))
+ assert_equal(["foo"], "foo\0".unpack("Z*"))
+ assert_equal(["foo"], "foo".unpack("Z5"))
+ end
+
+ def test_pack_unpack_bB
+ assert_equal("\xff\x00", ["1111111100000000"].pack("b*"))
+ assert_equal("\x01\x02", ["1000000001000000"].pack("b*"))
+ assert_equal("", ["1"].pack("b0"))
+ assert_equal("\x01", ["1"].pack("b1"))
+ assert_equal("\x01\x00", ["1"].pack("b2"))
+ assert_equal("\x01\x00", ["1"].pack("b3"))
+ assert_equal("\x01\x00\x00", ["1"].pack("b4"))
+ assert_equal("\x01\x00\x00", ["1"].pack("b5"))
+ assert_equal("\x01\x00\x00\x00", ["1"].pack("b6"))
+
+ assert_equal("\xff\x00", ["1111111100000000"].pack("B*"))
+ assert_equal("\x01\x02", ["0000000100000010"].pack("B*"))
+ assert_equal("", ["1"].pack("B0"))
+ assert_equal("\x80", ["1"].pack("B1"))
+ assert_equal("\x80\x00", ["1"].pack("B2"))
+ assert_equal("\x80\x00", ["1"].pack("B3"))
+ assert_equal("\x80\x00\x00", ["1"].pack("B4"))
+ assert_equal("\x80\x00\x00", ["1"].pack("B5"))
+ assert_equal("\x80\x00\x00\x00", ["1"].pack("B6"))
+
+ assert_equal(["1111111100000000"], "\xff\x00".unpack("b*"))
+ assert_equal(["1000000001000000"], "\x01\x02".unpack("b*"))
+ assert_equal([""], "".unpack("b0"))
+ assert_equal(["1"], "\x01".unpack("b1"))
+ assert_equal(["10"], "\x01".unpack("b2"))
+ assert_equal(["100"], "\x01".unpack("b3"))
+
+ assert_equal(["1111111100000000"], "\xff\x00".unpack("B*"))
+ assert_equal(["0000000100000010"], "\x01\x02".unpack("B*"))
+ assert_equal([""], "".unpack("B0"))
+ assert_equal(["1"], "\x80".unpack("B1"))
+ assert_equal(["10"], "\x80".unpack("B2"))
+ assert_equal(["100"], "\x80".unpack("B3"))
+ end
+
+ def test_pack_unpack_hH
+ assert_equal("\x01\xfe", ["10ef"].pack("h*"))
+ assert_equal("", ["10ef"].pack("h0"))
+ assert_equal("\x01\x0e", ["10ef"].pack("h3"))
+ assert_equal("\x01\xfe\x0", ["10ef"].pack("h5"))
+
+ assert_equal("\x10\xef", ["10ef"].pack("H*"))
+ assert_equal("", ["10ef"].pack("H0"))
+ assert_equal("\x10\xe0", ["10ef"].pack("H3"))
+ assert_equal("\x10\xef\x0", ["10ef"].pack("H5"))
+
+ assert_equal(["10ef"], "\x01\xfe".unpack("h*"))
+ assert_equal([""], "\x01\xfe".unpack("h0"))
+ assert_equal(["1"], "\x01\xfe".unpack("h1"))
+ assert_equal(["10"], "\x01\xfe".unpack("h2"))
+ assert_equal(["10e"], "\x01\xfe".unpack("h3"))
+ assert_equal(["10ef"], "\x01\xfe".unpack("h4"))
+ assert_equal(["10ef"], "\x01\xfe".unpack("h5"))
+
+ assert_equal(["10ef"], "\x10\xef".unpack("H*"))
+ assert_equal([""], "\x10\xef".unpack("H0"))
+ assert_equal(["1"], "\x10\xef".unpack("H1"))
+ assert_equal(["10"], "\x10\xef".unpack("H2"))
+ assert_equal(["10e"], "\x10\xef".unpack("H3"))
+ assert_equal(["10ef"], "\x10\xef".unpack("H4"))
+ assert_equal(["10ef"], "\x10\xef".unpack("H5"))
+ end
+
+ def test_pack_unpack_cC
+ assert_equal("\0\1\xff", [0, 1, 255].pack("c*"))
+ assert_equal("\0\1\xff", [0, 1, -1].pack("c*"))
+
+ assert_equal("\0\1\xff", [0, 1, 255].pack("C*"))
+ assert_equal("\0\1\xff", [0, 1, -1].pack("C*"))
+
+ assert_equal([0, 1, -1], "\0\1\xff".unpack("c*"))
+
+ assert_equal([0, 1, 255], "\0\1\xff".unpack("C*"))
+ end
+
+ def test_pack_unpack_sS
+ s1 = [513, -514].pack("s*")
+ s2 = [513, 65022].pack("S*")
+ assert_equal(s1, s2)
+ assert_equal([513, -514], s2.unpack("s*"))
+ assert_equal([513, 65022], s1.unpack("S*"))
+
+ s1 = [513, -514].pack("s!*")
+ s2 = [513, 65022].pack("S!*")
+ assert_equal(s1, s2)
+ assert_equal([513, -514], s2.unpack("s!*"))
+ assert_equal([513, 65022], s1.unpack("S!*"))
+ end
+
+ def test_pack_unpack_iI
+ s1 = [67305985, -50462977].pack("i*")
+ s2 = [67305985, 4244504319].pack("I*")
+ assert_equal(s1, s2)
+ assert_equal([67305985, -50462977], s2.unpack("i*"))
+ assert_equal([67305985, 4244504319], s1.unpack("I*"))
+
+ s1 = [67305985, -50462977].pack("i!*")
+ s2 = [67305985, 4244504319].pack("I!*")
+ assert_equal([67305985, -50462977], s1.unpack("i!*"))
+ assert_equal([67305985, 4244504319], s2.unpack("I!*"))
+ end
+
+ def test_pack_unpack_lL
+ s1 = [67305985, -50462977].pack("l*")
+ s2 = [67305985, 4244504319].pack("L*")
+ assert_equal(s1, s2)
+ assert_equal([67305985, -50462977], s2.unpack("l*"))
+ assert_equal([67305985, 4244504319], s1.unpack("L*"))
+
+ s1 = [67305985, -50462977].pack("l!*")
+ s2 = [67305985, 4244504319].pack("L!*")
+ assert_equal([67305985, -50462977], s1.unpack("l!*"))
+ assert_equal([67305985, 4244504319], s2.unpack("L!*"))
+ end
+
+ def test_pack_unpack_qQ
+ s1 = [578437695752307201, -506097522914230529].pack("q*")
+ s2 = [578437695752307201, 17940646550795321087].pack("Q*")
+ assert_equal(s1, s2)
+ assert_equal([578437695752307201, -506097522914230529], s2.unpack("q*"))
+ assert_equal([578437695752307201, 17940646550795321087], s1.unpack("Q*"))
+ end
+
+ def test_pack_unpack_nN
+ assert_equal("\000\000\000\001\377\377\177\377\200\000\377\377", [0,1,-1,32767,-32768,65535].pack("n*"))
+ assert_equal("\000\000\000\000\000\000\000\001\377\377\377\377", [0,1,-1].pack("N*"))
+
+ assert_equal([0,1,65535,32767,32768,65535], "\000\000\000\001\377\377\177\377\200\000\377\377".unpack("n*"))
+ assert_equal([0,1,4294967295], "\000\000\000\000\000\000\000\001\377\377\377\377".unpack("N*"))
+ end
+
+ def test_pack_unpack_vV
+ assert_equal("\000\000\001\000\377\377\377\177\000\200\377\377", [0,1,-1,32767,-32768,65535].pack("v*"))
+ assert_equal("\000\000\000\000\001\000\000\000\377\377\377\377", [0,1,-1].pack("V*"))
+
+ assert_equal([0,1,65535,32767,32768,65535], "\000\000\001\000\377\377\377\177\000\200\377\377".unpack("v*"))
+ assert_equal([0,1,4294967295], "\000\000\000\000\001\000\000\000\377\377\377\377".unpack("V*"))
+ end
+
+ def test_pack_unpack_fdeEgG
+ inf = 1.0/0.0
+ nan = inf/inf
+ [0.0, 1.0, 3.0, inf, -inf, nan].each do |x|
+ %w(f d e E g G).each do |f|
+ v = [x].pack(f).unpack(f)
+ if x.nan?
+ assert(v.first.nan?)
+ else
+ assert_equal([x], v)
+ end
+ end
+ end
+ end
+
+ def test_pack_unpack_x
+ assert_equal("", [].pack("x0"))
+ assert_equal("\0", [].pack("x"))
+ assert_equal("\0" * 30, [].pack("x30"))
+
+ assert_equal([0, 2], "\x00\x00\x02".unpack("CxC"))
+ assert_raise(ArgumentError) { "".unpack("x") }
+ end
+
+ def test_pack_unpack_X
+ assert_equal("\x00\x02", [0, 1, 2].pack("CCXC"))
+ assert_equal("\x02", [0, 1, 2].pack("CCX2C"))
+ assert_raise(ArgumentError) { [].pack("X") }
+
+ assert_equal([0, 2, 2], "\x00\x02".unpack("CCXC"))
+ assert_raise(ArgumentError) { "".unpack("X") }
+ end
+
+ def test_pack_unpack_atmark
+ assert_equal("\x01\x00\x00\x02", [1, 2].pack("C@3C"))
+ assert_equal("\x02", [1, 2].pack("C@0C"))
+ assert_equal("\x01\x02", [1, 2].pack("C@1C"))
+
+ assert_equal([1, 2], "\x01\x00\x00\x02".unpack("C@3C"))
+ assert_equal([nil], "\x00".unpack("@1C")) # is it OK?
+ assert_raise(ArgumentError) { "\x00".unpack("@2C") }
+ end
+
+ def test_pack_unpack_percent
+ assert_raise(ArgumentError) { [].pack("%") }
+ assert_raise(ArgumentError) { "".unpack("%") }
+ end
+
+ def test_pack_unpack_U
+ assert_equal([0], [0].pack("U").unpack("U"))
+ assert_equal([0x80], [0x80].pack("U").unpack("U"))
+ assert_equal([0x800], [0x800].pack("U").unpack("U"))
+ assert_equal([0x10000], [0x10000].pack("U").unpack("U"))
+ assert_equal([0x400000], [0x400000].pack("U").unpack("U"))
+
+ assert_raise(ArgumentError) { "\x80".unpack("U") }
+ assert_raise(ArgumentError) { "\xff".unpack("U") }
+ assert_raise(ArgumentError) { "\xfc\x00".unpack("U") }
+ assert_raise(ArgumentError) { "\xc0\xc0".unpack("U") }
+ assert_raise(ArgumentError) { "\xe0\x80\x80".unpack("U") }
+ end
+
+ def test_pack_unpack_u
+ assert_equal("", [""].pack("u"))
+ assert_equal("!80``\n", ["a"].pack("u"))
+ assert_equal("#86)C\n", ["abc"].pack("u"))
+ assert_equal("$86)C9```\n", ["abcd"].pack("u"))
+ assert_equal("M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n", ["a"*45].pack("u"))
+ assert_equal("M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n!80``\n", ["a"*46].pack("u"))
+ assert_equal("&86)C9&5F\n#9VAI\n", ["abcdefghi"].pack("u6"))
+
+ assert_equal([""], "".unpack("u"))
+ assert_equal(["a"], "!80``\n".unpack("u"))
+ assert_equal(["abc"], "#86)C\n".unpack("u"))
+ assert_equal(["abcd"], "$86)C9```\n".unpack("u"))
+ assert_equal(["a"*45], "M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n".unpack("u"))
+ assert_equal(["a"*46], "M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A\n!80``\n".unpack("u"))
+ assert_equal(["abcdefghi"], "&86)C9&5F\n#9VAI\n".unpack("u"))
+
+ assert_equal(["\x00"], "\"\n".unpack("u"))
+ assert_equal(["\x00"], "! \r \n".unpack("u"))
+ end
+
+ def test_pack_unpack_m
+ assert_equal("", [""].pack("m"))
+ assert_equal("AA==\n", ["\0"].pack("m"))
+ assert_equal("AAA=\n", ["\0\0"].pack("m"))
+ assert_equal("AAAA\n", ["\0\0\0"].pack("m"))
+ assert_equal("/w==\n", ["\377"].pack("m"))
+ assert_equal("//8=\n", ["\377\377"].pack("m"))
+ assert_equal("////\n", ["\377\377\377"].pack("m"))
+
+ assert_equal([""], "".unpack("m"))
+ assert_equal(["\0"], "AA==\n".unpack("m"))
+ assert_equal(["\0\0"], "AAA=\n".unpack("m"))
+ assert_equal(["\0\0\0"], "AAAA\n".unpack("m"))
+ assert_equal(["\377"], "/w==\n".unpack("m"))
+ assert_equal(["\377\377"], "//8=\n".unpack("m"))
+ assert_equal(["\377\377\377"], "////\n".unpack("m"))
+ end
+
+ def test_pack_unpack_M
+ assert_equal("a b c\td =\n\ne=\n", ["a b c\td \ne"].pack("M"))
+ assert_equal(["a b c\td \ne"], "a b c\td =\n\ne=\n".unpack("M"))
+ assert_equal("=00=\n", ["\0"].pack("M"))
+ assert_equal("a"*73+"=\na=\n", ["a"*74].pack("M"))
+ assert_equal(("a"*73+"=\n")*14+"a=\n", ["a"*1023].pack("M"))
+ assert_equal(["\0"], "=00=\n".unpack("M"))
+ assert_equal(["a"*74], ("a"*73+"=\na=\n").unpack("M"))
+ assert_equal(["a"*1023], (("a"*73+"=\n")*14+"a=\n").unpack("M"))
+ assert_equal(["\x0a"], "=0a=\n".unpack("M"))
+ assert_equal(["\x0a"], "=0A=\n".unpack("M"))
+ assert_equal([""], "=0Z=\n".unpack("M"))
+ assert_equal([""], "=\r\n".unpack("M"))
+ end
+
+ def test_pack_unpack_P2
+ assert_raise(ArgumentError) { ["abc"].pack("P4") }
+ assert_raise(ArgumentError) { [""].pack("P") }
+
+ assert_equal([], ".".unpack("P"))
+ assert_equal([], ".".unpack("p"))
+ assert_equal([nil], ("\0" * 1024).unpack("P"))
+ end
+
+ def test_pack_p2
+ assert([nil].pack("p") =~ /\A\0*\Z/)
+ end
+
+ def test_pack_unpack_w
+ assert_equal("\000", [0].pack("w"))
+ assert_equal("\001", [1].pack("w"))
+ assert_equal("\177", [127].pack("w"))
+ assert_equal("\201\000", [128].pack("w"))
+ assert_equal("\377\177", [0x3fff].pack("w"))
+ assert_equal("\201\200\000", [0x4000].pack("w"))
+ assert_equal("\203\377\377\377\177", [0x3fffffff].pack("w"))
+ assert_equal("\204\200\200\200\000", [0x40000000].pack("w"))
+ assert_equal("\217\377\377\377\177", [0xffffffff].pack("w"))
+ assert_equal("\220\200\200\200\000", [0x100000000].pack("w"))
+ assert_raise(ArgumentError) { [-1].pack("w") }
+
+ assert_equal([0], "\000".unpack("w"))
+ assert_equal([1], "\001".unpack("w"), [1])
+ assert_equal([127], "\177".unpack("w"), [127])
+ assert_equal([128], "\201\000".unpack("w"), [128])
+ assert_equal([0x3fff], "\377\177".unpack("w"), [0x3fff])
+ assert_equal([0x4000], "\201\200\000".unpack("w"), [0x4000])
+ assert_equal([0x3fffffff], "\203\377\377\377\177".unpack("w"), [0x3fffffff])
+ assert_equal([0x40000000], "\204\200\200\200\000".unpack("w"), [0x40000000])
+ assert_equal([0xffffffff], "\217\377\377\377\177".unpack("w"), [0xffffffff])
+ assert_equal([0x100000000], "\220\200\200\200\000".unpack("w"), [0x100000000])
+ end
+
+ def test_modify_under_safe4
+ s = "foo"
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ s.clear
+ end.join
+ end
+ end
+
+ def test_length_too_big
+ assert_raise(RangeError) { [].pack("C100000000000000000000") }
+ end
+end
diff --git a/trunk/test/ruby/test_parse.rb b/trunk/test/ruby/test_parse.rb
new file mode 100644
index 0000000000..e372ff6367
--- /dev/null
+++ b/trunk/test/ruby/test_parse.rb
@@ -0,0 +1,826 @@
+require 'test/unit'
+require 'stringio'
+
+class TestParse < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_else_without_rescue
+ x = eval <<-END
+ begin
+ else
+ 42
+ end
+ END
+ assert_equal(42, x)
+ end
+
+ def test_alias_backref
+ assert_raise(SyntaxError) do
+ eval <<-END
+ alias $foo $1
+ END
+ end
+ end
+
+ def test_command_call
+ t = Object.new
+ def t.foo(x); x; end
+
+ a = false
+ b = c = d = true
+ assert_nothing_raised do
+ eval <<-END
+ a &&= t.foo 42
+ b &&= t.foo 42
+ c &&= t.foo nil
+ d &&= t.foo false
+ END
+ end
+ assert_equal([false, 42, nil, false], [a, b, c, d])
+
+ a = 3
+ assert_nothing_raised { eval("a &= t.foo 5") }
+ assert_equal(1, a)
+
+ a = [nil, nil, true, true]
+ assert_nothing_raised do
+ eval <<-END
+ a[0] ||= t.foo 42
+ a[1] &&= t.foo 42
+ a[2] ||= t.foo 42
+ a[3] &&= t.foo 42
+ END
+ end
+ assert_equal([42, nil, true, 42], a)
+
+ o = Object.new
+ class << o
+ attr_accessor :foo, :bar, :Foo, :Bar, :baz, :qux
+ end
+ o.foo = o.Foo = o::baz = nil
+ o.bar = o.Bar = o::qux = 1
+ assert_nothing_raised do
+ eval <<-END
+ o.foo ||= t.foo 42
+ o.bar &&= t.foo 42
+ o.Foo ||= t.foo 42
+ o.Bar &&= t.foo 42
+ o::baz ||= t.foo 42
+ o::qux &&= t.foo 42
+ END
+ end
+ assert_equal([42, 42], [o.foo, o.bar])
+ assert_equal([42, 42], [o.Foo, o.Bar])
+ assert_equal([42, 42], [o::baz, o::qux])
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ $1 ||= t.foo 42
+ END
+ end
+
+ def t.bar(x); x + yield; end
+
+ a = b = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = t.bar "foo" do
+ "bar"
+ end.gsub "ob", "OB"
+ b = t.bar "foo" do
+ "bar"
+ end::gsub "ob", "OB"
+ END
+ end
+ assert_equal("foOBar", a)
+ assert_equal("foOBar", b)
+
+ a = nil
+ assert_nothing_raised do
+ t.instance_eval <<-END
+ a = bar "foo" { "bar" }
+ END
+ end
+ assert_equal("foobar", a)
+
+ a = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = t::bar "foo" { "bar" }
+ END
+ end
+ assert_equal("foobar", a)
+
+ def t.baz(*r)
+ @baz = r + (block_given? ? [yield] : [])
+ end
+
+ assert_nothing_raised do
+ t.instance_eval "baz (1), 2"
+ end
+ assert_equal([1, 2], t.instance_eval { @baz })
+ end
+
+ def test_mlhs_node
+ c = Class.new
+ class << c
+ attr_accessor :foo, :bar, :Foo, :Bar
+ FOO = BAR = nil
+ end
+
+ assert_nothing_raised do
+ eval <<-END
+ c::foo, c::bar = 1, 2
+ c.Foo, c.Bar = 1, 2
+ c::FOO, c::BAR = 1, 2
+ END
+ end
+ assert_equal([1, 2], [c::foo, c::bar])
+ assert_equal([1, 2], [c.Foo, c.Bar])
+ assert_equal([1, 2], [c::FOO, c::BAR])
+ end
+
+ def test_dynamic_constant_assignment
+ assert_raise(SyntaxError) do
+ Object.new.instance_eval <<-END
+ def foo
+ self::FOO, self::BAR = 1, 2
+ ::FOO, ::BAR = 1, 2
+ end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ $1, $2 = 1, 2
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ Object.new.instance_eval <<-END
+ def foo
+ ::FOO = 1
+ end
+ END
+ end
+
+ c = Class.new
+ assert_raise(SyntaxError) do
+ eval <<-END
+ c::FOO &= 1
+ ::FOO &= 1
+ END
+ end
+
+ c = Class.new
+ assert_raise(SyntaxError) do
+ eval <<-END
+ $1 &= 1
+ END
+ end
+ end
+
+ def test_class_module
+ assert_raise(SyntaxError) do
+ eval <<-END
+ class foo; end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo
+ class Foo; end
+ module Bar; end
+ end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ class Foo Bar; end
+ END
+ end
+ end
+
+ def test_op_name
+ o = Object.new
+ def o.>(x); x; end
+ def o./(x); x; end
+
+ a = nil
+ assert_nothing_raised do
+ o.instance_eval <<-END
+ undef >, /
+ END
+ end
+ end
+
+ def test_arg
+ o = Object.new
+ class << o
+ attr_accessor :foo, :bar, :Foo, :Bar, :baz, :qux
+ end
+ o.foo = o.Foo = o::baz = nil
+ o.bar = o.Bar = o::qux = 1
+ assert_nothing_raised do
+ eval <<-END
+ o.foo ||= 42
+ o.bar &&= 42
+ o.Foo ||= 42
+ o.Bar &&= 42
+ o::baz ||= 42
+ o::qux &&= 42
+ END
+ end
+ assert_equal([42, 42], [o.foo, o.bar])
+ assert_equal([42, 42], [o.Foo, o.Bar])
+ assert_equal([42, 42], [o::baz, o::qux])
+
+ a = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = -2.0 ** 2
+ END
+ end
+ assert_equal(-4.0, a)
+ end
+
+ def test_block_variable
+ o = Object.new
+ def o.foo(*r); yield(*r); end
+
+ a = nil
+ assert_nothing_raised do
+ eval <<-END
+ o.foo 1 {|; a| a = 42 }
+ END
+ end
+ assert_nil(a)
+ end
+
+ def test_bad_arg
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo(FOO); end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo(@foo); end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo($foo); end
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo(@@foo); end
+ END
+ end
+
+ o = Object.new
+ def o.foo(*r); yield(*r); end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ o.foo 1 {|; @a| @a = 42 }
+ END
+ end
+ end
+
+ def test_do_lambda
+ a = b = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = -> do
+ b = 42
+ end
+ END
+ end
+ a.call
+ assert_equal(42, b)
+ end
+
+ def test_block_call_colon2
+ o = Object.new
+ def o.foo(x); x + yield; end
+
+ a = b = nil
+ assert_nothing_raised do
+ o.instance_eval <<-END
+ a = foo 1 do 42 end.to_s
+ b = foo 1 do 42 end::to_s
+ END
+ end
+ assert_equal("43", a)
+ assert_equal("43", b)
+ end
+
+ def test_call_method
+ a = b = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = proc {|x| x + "bar" }.("foo")
+ b = proc {|x| x + "bar" }::("foo")
+ END
+ end
+ assert_equal("foobar", a)
+ assert_equal("foobar", b)
+ end
+
+ def test_xstring
+ assert_raise(Errno::ENOENT) do
+ eval("``")
+ end
+ end
+
+ def test_words
+ assert_equal([], %W( ))
+ end
+
+ def test_dstr
+ @@foo = 1
+ assert_equal("foo 1 bar", "foo #@@foo bar")
+ "1" =~ /(.)/
+ assert_equal("foo 1 bar", "foo #$1 bar")
+ end
+
+ def test_dsym
+ assert_nothing_raised { eval(':""') }
+ end
+
+ def test_arg2
+ o = Object.new
+
+ assert_nothing_raised do
+ eval <<-END
+ def o.foo(a=42,*r,z,&b); b.call(r.inject(a*1000+z*100, :+)); end
+ END
+ end
+ assert_equal(-1405, o.foo(1,2,3,4) {|x| -x })
+ assert_equal(-1302, o.foo(1,2,3) {|x| -x })
+ assert_equal(-1200, o.foo(1,2) {|x| -x })
+ assert_equal(-42100, o.foo(1) {|x| -x })
+ assert_raise(ArgumentError) { o.foo() }
+
+ assert_nothing_raised do
+ eval <<-END
+ def o.foo(a=42,z,&b); b.call(a*1000+z*100); end
+ END
+ end
+ assert_equal(-1200, o.foo(1,2) {|x| -x } )
+ assert_equal(-42100, o.foo(1) {|x| -x } )
+ assert_raise(ArgumentError) { o.foo() }
+
+ assert_nothing_raised do
+ eval <<-END
+ def o.foo(*r,z,&b); b.call(r.inject(z*100, :+)); end
+ END
+ end
+ assert_equal(-303, o.foo(1,2,3) {|x| -x } )
+ assert_equal(-201, o.foo(1,2) {|x| -x } )
+ assert_equal(-100, o.foo(1) {|x| -x } )
+ assert_raise(ArgumentError) { o.foo() }
+ end
+
+ def test_duplicate_argument
+ assert_raise(SyntaxError) do
+ eval <<-END
+ 1.times {|&b?| }
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ 1.times {|a, a|}
+ END
+ end
+
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo(a, a); end
+ END
+ end
+ end
+
+ def test_define_singleton_error
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def ("foo").foo; end
+ END
+ end
+ end
+
+ def test_backquote
+ t = Object.new
+
+ assert_nothing_raised do
+ eval <<-END
+ def t.`(x); "foo" + x + "bar"; end
+ END
+ end
+ a = b = nil
+ assert_nothing_raised do
+ eval <<-END
+ a = t.` "zzz"
+ 1.times {|;z| t.` ("zzz") }
+ END
+ t.instance_eval <<-END
+ b = `zzz`
+ END
+ end
+ assert_equal("foozzzbar", a)
+ assert_equal("foozzzbar", b)
+ end
+
+ def test_carrige_return
+ assert_equal(2, eval("1 +\r\n1"))
+ end
+
+ def test_string
+ assert_raise(SyntaxError) do
+ eval '"\xg1"'
+ end
+
+ assert_raise(SyntaxError) do
+ eval '"\u{1234"'
+ end
+
+ assert_raise(SyntaxError) do
+ eval '"\M1"'
+ end
+
+ assert_raise(SyntaxError) do
+ eval '"\C1"'
+ end
+
+ assert_equal("\x81", eval('"\C-\M-a"'))
+ assert_equal("\177", eval('"\c?"'))
+ end
+
+ def test_question
+ assert_raise(SyntaxError) { eval('?') }
+ assert_raise(SyntaxError) { eval('? ') }
+ assert_raise(SyntaxError) { eval("?\n") }
+ assert_raise(SyntaxError) { eval("?\t") }
+ assert_raise(SyntaxError) { eval("?\v") }
+ assert_raise(SyntaxError) { eval("?\r") }
+ assert_raise(SyntaxError) { eval("?\f") }
+ assert_equal("\u{1234}", eval("?\u{1234}"))
+ assert_equal("\u{1234}", eval('?\u{1234}'))
+ end
+
+ def test_percent
+ assert_equal(:foo, eval('%s(foo)'))
+ assert_raise(SyntaxError) { eval('%s') }
+ assert_raise(SyntaxError) { eval('%ss') }
+ assert_raise(SyntaxError) { eval('%z()') }
+ end
+
+ def test_symbol
+ assert_raise(SyntaxError) do
+ eval ":'foo\0bar'"
+ end
+ assert_raise(SyntaxError) do
+ eval ':"foo\u0000bar"'
+ end
+ assert_raise(SyntaxError) do
+ eval ':"foo\u{0}bar"'
+ end
+ assert_raise(SyntaxError) do
+ eval ':"foo\u{}bar"'
+ end
+ end
+
+ def test_parse_string
+ assert_raise(SyntaxError) do
+ eval <<-END
+/
+ END
+ end
+ end
+
+ def test_here_document
+ x = nil
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<FOO
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<FOO
+#$
+FOO
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<"
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<``
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<--
+ )
+ end
+
+ assert_raise(SyntaxError) do
+ eval %q(
+<<FOO
+#$
+foo
+FOO
+ )
+ end
+
+ assert_nothing_raised do
+ eval "x = <<FOO\r\n1\r\nFOO"
+ end
+ assert_equal("1\n", x)
+ end
+
+ def test_magic_comment
+ x = nil
+ assert_nothing_raised do
+ eval <<-END
+# coding = utf-8
+x = __ENCODING__
+ END
+ end
+ assert_equal(Encoding.find("UTF-8"), x)
+
+ assert_raise(ArgumentError) do
+ eval <<-END
+# coding = foobarbazquxquux_dummy_enconding
+x = __ENCODING__
+ END
+ end
+ end
+
+ def test_utf8_bom
+ x = nil
+ assert_nothing_raised do
+ eval "\xef\xbb\xbf x = __ENCODING__"
+ end
+ assert_equal(Encoding.find("UTF-8"), x)
+ assert_raise(NameError) { eval "\xef" }
+ end
+
+ def test_dot_in_next_line
+ x = nil
+ assert_nothing_raised do
+ eval <<-END
+ x = 1
+ .to_s
+ END
+ end
+ assert_equal("1", x)
+ end
+
+ def test_pow_asgn
+ x = 3
+ assert_nothing_raised { eval("x **= 2") }
+ assert_equal(9, x)
+ end
+
+ def test_embedded_rd
+ assert_raise(SyntaxError) do
+ eval <<-END
+=begin
+ END
+ end
+ end
+
+ def test_float
+ assert_equal(1.0/0, eval("1e10000"))
+ assert_raise(SyntaxError) { eval('1_E') }
+ assert_raise(SyntaxError) { eval('1E1E1') }
+ end
+
+ def test_global_variable
+ assert_equal(nil, eval('$-x'))
+ assert_equal(nil, eval('alias $preserve_last_match $&'))
+ assert_equal(nil, eval('alias $& $test_parse_foobarbazqux'))
+ $test_parse_foobarbazqux = nil
+ assert_equal(nil, $&)
+ assert_equal(nil, eval('alias $& $preserve_last_match'))
+ assert_raise(SyntaxError) { eval('$#') }
+ end
+
+ def test_invalid_instance_variable
+ assert_raise(SyntaxError) { eval('@#') }
+ end
+
+ def test_invalid_class_variable
+ assert_raise(SyntaxError) { eval('@@1') }
+ end
+
+ def test_invalid_char
+ x = 1
+ assert_equal(1, eval("\x01x"))
+ assert_equal(nil, eval("\x04x"))
+ end
+
+ def test_literal_concat
+ x = "baz"
+ assert_equal("foobarbaz", eval('"foo" "bar#{x}"'))
+ end
+
+ def test_unassignable
+ assert_raise(SyntaxError) do
+ eval %q(self = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(nil = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(true = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(false = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(__FILE__ = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(__LINE__ = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval %q(__ENCODING__ = 1)
+ end
+ assert_raise(SyntaxError) do
+ eval <<-END
+ def foo
+ FOO = 1
+ end
+ END
+ end
+ end
+
+ def test_block_dup
+ assert_raise(SyntaxError) do
+ eval <<-END
+ foo(&proc{}) {}
+ END
+ end
+ end
+
+ def test_set_backref
+ assert_raise(SyntaxError) do
+ eval <<-END
+ $& = 1
+ END
+ end
+ end
+
+ def test_arg_concat
+ o = Object.new
+ class << o; self; end.instance_eval do
+ define_method(:[]=) {|*r, &b| b.call(r) }
+ end
+ r = nil
+ assert_nothing_raised do
+ eval <<-END
+ o[&proc{|x| r = x }] = 1
+ END
+ end
+ assert_equal([1], r)
+ end
+
+ def test_void_expr_stmts_value
+ # This test checks if void contexts are warned correctly.
+ # Thus, warnings MUST NOT be suppressed.
+ $VERBOSE = true
+ stderr = $stderr
+ $stderr = StringIO.new("")
+ x = 1
+ assert_nil eval("x; nil")
+ assert_nil eval("1+1; nil")
+ assert_nil eval("TestParse; nil")
+ assert_nil eval("::TestParse; nil")
+ assert_nil eval("x..x; nil")
+ assert_nil eval("x...x; nil")
+ assert_nil eval("self; nil")
+ assert_nil eval("nil; nil")
+ assert_nil eval("true; nil")
+ assert_nil eval("false; nil")
+ assert_nil eval("defined?(1); nil")
+
+ assert_raise(SyntaxError) do
+ eval %q(1; next; 2)
+ end
+
+ o = Object.new
+ assert_nothing_raised do
+ eval <<-END
+ x = def o.foo; end
+ END
+ end
+ assert_equal($stderr.string.lines.to_a.size, 14)
+ $stderr = stderr
+ end
+
+ def test_assign_in_conditional
+ assert_raise(SyntaxError) do
+ eval <<-END
+ (x, y = 1, 2) ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ eval <<-END
+ if @x = true
+ 1
+ else
+ 2
+ end
+ END
+ end
+ end
+
+ def test_literal_in_conditional
+ assert_nothing_raised do
+ eval <<-END
+ "foo" ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ x = "bar"
+ eval <<-END
+ /foo#{x}baz/ ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ eval <<-END
+ (true..false) ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ eval <<-END
+ ("foo".."bar") ? 1 : 2
+ END
+ end
+
+ assert_nothing_raised do
+ x = "bar"
+ eval <<-END
+ :"foo#{"x"}baz" ? 1 : 2
+ END
+ end
+ end
+
+ def test_no_blockarg
+ assert_raise(SyntaxError) do
+ eval <<-END
+ yield(&:+)
+ END
+ end
+ end
+
+ def test_intern
+ assert_equal(':""', ''.intern.inspect)
+ assert_equal(':$foo', '$foo'.intern.inspect)
+ assert_equal(':"!foo"', '!foo'.intern.inspect)
+ assert_equal(':"foo=="', "foo==".intern.inspect)
+ end
+
+ def test_all_symbols
+ x = Symbol.all_symbols
+ assert_kind_of(Array, x)
+ assert(x.all? {|s| s.is_a?(Symbol) })
+ end
+
+ def test_is_class_id
+ c = Class.new
+ assert_raise(NameError) do
+ c.instance_eval { remove_class_variable(:@var) }
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_path.rb b/trunk/test/ruby/test_path.rb
new file mode 100644
index 0000000000..18c701f033
--- /dev/null
+++ b/trunk/test/ruby/test_path.rb
@@ -0,0 +1,224 @@
+require 'test/unit'
+
+class TestPath < Test::Unit::TestCase
+ def test_path
+ assert_equal("a", File.basename("a"))
+ assert_equal("b", File.basename("a/b"))
+ assert_equal("b", File.basename("a/b/"))
+ assert_equal("/", File.basename("/"))
+ assert_equal("/", File.basename("//"))
+ assert_equal("/", File.basename("///"))
+ assert_equal("b", File.basename("a/b////"))
+ assert_equal("a", File.basename("a.rb", ".rb"))
+ assert_equal("a", File.basename("a.rb///", ".rb"))
+ assert_equal("a", File.basename("a.rb///", ".*"))
+ assert_equal("a.rb", File.basename("a.rb///", ".c"))
+ assert_equal(".", File.dirname("a"))
+ assert_equal("/", File.dirname("/"))
+ assert_equal("/", File.dirname("/a"))
+ assert_equal("a", File.dirname("a/b"))
+ assert_equal("a/b", File.dirname("a/b/c"))
+ assert_equal("/a/b", File.dirname("/a/b/c"))
+ assert_equal("/a", File.dirname("/a/b/"))
+ assert_equal("/a", File.dirname("/a/b///"))
+ case Dir.pwd
+ when %r'\A\w:'
+ assert_match(/\A\w:\/\z/, File.expand_path(".", "/"))
+ assert_match(/\A\w:\/a\z/, File.expand_path("a", "/"))
+ dosish = true
+ when %r'\A//'
+ assert_match(%r'\A//[^/]+/[^/]+\z', File.expand_path(".", "/"))
+ assert_match(%r'\A//[^/]+/[^/]+/a\z', File.expand_path(".", "/"))
+ dosish = true
+ else
+ assert_equal("/", File.expand_path(".", "/"))
+ assert_equal("/sub", File.expand_path("sub", "/"))
+ end
+ if dosish
+ assert_equal("//machine/share", File.expand_path("/", "//machine/share/sub"))
+ assert_equal("//machine/share/dir", File.expand_path("/dir", "//machine/share/sub"))
+ assert_equal("z:/", File.expand_path("/", "z:/sub"))
+ assert_equal("z:/dir", File.expand_path("/dir", "z:/sub"))
+ end
+ assert_equal("//", File.expand_path(".", "//"))
+ assert_equal("//sub", File.expand_path("sub", "//"))
+ end
+
+ def test_dirname
+ if /(bcc|ms)win\d|mingw|cygwin|djgpp|human|emx/ =~ RUBY_PLATFORM
+ # DOSISH_DRIVE_LETTER
+ assert_equal('C:.', File.dirname('C:'))
+ assert_equal('C:.', File.dirname('C:a'))
+ assert_equal('C:.', File.dirname('C:a/'))
+ assert_equal('C:a', File.dirname('C:a/b'), "[ruby-dev:27738]")
+
+ assert_equal('C:/', File.dirname('C:/'))
+ assert_equal('C:/', File.dirname('C:/a'))
+ assert_equal('C:/', File.dirname('C:/a/'))
+ assert_equal('C:/a', File.dirname('C:/a/b'))
+
+ assert_equal('C:/', File.dirname('C://'))
+ assert_equal('C:/', File.dirname('C://a'))
+ assert_equal('C:/', File.dirname('C://a/'))
+ assert_equal('C:/a', File.dirname('C://a/b'))
+
+ assert_equal('C:/', File.dirname('C:///'), "[ruby-dev:27738]")
+ assert_equal('C:/', File.dirname('C:///a'))
+ assert_equal('C:/', File.dirname('C:///a/'))
+ assert_equal('C:/a', File.dirname('C:///a/b'))
+ else
+ # others
+ assert_equal('.', File.dirname('C:'))
+ assert_equal('.', File.dirname('C:a'))
+ assert_equal('.', File.dirname('C:a/'))
+ assert_equal('C:a', File.dirname('C:a/b'))
+
+ assert_equal('.', File.dirname('C:/'))
+ assert_equal('C:', File.dirname('C:/a'))
+ assert_equal('C:', File.dirname('C:/a/'))
+ assert_equal('C:/a', File.dirname('C:/a/b'))
+
+ assert_equal('.', File.dirname('C://'))
+ assert_equal('C:', File.dirname('C://a'))
+ assert_equal('C:', File.dirname('C://a/'))
+ # not spec.
+ #assert_equal('C://a', File.dirname('C://a/b'))
+
+ assert_equal('.', File.dirname('C:///'))
+ assert_equal('C:', File.dirname('C:///a'))
+ assert_equal('C:', File.dirname('C:///a/'))
+ # not spec.
+ #assert_equal('C:///a', File.dirname('C:///a/b'))
+ end
+
+ assert_equal('.', File.dirname(''))
+ assert_equal('.', File.dirname('a'))
+ assert_equal('.', File.dirname('a/'))
+ assert_equal('a', File.dirname('a/b'))
+
+ assert_equal('/', File.dirname('/'))
+ assert_equal('/', File.dirname('/a'))
+ assert_equal('/', File.dirname('/a/'))
+ assert_equal('/a', File.dirname('/a/b'))
+
+ if /(bcc|ms|cyg)win|mingw|djgpp|human|emx/ =~ RUBY_PLATFORM
+ # DOSISH_UNC
+ assert_equal('//', File.dirname('//'))
+ assert_equal('//a', File.dirname('//a'))
+ assert_equal('//a', File.dirname('//a/'))
+ assert_equal('//a/b', File.dirname('//a/b'))
+ assert_equal('//a/b', File.dirname('//a/b/'))
+ assert_equal('//a/b', File.dirname('//a/b/c'))
+
+ assert_equal('//', File.dirname('///'))
+ assert_equal('//a', File.dirname('///a'))
+ assert_equal('//a', File.dirname('///a/'))
+ assert_equal('//a/b', File.dirname('///a/b'))
+ assert_equal('//a/b', File.dirname('///a/b/'))
+ assert_equal('//a/b', File.dirname('///a/b/c'))
+ else
+ # others
+ assert_equal('/', File.dirname('//'))
+ assert_equal('/', File.dirname('//a'))
+ assert_equal('/', File.dirname('//a/'))
+ assert_equal('/a', File.dirname('//a/b'))
+ assert_equal('/a', File.dirname('//a/b/'))
+ assert_equal('/a/b', File.dirname('//a/b/c'))
+
+ assert_equal('/', File.dirname('///'))
+ assert_equal('/', File.dirname('///a'))
+ assert_equal('/', File.dirname('///a/'))
+ assert_equal('/a', File.dirname('///a/b'))
+ assert_equal('/a', File.dirname('///a/b/'))
+ assert_equal('/a/b', File.dirname('///a/b/c'))
+ end
+ end
+
+ def test_basename
+ if /(bcc|ms)win\d|mingw|cygwin|djgpp|human|emx/ =~ RUBY_PLATFORM
+ # DOSISH_DRIVE_LETTER
+ assert_equal('', File.basename('C:'))
+ assert_equal('a', File.basename('C:a'))
+ assert_equal('a', File.basename('C:a/'))
+ assert_equal('b', File.basename('C:a/b'))
+
+ assert_equal('/', File.basename('C:/'))
+ assert_equal('a', File.basename('C:/a'))
+ assert_equal('a', File.basename('C:/a/'))
+ assert_equal('b', File.basename('C:/a/b'))
+
+ assert_equal('/', File.basename('C://'))
+ assert_equal('a', File.basename('C://a'))
+ assert_equal('a', File.basename('C://a/'))
+ assert_equal('b', File.basename('C://a/b'))
+
+ assert_equal('/', File.basename('C:///'))
+ assert_equal('a', File.basename('C:///a'))
+ assert_equal('a', File.basename('C:///a/'))
+ assert_equal('b', File.basename('C:///a/b'))
+ else
+ # others
+ assert_equal('C:', File.basename('C:'))
+ assert_equal('C:a', File.basename('C:a'))
+ assert_equal('C:a', File.basename('C:a/'))
+ assert_equal('b', File.basename('C:a/b'))
+
+ assert_equal('C:', File.basename('C:/'))
+ assert_equal('a', File.basename('C:/a'))
+ assert_equal('a', File.basename('C:/a/'))
+ assert_equal('b', File.basename('C:/a/b'))
+
+ assert_equal('C:', File.basename('C://'))
+ assert_equal('a', File.basename('C://a'))
+ assert_equal('a', File.basename('C://a/'))
+ assert_equal('b', File.basename('C://a/b'))
+
+ assert_equal('C:', File.basename('C:///'))
+ assert_equal('a', File.basename('C:///a'))
+ assert_equal('a', File.basename('C:///a/'))
+ assert_equal('b', File.basename('C:///a/b'))
+ end
+
+ assert_equal('', File.basename(''))
+ assert_equal('a', File.basename('a'))
+ assert_equal('a', File.basename('a/'))
+ assert_equal('b', File.basename('a/b'))
+
+ assert_equal('/', File.basename('/'))
+ assert_equal('a', File.basename('/a'))
+ assert_equal('a', File.basename('/a/'))
+ assert_equal('b', File.basename('/a/b'))
+
+ if /(bcc|ms|cyg)win|mingw|djgpp|human|emx/ =~ RUBY_PLATFORM
+ # DOSISH_UNC
+ assert_equal('/', File.basename('//'))
+ assert_equal('/', File.basename('//a'))
+ assert_equal('/', File.basename('//a/'))
+ assert_equal('/', File.basename('//a/b'), "[ruby-dev:27776]")
+ assert_equal('/', File.basename('//a/b/'))
+ assert_equal('c', File.basename('//a/b/c'))
+
+ assert_equal('/', File.basename('///'))
+ assert_equal('/', File.basename('///a'))
+ assert_equal('/', File.basename('///a/'))
+ assert_equal('/', File.basename('///a/b'))
+ assert_equal('/', File.basename('///a/b/'))
+ assert_equal('c', File.basename('///a/b/c'))
+ else
+ # others
+ assert_equal('/', File.basename('//'))
+ assert_equal('a', File.basename('//a'))
+ assert_equal('a', File.basename('//a/'))
+ assert_equal('b', File.basename('//a/b'))
+ assert_equal('b', File.basename('//a/b/'))
+ assert_equal('c', File.basename('//a/b/c'))
+
+ assert_equal('/', File.basename('///'))
+ assert_equal('a', File.basename('///a'))
+ assert_equal('a', File.basename('///a/'))
+ assert_equal('b', File.basename('///a/b'))
+ assert_equal('b', File.basename('///a/b/'))
+ assert_equal('c', File.basename('///a/b/c'))
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_pipe.rb b/trunk/test/ruby/test_pipe.rb
new file mode 100644
index 0000000000..34f231ad8c
--- /dev/null
+++ b/trunk/test/ruby/test_pipe.rb
@@ -0,0 +1,16 @@
+require 'test/unit'
+require_relative 'ut_eof'
+
+class TestPipe < Test::Unit::TestCase
+ include TestEOF
+ def open_file(content)
+ r, w = IO.pipe
+ w << content
+ w.close
+ begin
+ yield r
+ ensure
+ r.close
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_prec.rb b/trunk/test/ruby/test_prec.rb
new file mode 100644
index 0000000000..d872242c11
--- /dev/null
+++ b/trunk/test/ruby/test_prec.rb
@@ -0,0 +1,21 @@
+require 'test/unit'
+
+class TestPrecision < Test::Unit::TestCase
+ def test_prec_i
+ assert_same(1, 1.0.prec(Integer))
+ assert_same(1, 1.0.prec_i)
+ assert_same(1, Integer.induced_from(1.0))
+ end
+
+ def test_prec_f
+ assert_equal(1.0, 1.prec(Float))
+ assert_equal(1.0, 1.prec_f)
+ assert_equal(1.0, Float.induced_from(1))
+ end
+
+ def test_induced_from
+ m = Module.new
+ m.instance_eval { include(Precision) }
+ assert_raise(TypeError) { m.induced_from(0) }
+ end
+end
diff --git a/trunk/test/ruby/test_primitive.rb b/trunk/test/ruby/test_primitive.rb
new file mode 100644
index 0000000000..8ffbe549d6
--- /dev/null
+++ b/trunk/test/ruby/test_primitive.rb
@@ -0,0 +1,397 @@
+require 'test/unit'
+
+class TestRubyPrimitive < Test::Unit::TestCase
+
+ def test_not
+ assert_equal false, !true
+ assert_equal true, !false
+ assert_equal true, !nil
+ assert_equal false, !(1+1)
+ assert_equal false, !!nil
+ assert_equal true, !!1
+ end
+
+ def test_lvar
+ a = 1
+ assert_equal 1, a
+ b = 2
+ assert_equal 1, a
+ a = b = 3
+ assert_equal 3, a
+ assert_equal 3, b
+ a = b = c = 4
+ assert_equal 4, a
+ assert_equal 4, b
+ assert_equal 4, c
+ end
+
+ C = 1
+ class A
+ Const = 1
+ class B
+ Const = 2
+ class C
+ Const = 3
+ def const
+ Const
+ end
+ end
+ end
+ end
+ (1..2).map {
+ A::B::C::Const
+ }
+
+ def test_constant
+ assert_equal 1, C
+ assert_equal 1, C
+ assert_equal 1, A::Const
+ assert_equal 2, A::B::Const
+ assert_equal 3, A::B::C::Const
+ assert_equal 3, A::B::C.new.const
+ assert_equal 1, ::TestRubyPrimitive::A::Const
+ A::B::C.send(:remove_const, :Const)
+ assert_equal 2, A::B::C.new.const
+ assert_raise(TypeError) {
+ C::CONST
+ }
+ end
+
+ class A2
+ class B2
+ class C2
+ C = 7
+ end
+ end
+ end
+
+ def test_constant_cache
+ i = 0
+ while i < 3
+ r = A2::B2::C2::C
+ i += 1
+ end
+ assert_equal 7, r
+ end
+
+ class A3
+ class B3
+ C = 99
+ end
+ end
+ i = 0
+ while i < 3
+ r = A3::B3::C # cache
+ class A3::B3
+ remove_const :C
+ end
+ A3::B3::C = i ** i
+ i += 1
+ end
+
+ def test_constant_cache2
+ assert_equal 4, A3::B3::C
+ end
+
+ class A4
+ Const = 7
+ (1..3).map {
+ $test_ruby_primitive_constant_cache3 = self::Const
+ }
+ end
+
+ def test_constant_cache3
+ assert_equal 7, $test_ruby_primitive_constant_cache3
+ end
+
+ class A5
+ Const = 8
+ (1..3).map {
+ $test_ruby_primitive_constant_cache4 = eval('self')::Const
+ }
+ end
+
+ def test_constatant_cache4
+ assert_equal 8, $test_ruby_primitive_constant_cache4
+ end
+
+ class A6
+ Const = 0
+ def self.foo
+ self::Const
+ end
+ end
+ class B6 < A6
+ Const = 1
+ end
+ class C6 < B6
+ Const = 2
+ end
+ $test_ruby_primitive_constant_cache5 = [A6.foo, B6.foo, C6.foo]
+
+ def test_constant_cache5
+ assert_equal [0, 1, 2], $test_ruby_primitive_constant_cache5
+ end
+
+ def test_gvar
+ $test_ruby_primitive_gvar = 7
+ assert_equal 7, $test_ruby_primitive_gvar
+ assert_equal 7, $test_ruby_primitive_gvar
+ $test_ruby_primitive_gvar = 88
+ assert_equal 88, $test_ruby_primitive_gvar
+ assert_equal 88, $test_ruby_primitive_gvar
+ assert_equal 7, ($test_ruby_primitive_gvar = 7)
+ assert_equal 7, ($test_ruby_primitive_gvar = 7)
+ end
+
+ class A7
+ @@c = 1
+ def m
+ @@c += 1
+ end
+ end
+
+ def test_cvar_from_instance_method
+ assert_equal 2, A7.new.m
+ assert_equal 3, A7.new.m
+ assert_equal 4, A7.new.m
+ end
+
+ class A8
+ @@c = 1
+ class << self
+ def m
+ @@c += 1
+ end
+ end
+ end
+
+ def test_cvar_from_singleton_method
+ assert_equal 2, A8.m
+ assert_equal 3, A8.m
+ assert_equal 4, A8.m
+ end
+
+ class A9
+ @@c = 1
+ def self.m
+ @@c += 1
+ end
+ end
+
+ def test_cvar_from_singleton_method2
+ assert_equal 2, A9.m
+ assert_equal 3, A9.m
+ assert_equal 4, A9.m
+ end
+
+ class A10
+ attr_accessor :a
+ end
+
+ def test_opassign
+ i = 0
+ i += 1
+ assert_equal 1, i
+
+ @iv = 2
+ @iv += 2
+ assert_equal 4, @iv
+
+ @@cv ||= 1
+ assert_equal 1, @@cv
+ @@cv &&= 2
+ assert_equal 2, @@cv
+ @@cv ||= 99
+ assert_equal 2, @@cv
+
+ $gv = 3
+ $gv += 4
+ assert_equal 7, $gv
+
+ obj = A10.new
+ obj.a = 9
+ obj.a &&= 7
+ assert_equal 7, obj.a
+
+ obj.a = nil
+ obj.a ||= 2
+ assert_equal 2, obj.a
+
+ obj.a &&= 3
+ assert_equal 3, obj.a
+
+ a = []
+ a[0] ||= 3
+ assert_equal 3, a[0]
+ a[0] &&= 7
+ assert_equal 7, a[0]
+ a[0] ||= 3
+ assert_equal 7, a[0]
+ end
+
+ def test_opassign_and_or
+ a = 1
+ a ||= 2
+ assert_equal 1, a
+ a = nil
+ a ||= 2
+ assert_equal 2, a
+ a = 1
+ a &&= 3
+ assert_equal 3, a
+ a = nil
+ a &&= 4
+ assert_nil a
+
+ h = {}
+ h[0] ||= 1
+ assert_equal 1, h[0]
+ h = {}
+ h[0] &&= 1
+ assert_nil h[0]
+ h = {0 => 7}
+ h[0] ||= 1
+ assert_equal 7, h[0]
+ h = {0 => 7}
+ h[0] &&= 1
+ assert_equal 1, h[0]
+ end
+
+ def test_backref
+ /a(b)(c)d/ =~ 'xyzabcdefgabcdefg'
+ assert_equal 'b', $1
+ assert_equal 'c', $2
+ assert_nil $3
+ assert_instance_of MatchData, $~
+ assert_equal 'abcd', $&
+ assert_equal 'xyz', $`
+ assert_equal 'efgabcdefg', $'
+ assert_equal 'c', $+
+
+ /(?!)/ =~ 'xyzabcdefgabcdefg'
+ assert_nil $1
+ assert_nil $2
+ assert_nil $3
+ assert_nil $~
+ assert_nil $&
+ assert_nil $`
+ assert_nil $'
+ assert_nil $+
+ end
+
+ def test_fact
+ assert_equal 306057512216440636035370461297268629388588804173576999416776741259476533176716867465515291422477573349939147888701726368864263907759003154226842927906974559841225476930271954604008012215776252176854255965356903506788725264321896264299365204576448830388909753943489625436053225980776521270822437639449120128678675368305712293681943649956460498166450227716500185176546469340112226034729724066333258583506870150169794168850353752137554910289126407157154830282284937952636580145235233156936482233436799254594095276820608062232812387383880817049600000000000000000000000000000000000000000000000000000000000000000000000000, fact(300)
+ end
+
+ def fact(n)
+ if n > 1
+ n * fact(n - 1)
+ else
+ 1
+ end
+ end
+
+ def test_mul
+ assert_equal 0, 2 * 0
+ assert_equal 0, 0 * 2
+ assert_equal 4, 2 * 2
+ end
+
+ class MyNum
+ def /(a)
+ a * 100
+ end
+ end
+
+ def test_div
+ assert_equal 1, 3 / 2
+ assert_equal 1.5, 3.0 / 2.0
+ assert_equal 300, MyNum.new / 3
+ end
+
+ class MyArr
+ def length
+ 'string'
+ end
+ end
+
+ def test_length
+ assert_equal 0, [].length
+ assert_equal 1, [1].length
+ assert_equal 2, [1,2].length
+ assert_equal 0, {}.length
+ assert_equal 1, {1=>1}.length
+ assert_equal 2, {1=>1, 2=>2}.length
+ assert_equal 'string', MyArr.new.length
+ end
+
+ class MyNum2
+ def %(a)
+ a * 100
+ end
+ end
+
+ def test_mod
+ assert_equal 2, 5 % 3
+ assert_equal 1.0, 3.0 % 2.0
+ assert_equal 300, MyNum2.new % 3
+ end
+
+ class MyObj
+ def [](*args)
+ args
+ end
+
+ def []=(*args)
+ args
+ end
+ end
+
+ def test_aref
+ a = [0,1]
+ assert_equal 0, a[0]
+ assert_equal 1, a[1]
+ assert_nil a[2]
+ h = {0=>0, 1=>1}
+ obj = MyObj.new
+ assert_equal 0, h[0]
+ assert_equal 1, h[1]
+ assert_nil h[2]
+ assert_equal [0], obj[0]
+ assert_equal [0,1], obj[0,1]
+ assert_equal [0,1,2], obj[0,1,2]
+ end
+
+ def test_aset
+ obj = MyObj.new
+ assert_equal 7, (obj[0] = 7)
+ assert_equal 7, (obj[0,1] = 7)
+ assert_equal 7, (obj[0,1,2] = 7)
+ end
+
+ class MyObj2
+ def attr=(*args)
+ args
+ end
+ end
+
+ def test_attr_setter
+ obj = MyObj2.new
+ assert_equal 1, (obj.attr = 1)
+ end
+
+ def test_list_expand
+ a = []
+ assert_equal [0], [0, *a]
+ a = [1]
+ assert_equal [0,1], [0, *a]
+ a = [1,2]
+ assert_equal [0,1,2], [0, *a]
+ a = [1,2,3]
+ assert_equal [0,1,2,3], [0, *a]
+ #a = [1,2,3]
+ #assert_equal [0,1,2,3,4], [0, *a, 4]
+ end
+
+end
diff --git a/trunk/test/ruby/test_proc.rb b/trunk/test/ruby/test_proc.rb
new file mode 100644
index 0000000000..ee53eeaf3a
--- /dev/null
+++ b/trunk/test/ruby/test_proc.rb
@@ -0,0 +1,312 @@
+require 'test/unit'
+
+class TestProc < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_proc
+ p1 = proc{|i| i}
+ assert_equal(2, p1.call(2))
+ assert_equal(3, p1.call(3))
+
+ p1 = proc{|i| i*2}
+ assert_equal(4, p1.call(2))
+ assert_equal(6, p1.call(3))
+
+ p2 = nil
+ x=0
+
+ proc{
+ iii=5 # nested local variable
+ p1 = proc{|i|
+ iii = i
+ }
+ p2 = proc {
+ x = iii # nested variables shared by procs
+ }
+ # scope of nested variables
+ assert(defined?(iii))
+ }.call
+ assert(!defined?(iii)) # out of scope
+
+ loop{iii=5; assert(eval("defined? iii")); break}
+ loop {
+ iii = 10
+ def self.dyna_var_check
+ loop {
+ assert(!defined?(iii))
+ break
+ }
+ end
+ dyna_var_check
+ break
+ }
+ p1.call(5)
+ p2.call
+ assert_equal(5, x)
+ end
+
+ def assert_arity(n)
+ meta = class << self; self; end
+ meta.class_eval {define_method(:foo, Proc.new)}
+ assert_equal(n, method(:foo).arity)
+ end
+
+ def test_arity
+ assert_equal(0, proc{}.arity)
+ assert_equal(0, proc{||}.arity)
+ assert_equal(1, proc{|x|}.arity)
+ assert_equal(2, proc{|x, y|}.arity)
+ assert_equal(-2, proc{|x, *y|}.arity)
+ assert_equal(-1, proc{|*x|}.arity)
+ assert_equal(-1, proc{|*|}.arity)
+ assert_equal(-3, proc{|x, *y, z|}.arity)
+ assert_equal(-4, proc{|x, *y, z, a|}.arity)
+
+ assert_arity(0) {}
+ assert_arity(0) {||}
+ assert_arity(1) {|x|}
+ assert_arity(2) {|x, y|}
+ assert_arity(-2) {|x, *y|}
+ assert_arity(-3) {|x, *y, z|}
+ assert_arity(-1) {|*x|}
+ assert_arity(-1) {|*|}
+ end
+
+ def m(x)
+ lambda { x }
+ end
+
+ def test_eq
+ a = m(1)
+ b = m(2)
+ assert_not_equal(a, b, "[ruby-dev:22592]")
+ assert_not_equal(a.call, b.call, "[ruby-dev:22592]")
+
+ assert_not_equal(proc {||}, proc {|x,y|}, "[ruby-dev:22599]")
+
+ a = lambda {|x| lambda {} }.call(1)
+ b = lambda {}
+ assert_not_equal(a, b, "[ruby-dev:22601]")
+ end
+
+ def test_block_par
+ assert_equal(10, Proc.new{|&b| b.call(10)}.call {|x| x})
+ assert_equal(12, Proc.new{|a,&b| b.call(a)}.call(12) {|x| x})
+ end
+
+ def test_safe
+ safe = $SAFE
+ c = Class.new
+ x = c.new
+
+ p = proc {
+ $SAFE += 1
+ proc {$SAFE}
+ }.call
+ assert_equal(safe, $SAFE)
+ assert_equal(safe + 1, p.call)
+ assert_equal(safe, $SAFE)
+
+ c.class_eval {define_method(:safe, p)}
+ assert_equal(safe, x.safe)
+ assert_equal(safe, x.method(:safe).call)
+ assert_equal(safe, x.method(:safe).to_proc.call)
+
+ p = proc {$SAFE += 1}
+ assert_equal(safe + 1, p.call)
+ assert_equal(safe, $SAFE)
+
+ c.class_eval {define_method(:inc, p)}
+ assert_equal(safe + 1, proc {x.inc; $SAFE}.call)
+ assert_equal(safe, $SAFE)
+ assert_equal(safe + 1, proc {x.method(:inc).call; $SAFE}.call)
+ assert_equal(safe, $SAFE)
+ assert_equal(safe + 1, proc {x.method(:inc).to_proc.call; $SAFE}.call)
+ assert_equal(safe, $SAFE)
+ end
+
+ def m2
+ "OK"
+ end
+
+ def block
+ method(:m2).to_proc
+ end
+
+ # [yarv-dev:777] block made by Method#to_proc
+ def test_method_to_proc
+ b = block()
+ assert_equal "OK", b.call
+ end
+
+ def test_curry
+ b = proc {|x, y, z| (x||0) + (y||0) + (z||0) }
+ assert_equal(6, b.curry[1][2][3])
+ assert_equal(6, b.curry[1, 2][3, 4])
+ assert_equal(6, b.curry(5)[1][2][3][4][5])
+ assert_equal(6, b.curry(5)[1, 2][3, 4][5])
+ assert_equal(1, b.curry(1)[1])
+
+ b = proc {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
+ assert_equal(6, b.curry[1][2][3])
+ assert_equal(10, b.curry[1, 2][3, 4])
+ assert_equal(15, b.curry(5)[1][2][3][4][5])
+ assert_equal(15, b.curry(5)[1, 2][3, 4][5])
+ assert_equal(1, b.curry(1)[1])
+
+ b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }
+ assert_equal(6, b.curry[1][2][3])
+ assert_raise(ArgumentError) { b.curry[1, 2][3, 4] }
+ assert_raise(ArgumentError) { b.curry(5) }
+ assert_raise(ArgumentError) { b.curry(1) }
+
+ b = lambda {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
+ assert_equal(6, b.curry[1][2][3])
+ assert_equal(10, b.curry[1, 2][3, 4])
+ assert_equal(15, b.curry(5)[1][2][3][4][5])
+ assert_equal(15, b.curry(5)[1, 2][3, 4][5])
+ assert_raise(ArgumentError) { b.curry(1) }
+
+ b = proc { :foo }
+ assert_equal(:foo, b.curry[])
+ end
+
+ def test_curry_ski_fib
+ s = proc {|f, g, x| f[x][g[x]] }.curry
+ k = proc {|x, y| x }.curry
+ i = proc {|x| x }.curry
+
+ fib = []
+ inc = proc {|x| fib[-1] += 1; x }.curry
+ ret = proc {|x| throw :end if fib.size > 10; fib << 0; x }.curry
+
+ catch(:end) do
+ s[
+ s[s[i][i]][k[i]]
+ ][
+ k[inc]
+ ][
+ s[
+ s[
+ k[s]
+ ][
+ s[k[s[k[s]]]
+ ][
+ s[s[k[s]][s[k[s[k[ret]]]][s[k[s[i]]][k]]]][k]]
+ ]
+ ][
+ k[s[k[s]][k]]
+ ]
+ ]
+ end
+
+ assert_equal(fib, [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89])
+ end
+
+ def test_curry_from_knownbug
+ a = lambda {|x, y, &b| b }
+ b = a.curry[1]
+
+ assert_equal(:ok,
+ if b.call(2){} == nil
+ :ng
+ else
+ :ok
+ end, 'moved from btest/knownbug, [ruby-core:15551]')
+ end
+
+ def test_dup_clone
+ b = proc {|x| x + "bar" }
+ class << b; attr_accessor :foo; end
+
+ bd = b.dup
+ assert_equal("foobar", bd.call("foo"))
+ assert_raise(NoMethodError) { bd.foo = :foo }
+ assert_raise(NoMethodError) { bd.foo }
+
+ bc = b.clone
+ assert_equal("foobar", bc.call("foo"))
+ bc.foo = :foo
+ assert_equal(:foo, bc.foo)
+ end
+
+ def test_binding
+ b = proc {|x, y, z| proc {}.binding }.call(1, 2, 3)
+ class << b; attr_accessor :foo; end
+
+ bd = b.dup
+ assert_equal([1, 2, 3], bd.eval("[x, y, z]"))
+ assert_raise(NoMethodError) { bd.foo = :foo }
+ assert_raise(NoMethodError) { bd.foo }
+
+ bc = b.clone
+ assert_equal([1, 2, 3], bc.eval("[x, y, z]"))
+ bc.foo = :foo
+ assert_equal(:foo, bc.foo)
+
+ b = nil
+ 1.times { x, y, z = 1, 2, 3; b = binding }
+ assert_equal([1, 2, 3], b.eval("[x, y, z]"))
+ end
+
+ def test_proc_lambda
+ assert_raise(ArgumentError) { proc }
+ assert_raise(ArgumentError) { lambda }
+
+ o = Object.new
+ def o.foo
+ b = nil
+ 1.times { b = lambda }
+ b
+ end
+ assert_equal(:foo, o.foo { :foo }.call)
+
+ def o.foo(&b)
+ b = nil
+ 1.times { b = lambda }
+ b
+ end
+ assert_equal(:foo, o.foo { :foo }.call)
+ end
+
+ def test_arity2
+ assert_equal(0, method(:proc).to_proc.arity)
+ assert_equal(-1, proc {}.curry.arity)
+ end
+
+ def test_proc_location
+ t = Thread.new { sleep }
+ assert_raise(ThreadError) { t.instance_eval { initialize { } } }
+ t.kill
+ end
+
+ def test_eq2
+ b1 = proc { }
+ b2 = b1.dup
+ assert(b1 == b2)
+ end
+
+ def test_to_proc
+ b = proc { :foo }
+ assert_equal(:foo, b.to_proc.call)
+ end
+
+ def test_localjump_error
+ o = Object.new
+ def foo; yield; end
+ exc = foo rescue $!
+ assert_nil(exc.exit_value)
+ assert_equal(:noreason, exc.reason)
+ end
+
+ def test_binding2
+ assert_raise(ArgumentError) { proc {}.curry.binding }
+ end
+end
diff --git a/trunk/test/ruby/test_process.rb b/trunk/test/ruby/test_process.rb
new file mode 100644
index 0000000000..ba933b2d56
--- /dev/null
+++ b/trunk/test/ruby/test_process.rb
@@ -0,0 +1,1007 @@
+require 'test/unit'
+require 'tmpdir'
+require 'pathname'
+require_relative 'envutil'
+
+class TestProcess < Test::Unit::TestCase
+ RUBY = EnvUtil.rubybin
+
+ def setup
+ Process.waitall
+ end
+
+ def teardown
+ Process.waitall
+ end
+
+ def write_file(filename, content)
+ File.open(filename, "w") {|f|
+ f << content
+ }
+ end
+
+ def with_tmpchdir
+ Dir.mktmpdir {|d|
+ d = Pathname.new(d).realpath.to_s
+ Dir.chdir(d) {
+ yield d
+ }
+ }
+ end
+
+ def run_in_child(str) # should be called in a temporary directory
+ write_file("test-script", str)
+ Process.wait spawn(RUBY, "test-script")
+ $?
+ end
+
+ def test_rlimit_availability
+ begin
+ Process.getrlimit(nil)
+ rescue NotImplementedError
+ assert_raise(NotImplementedError) { Process.setrlimit }
+ rescue TypeError
+ assert_raise(ArgumentError) { Process.setrlimit }
+ end
+ end
+
+ def rlimit_exist?
+ Process.getrlimit(nil)
+ rescue NotImplementedError
+ return false
+ rescue TypeError
+ return true
+ end
+
+ def test_rlimit_nofile
+ return unless rlimit_exist?
+ with_tmpchdir {
+ write_file 's', <<-"End"
+ cur_nofile, max_nofile = Process.getrlimit(Process::RLIMIT_NOFILE)
+ result = 1
+ begin
+ Process.setrlimit(Process::RLIMIT_NOFILE, 0, max_nofile)
+ rescue Errno::EINVAL
+ result = 0
+ end
+ if result == 1
+ begin
+ IO.pipe
+ rescue Errno::EMFILE
+ result = 0
+ end
+ end
+ Process.setrlimit(Process::RLIMIT_NOFILE, cur_nofile, max_nofile)
+ exit result
+ End
+ pid = spawn RUBY, "s"
+ Process.wait pid
+ assert_equal(0, $?.to_i, "#{$?}")
+ }
+ end
+
+ def test_rlimit_name
+ return unless rlimit_exist?
+ [
+ :AS, "AS",
+ :CORE, "CORE",
+ :CPU, "CPU",
+ :DATA, "DATA",
+ :FSIZE, "FSIZE",
+ :MEMLOCK, "MEMLOCK",
+ :NOFILE, "NOFILE",
+ :NPROC, "NPROC",
+ :RSS, "RSS",
+ :STACK, "STACK",
+ :SBSIZE, "SBSIZE",
+ ].each {|name|
+ if Process.const_defined? "RLIMIT_#{name}"
+ assert_nothing_raised { Process.getrlimit(name) }
+ else
+ assert_raise(ArgumentError) { Process.getrlimit(name) }
+ end
+ }
+ assert_raise(ArgumentError) { Process.getrlimit(:FOO) }
+ assert_raise(ArgumentError) { Process.getrlimit("FOO") }
+ end
+
+ def test_rlimit_value
+ return unless rlimit_exist?
+ assert_raise(ArgumentError) { Process.setrlimit(:CORE, :FOO) }
+ assert_raise(Errno::EPERM, Errno::EINVAL) { Process.setrlimit(:NOFILE, :INFINITY) }
+ assert_raise(Errno::EPERM, Errno::EINVAL) { Process.setrlimit(:NOFILE, "INFINITY") }
+ end
+
+ TRUECOMMAND = [RUBY, '-e', '']
+
+ def test_execopts_opts
+ assert_nothing_raised {
+ Process.wait Process.spawn(*TRUECOMMAND, {})
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*TRUECOMMAND, :foo => 100)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*TRUECOMMAND, Process => 100)
+ }
+ end
+
+ def test_execopts_pgroup
+ assert_nothing_raised { system(*TRUECOMMAND, :pgroup=>false) }
+
+ io = IO.popen([RUBY, "-e", "print Process.getpgrp"])
+ assert_equal(Process.getpgrp.to_s, io.read)
+ io.close
+
+ io = IO.popen([RUBY, "-e", "print Process.getpgrp", :pgroup=>true])
+ assert_equal(io.pid.to_s, io.read)
+ io.close
+
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :pgroup=>-1) }
+ assert_raise(Errno::EPERM) { Process.wait spawn(*TRUECOMMAND, :pgroup=>2) }
+
+ io1 = IO.popen([RUBY, "-e", "print Process.getpgrp", :pgroup=>true])
+ io2 = IO.popen([RUBY, "-e", "print Process.getpgrp", :pgroup=>io1.pid])
+ assert_equal(io1.pid.to_s, io1.read)
+ assert_equal(io1.pid.to_s, io2.read)
+ Process.wait io1.pid
+ Process.wait io2.pid
+ io1.close
+ io2.close
+ end
+
+ def test_execopts_rlimit
+ return unless rlimit_exist?
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :rlimit_foo=>0) }
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :rlimit_NOFILE=>0) }
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :rlimit_nofile=>[]) }
+ assert_raise(ArgumentError) { system(*TRUECOMMAND, :rlimit_nofile=>[1,2,3]) }
+
+ max = Process.getrlimit(:CORE).last
+
+ n = max
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
+ assert_equal("[#{n}, #{n}]\n", io.read)
+ }
+
+ n = 0
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
+ assert_equal("[#{n}, #{n}]\n", io.read)
+ }
+
+ n = max
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>[n]]) {|io|
+ assert_equal("[#{n}, #{n}]", io.read.chomp)
+ }
+
+ m, n = 0, max
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
+ assert_equal("[#{m}, #{n}]", io.read.chomp)
+ }
+
+ m, n = 0, 0
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
+ assert_equal("[#{m}, #{n}]", io.read.chomp)
+ }
+
+ n = max
+ IO.popen([RUBY, "-e",
+ "p Process.getrlimit(:CORE), Process.getrlimit(:CPU)",
+ :rlimit_core=>n, :rlimit_cpu=>3600]) {|io|
+ assert_equal("[#{n}, #{n}]\n[3600, 3600]", io.read.chomp)
+ }
+ end
+
+ ENVCOMMAND = [RUBY, '-e', 'ENV.each {|k,v| puts "#{k}=#{v}" }']
+
+ def test_execopts_env
+ assert_raise(ArgumentError) {
+ system({"F=O"=>"BAR"}, *TRUECOMMAND)
+ }
+
+ h = {}
+ ENV.each {|k,v| h[k] = nil unless k.upcase == "PATH" }
+ IO.popen([h, RUBY, '-e', 'puts ENV.keys.map{|e|e.upcase}']) {|io|
+ assert_equal("PATH\n", io.read)
+ }
+
+ IO.popen([{"FOO"=>"BAR"}, *ENVCOMMAND]) {|io|
+ assert_match(/^FOO=BAR$/, io.read)
+ }
+
+ with_tmpchdir {|d|
+ system({"fofo"=>"haha"}, *ENVCOMMAND, STDOUT=>"out")
+ assert_match(/^fofo=haha$/, File.read("out").chomp)
+ }
+ end
+
+ def test_execopts_unsetenv_others
+ IO.popen([*ENVCOMMAND, :unsetenv_others=>true]) {|io|
+ assert_equal("", io.read)
+ }
+ IO.popen([{"A"=>"B"}, *ENVCOMMAND, :unsetenv_others=>true]) {|io|
+ assert_equal("A=B\n", io.read)
+ }
+ end
+
+ PWD = [RUBY, '-e', 'puts Dir.pwd']
+
+ def test_execopts_chdir
+ with_tmpchdir {|d|
+ IO.popen([*PWD, :chdir => d]) {|io|
+ assert_equal(d, io.read.chomp)
+ }
+ assert_raise(Errno::ENOENT) {
+ Process.wait Process.spawn(*PWD, :chdir => "d/notexist")
+ }
+ }
+ end
+
+ UMASK = [RUBY, '-e', 'printf "%04o\n", File.umask']
+
+ def test_execopts_umask
+ IO.popen([*UMASK, :umask => 0]) {|io|
+ assert_equal("0000", io.read.chomp)
+ }
+ IO.popen([*UMASK, :umask => 0777]) {|io|
+ assert_equal("0777", io.read.chomp)
+ }
+ end
+
+ def with_pipe
+ begin
+ r, w = IO.pipe
+ yield r, w
+ ensure
+ r.close unless r.closed?
+ w.close unless w.closed?
+ end
+ end
+
+ def with_pipes(n)
+ ary = []
+ begin
+ n.times {
+ ary << IO.pipe
+ }
+ yield ary
+ ensure
+ ary.each {|r, w|
+ r.close unless r.closed?
+ w.close unless w.closed?
+ }
+ end
+ end
+
+ ECHO = lambda {|arg| [RUBY, '-e', "puts #{arg.dump}; STDOUT.flush"] }
+ SORT = [RUBY, '-e', "puts ARGF.readlines.sort"]
+ CAT = [RUBY, '-e', "IO.copy_stream STDIN, STDOUT"]
+
+ def test_execopts_redirect
+ with_tmpchdir {|d|
+ Process.wait Process.spawn(*ECHO["a"], STDOUT=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ assert_equal("a", File.read("out").chomp)
+ Process.wait Process.spawn(*ECHO["0"], STDOUT=>["out", File::WRONLY|File::CREAT|File::APPEND, 0644])
+ assert_equal("a\n0\n", File.read("out"))
+ Process.wait Process.spawn(*SORT, STDIN=>["out", File::RDONLY, 0644],
+ STDOUT=>["out2", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ assert_equal("0\na\n", File.read("out2"))
+ Process.wait Process.spawn(*ECHO["b"], [STDOUT, STDERR]=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ assert_equal("b", File.read("out").chomp)
+ # problem occur with valgrind
+ #Process.wait Process.spawn(*ECHO["a"], STDOUT=>:close, STDERR=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ #p File.read("out")
+ #assert(!File.read("out").empty?) # error message such as "-e:1:in `flush': Bad file descriptor (Errno::EBADF)"
+ Process.wait Process.spawn(*ECHO["c"], STDERR=>STDOUT, STDOUT=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644])
+ assert_equal("c", File.read("out").chomp)
+ File.open("out", "w") {|f|
+ Process.wait Process.spawn(*ECHO["d"], f=>STDOUT, STDOUT=>f)
+ assert_equal("d", File.read("out").chomp)
+ }
+ Process.wait Process.spawn(*ECHO["e"], STDOUT=>["out", File::WRONLY|File::CREAT|File::TRUNC, 0644],
+ 3=>STDOUT, 4=>STDOUT, 5=>STDOUT, 6=>STDOUT, 7=>STDOUT)
+ assert_equal("e", File.read("out").chomp)
+ File.open("out", "w") {|f|
+ h = {STDOUT=>f, f=>STDOUT}
+ 3.upto(30) {|i| h[i] = STDOUT if f.fileno != i }
+ Process.wait Process.spawn(*ECHO["f"], h)
+ assert_equal("f", File.read("out").chomp)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*ECHO["f"], 1=>Process)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*ECHO["f"], [Process]=>1)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*ECHO["f"], [1, STDOUT]=>2)
+ }
+ assert_raise(ArgumentError) {
+ Process.wait Process.spawn(*ECHO["f"], -1=>2)
+ }
+ Process.wait Process.spawn(*ECHO["hhh\nggg\n"], STDOUT=>"out")
+ assert_equal("hhh\nggg\n", File.read("out"))
+ Process.wait Process.spawn(*SORT, STDIN=>"out", STDOUT=>"out2")
+ assert_equal("ggg\nhhh\n", File.read("out2"))
+
+ assert_raise(Errno::ENOENT) {
+ Process.wait Process.spawn("non-existing-command", (3..60).to_a=>["err", File::WRONLY|File::CREAT])
+ }
+ assert_equal("", File.read("err"))
+
+ system(*ECHO["bb\naa\n"], STDOUT=>["out", "w"])
+ assert_equal("bb\naa\n", File.read("out"))
+ system(*SORT, STDIN=>["out"], STDOUT=>"out2")
+ assert_equal("aa\nbb\n", File.read("out2"))
+
+ with_pipe {|r1, w1|
+ with_pipe {|r2, w2|
+ pid = spawn(*SORT, STDIN=>r1, STDOUT=>w2, w1=>:close, r2=>:close)
+ r1.close
+ w2.close
+ w1.puts "c"
+ w1.puts "a"
+ w1.puts "b"
+ w1.close
+ assert_equal("a\nb\nc\n", r2.read)
+ Process.wait(pid)
+ }
+ }
+
+ with_pipes(5) {|pipes|
+ ios = pipes.flatten
+ h = {}
+ ios.length.times {|i| h[ios[i]] = ios[(i-1)%ios.length] }
+ h2 = h.invert
+ rios = pipes.map {|r, w| r }
+ wios = pipes.map {|r, w| w }
+ child_wfds = wios.map {|w| h2[w].fileno }
+ pid = spawn(RUBY, "-e",
+ "[#{child_wfds.join(',')}].each {|fd| IO.new(fd).puts fd }", h)
+ pipes.each {|r, w|
+ assert_equal("#{h2[w].fileno}\n", r.gets)
+ }
+ Process.wait pid;
+ }
+
+ with_pipes(5) {|pipes|
+ ios = pipes.flatten
+ h = {}
+ ios.length.times {|i| h[ios[i]] = ios[(i+1)%ios.length] }
+ h2 = h.invert
+ rios = pipes.map {|r, w| r }
+ wios = pipes.map {|r, w| w }
+ child_wfds = wios.map {|w| h2[w].fileno }
+ pid = spawn(RUBY, "-e",
+ "[#{child_wfds.join(',')}].each {|fd| IO.new(fd).puts fd }", h)
+ pipes.each {|r, w|
+ assert_equal("#{h2[w].fileno}\n", r.gets)
+ }
+ Process.wait pid;
+ }
+
+ closed_fd = nil
+ with_pipes(5) {|pipes|
+ io = pipes.last.last
+ closed_fd = io.fileno
+ }
+ assert_raise(Errno::EBADF) { Process.wait spawn(*TRUECOMMAND, closed_fd=>closed_fd) }
+
+ with_pipe {|r, w|
+ w.close_on_exec = true
+ pid = spawn(RUBY, "-e", "IO.new(#{w.fileno}).print 'a'", w=>w)
+ w.close
+ assert_equal("a", r.read)
+ Process.wait pid
+ }
+
+ system(*ECHO["funya"], :out=>"out")
+ assert_equal("funya\n", File.read("out"))
+ system(RUBY, '-e', 'STDOUT.reopen(STDERR); puts "henya"', :err=>"out")
+ assert_equal("henya\n", File.read("out"))
+ IO.popen([*CAT, :in=>"out"]) {|io|
+ assert_equal("henya\n", io.read)
+ }
+ }
+ end
+
+ def test_execopts_exec
+ with_tmpchdir {|d|
+ write_file("s", 'exec "echo aaa", STDOUT=>"foo"')
+ pid = spawn RUBY, 's'
+ Process.wait pid
+ assert_equal("aaa\n", File.read("foo"))
+ }
+ end
+
+ def test_execopts_popen
+ with_tmpchdir {|d|
+ IO.popen("#{RUBY} -e 'puts :foo'") {|io| assert_equal("foo\n", io.read) }
+ assert_raise(Errno::ENOENT) { IO.popen(["echo bar"]) {} } # assuming "echo bar" command not exist.
+ IO.popen(ECHO["baz"]) {|io| assert_equal("baz\n", io.read) }
+ assert_raise(ArgumentError) {
+ IO.popen([*ECHO["qux"], STDOUT=>STDOUT]) {|io| }
+ }
+ IO.popen([*ECHO["hoge"], STDERR=>STDOUT]) {|io|
+ assert_equal("hoge\n", io.read)
+ }
+ assert_raise(ArgumentError) {
+ IO.popen([*ECHO["fuga"], STDOUT=>"out"]) {|io| }
+ }
+ with_pipe {|r, w|
+ IO.popen([RUBY, '-e', 'IO.new(3).puts("a"); puts "b"', 3=>w]) {|io|
+ assert_equal("b\n", io.read)
+ }
+ w.close
+ assert_equal("a\n", r.read)
+ }
+ IO.popen([RUBY, '-e', "IO.new(9).puts(:b)",
+ 9=>["out2", File::WRONLY|File::CREAT|File::TRUNC]]) {|io|
+ assert_equal("", io.read)
+ }
+ assert_equal("b\n", File.read("out2"))
+ }
+ end
+
+ def test_popen_fork
+ return if /freebsd/ =~ RUBY_PLATFORM # this test freeze in FreeBSD
+ IO.popen("-") {|io|
+ if !io
+ puts "fooo"
+ else
+ assert_equal("fooo\n", io.read)
+ end
+ }
+ rescue NotImplementedError
+ end
+
+ def test_fd_inheritance
+ with_pipe {|r, w|
+ system(RUBY, '-e', 'IO.new(ARGV[0].to_i).puts(:ba)', w.fileno.to_s)
+ w.close
+ assert_equal("ba\n", r.read)
+ }
+ with_pipe {|r, w|
+ Process.wait spawn(RUBY, '-e',
+ 'IO.new(ARGV[0].to_i).puts("bi") rescue nil',
+ w.fileno.to_s)
+ w.close
+ assert_equal("", r.read)
+ }
+ with_pipe {|r, w|
+ with_tmpchdir {|d|
+ write_file("s", <<-"End")
+ exec(#{RUBY.dump}, '-e',
+ 'IO.new(ARGV[0].to_i).puts("bu") rescue nil',
+ #{w.fileno.to_s.dump})
+ End
+ Process.wait spawn(RUBY, "s", :close_others=>false)
+ w.close
+ assert_equal("bu\n", r.read)
+ }
+ }
+ with_pipe {|r, w|
+ io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}).puts('me')"])
+ w.close
+ errmsg = io.read
+ assert_equal("", r.read)
+ assert_not_equal("", errmsg)
+ Process.wait
+ }
+ with_pipe {|r, w|
+ errmsg = `#{RUBY} -e "STDERR.reopen(STDOUT); IO.new(#{w.fileno}).puts(123)"`
+ w.close
+ assert_equal("", r.read)
+ assert_not_equal("", errmsg)
+ }
+ end
+
+ def test_execopts_close_others
+ with_tmpchdir {|d|
+ with_pipe {|r, w|
+ system(RUBY, '-e', 'STDERR.reopen("err", "w"); IO.new(ARGV[0].to_i).puts("ma")', w.fileno.to_s, :close_others=>true)
+ w.close
+ assert_equal("", r.read)
+ assert_not_equal("", File.read("err"))
+ File.unlink("err")
+ }
+ with_pipe {|r, w|
+ Process.wait spawn(RUBY, '-e', 'STDERR.reopen("err", "w"); IO.new(ARGV[0].to_i).puts("mi")', w.fileno.to_s, :close_others=>true)
+ w.close
+ assert_equal("", r.read)
+ assert_not_equal("", File.read("err"))
+ File.unlink("err")
+ }
+ with_pipe {|r, w|
+ Process.wait spawn(RUBY, '-e', 'IO.new(ARGV[0].to_i).puts("bi")', w.fileno.to_s, :close_others=>false)
+ w.close
+ assert_equal("bi\n", r.read)
+ }
+ with_pipe {|r, w|
+ write_file("s", <<-"End")
+ exec(#{RUBY.dump}, '-e',
+ 'STDERR.reopen("err", "w"); IO.new(ARGV[0].to_i).puts("mu")',
+ #{w.fileno.to_s.dump},
+ :close_others=>true)
+ End
+ Process.wait spawn(RUBY, "s", :close_others=>false)
+ w.close
+ assert_equal("", r.read)
+ assert_not_equal("", File.read("err"))
+ File.unlink("err")
+ }
+ with_pipe {|r, w|
+ io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}).puts('me')", :close_others=>true])
+ w.close
+ errmsg = io.read
+ assert_equal("", r.read)
+ assert_not_equal("", errmsg)
+ Process.wait
+ }
+ with_pipe {|r, w|
+ io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}).puts('mo')", :close_others=>false])
+ w.close
+ errmsg = io.read
+ assert_equal("mo\n", r.read)
+ assert_equal("", errmsg)
+ Process.wait
+ }
+ with_pipe {|r, w|
+ io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}).puts('mo')", :close_others=>nil])
+ w.close
+ errmsg = io.read
+ assert_equal("mo\n", r.read)
+ assert_equal("", errmsg)
+ Process.wait
+ }
+
+ }
+ end
+
+ def test_execopts_redirect_self
+ with_pipe {|r, w|
+ w << "haha\n"
+ w.close
+ r.close_on_exec = true
+ IO.popen([RUBY, "-e", "print IO.new(#{r.fileno}).read", r.fileno=>r.fileno, :close_others=>false]) {|io|
+ assert_equal("haha\n", io.read)
+ }
+ }
+ end
+
+ def test_execopts_duplex_io
+ IO.popen("#{RUBY} -e ''", "r+") {|duplex|
+ assert_raise(ArgumentError) { system("#{RUBY} -e ''", duplex=>STDOUT) }
+ assert_raise(ArgumentError) { system("#{RUBY} -e ''", STDOUT=>duplex) }
+ }
+ end
+
+ def test_execopts_modification
+ h = {}
+ Process.wait spawn(*TRUECOMMAND, h)
+ assert_equal({}, h)
+
+ h = {}
+ system(*TRUECOMMAND, h)
+ assert_equal({}, h)
+
+ h = {}
+ io = IO.popen([*TRUECOMMAND, h])
+ io.close
+ assert_equal({}, h)
+ end
+
+ def test_system_noshell
+ str = "echo non existing command name which contains spaces"
+ assert_nil(system([str, str]))
+ end
+
+ def test_spawn_noshell
+ str = "echo non existing command name which contains spaces"
+ assert_raise(Errno::ENOENT) { spawn([str, str]) }
+ end
+
+ def test_popen_noshell
+ str = "echo non existing command name which contains spaces"
+ assert_raise(Errno::ENOENT) { IO.popen([str, str]) }
+ end
+
+ def test_exec_noshell
+ with_tmpchdir {|d|
+ with_pipe {|r, w|
+ write_file("s", <<-"End")
+ str = "echo non existing command name which contains spaces"
+ w = IO.new(#{w.fileno})
+ STDOUT.reopen(w)
+ STDERR.reopen(w)
+ begin
+ exec [str, str]
+ rescue Errno::ENOENT
+ w.write "Errno::ENOENT success"
+ end
+ End
+ system(RUBY, "s", :close_others=>false)
+ w.close
+ assert_equal("Errno::ENOENT success", r.read)
+ }
+ }
+ end
+
+ def test_system_wordsplit
+ with_tmpchdir {|d|
+ write_file("script", <<-'End')
+ File.open("result", "w") {|t| t << "haha pid=#{$$} ppid=#{Process.ppid}" }
+ exit 5
+ End
+ str = "#{RUBY} script"
+ ret = system(str)
+ status = $?
+ assert_equal(false, ret)
+ assert(status.exited?)
+ assert_equal(5, status.exitstatus)
+ assert_equal("haha pid=#{status.pid} ppid=#{$$}", File.read("result"))
+ }
+ end
+
+ def test_spawn_wordsplit
+ with_tmpchdir {|d|
+ write_file("script", <<-'End')
+ File.open("result", "w") {|t| t << "hihi pid=#{$$} ppid=#{Process.ppid}" }
+ exit 6
+ End
+ str = "#{RUBY} script"
+ pid = spawn(str)
+ Process.wait pid
+ status = $?
+ assert_equal(pid, status.pid)
+ assert(status.exited?)
+ assert_equal(6, status.exitstatus)
+ assert_equal("hihi pid=#{status.pid} ppid=#{$$}", File.read("result"))
+ }
+ end
+
+ def test_popen_wordsplit
+ with_tmpchdir {|d|
+ write_file("script", <<-'End')
+ print "fufu pid=#{$$} ppid=#{Process.ppid}"
+ exit 7
+ End
+ str = "#{RUBY} script"
+ io = IO.popen(str)
+ pid = io.pid
+ result = io.read
+ io.close
+ status = $?
+ assert_equal(pid, status.pid)
+ assert(status.exited?)
+ assert_equal(7, status.exitstatus)
+ assert_equal("fufu pid=#{status.pid} ppid=#{$$}", result)
+ }
+ end
+
+ def test_exec_wordsplit
+ with_tmpchdir {|d|
+ write_file("script", <<-'End')
+ File.open("result", "w") {|t|
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ t << "hehe ppid=#{Process.ppid}"
+ else
+ t << "hehe pid=#{$$} ppid=#{Process.ppid}"
+ end
+ }
+ exit 6
+ End
+ write_file("s", <<-"End")
+ ruby = #{RUBY.dump}
+ exec "\#{ruby} script"
+ End
+ pid = spawn(RUBY, "s")
+ Process.wait pid
+ status = $?
+ assert_equal(pid, status.pid)
+ assert(status.exited?)
+ assert_equal(6, status.exitstatus)
+ if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
+ expected = "hehe ppid=#{status.pid}"
+ else
+ expected = "hehe pid=#{status.pid} ppid=#{$$}"
+ end
+ assert_equal(expected, File.read("result"))
+ }
+ end
+
+ def test_system_shell
+ with_tmpchdir {|d|
+ write_file("script1", <<-'End')
+ File.open("result1", "w") {|t| t << "taka pid=#{$$} ppid=#{Process.ppid}" }
+ exit 7
+ End
+ write_file("script2", <<-'End')
+ File.open("result2", "w") {|t| t << "taki pid=#{$$} ppid=#{Process.ppid}" }
+ exit 8
+ End
+ ret = system("#{RUBY} script1 || #{RUBY} script2")
+ status = $?
+ assert_equal(false, ret)
+ assert(status.exited?)
+ result1 = File.read("result1")
+ result2 = File.read("result2")
+ assert_match(/\Ataka pid=\d+ ppid=\d+\z/, result1)
+ assert_match(/\Ataki pid=\d+ ppid=\d+\z/, result2)
+ assert_not_equal(result1[/\d+/].to_i, status.pid)
+ }
+ end
+
+ def test_spawn_shell
+ with_tmpchdir {|d|
+ write_file("script1", <<-'End')
+ File.open("result1", "w") {|t| t << "taku pid=#{$$} ppid=#{Process.ppid}" }
+ exit 7
+ End
+ write_file("script2", <<-'End')
+ File.open("result2", "w") {|t| t << "take pid=#{$$} ppid=#{Process.ppid}" }
+ exit 8
+ End
+ pid = spawn("#{RUBY} script1 || #{RUBY} script2")
+ Process.wait pid
+ status = $?
+ assert(status.exited?)
+ assert(!status.success?)
+ result1 = File.read("result1")
+ result2 = File.read("result2")
+ assert_match(/\Ataku pid=\d+ ppid=\d+\z/, result1)
+ assert_match(/\Atake pid=\d+ ppid=\d+\z/, result2)
+ assert_not_equal(result1[/\d+/].to_i, status.pid)
+ }
+ end
+
+ def test_popen_shell
+ with_tmpchdir {|d|
+ write_file("script1", <<-'End')
+ puts "tako pid=#{$$} ppid=#{Process.ppid}"
+ exit 7
+ End
+ write_file("script2", <<-'End')
+ puts "tika pid=#{$$} ppid=#{Process.ppid}"
+ exit 8
+ End
+ io = IO.popen("#{RUBY} script1 || #{RUBY} script2")
+ result = io.read
+ io.close
+ status = $?
+ assert(status.exited?)
+ assert(!status.success?)
+ assert_match(/\Atako pid=\d+ ppid=\d+\ntika pid=\d+ ppid=\d+\n\z/, result)
+ assert_not_equal(result[/\d+/].to_i, status.pid)
+ }
+ end
+
+ def test_exec_shell
+ with_tmpchdir {|d|
+ write_file("script1", <<-'End')
+ File.open("result1", "w") {|t| t << "tiki pid=#{$$} ppid=#{Process.ppid}" }
+ exit 7
+ End
+ write_file("script2", <<-'End')
+ File.open("result2", "w") {|t| t << "tiku pid=#{$$} ppid=#{Process.ppid}" }
+ exit 8
+ End
+ write_file("s", <<-"End")
+ ruby = #{RUBY.dump}
+ exec("\#{ruby} script1 || \#{ruby} script2")
+ End
+ pid = spawn RUBY, "s"
+ Process.wait pid
+ status = $?
+ assert(status.exited?)
+ assert(!status.success?)
+ result1 = File.read("result1")
+ result2 = File.read("result2")
+ assert_match(/\Atiki pid=\d+ ppid=\d+\z/, result1)
+ assert_match(/\Atiku pid=\d+ ppid=\d+\z/, result2)
+ assert_not_equal(result1[/\d+/].to_i, status.pid)
+ }
+ end
+
+ def test_argv0
+ with_tmpchdir {|d|
+ assert_equal(false, system([RUBY, "asdfg"], "-e", "exit false"))
+ assert_equal(true, system([RUBY, "zxcvb"], "-e", "exit true"))
+
+ Process.wait spawn([RUBY, "poiu"], "-e", "exit 4")
+ assert_equal(4, $?.exitstatus)
+
+ assert_equal("1", IO.popen([[RUBY, "qwerty"], "-e", "print 1"]).read)
+ Process.wait
+
+ write_file("s", <<-"End")
+ exec([#{RUBY.dump}, "lkjh"], "-e", "exit 5")
+ End
+ pid = spawn RUBY, "s"
+ Process.wait pid
+ assert_equal(5, $?.exitstatus)
+ }
+ end
+
+ def with_stdin(filename)
+ open(filename) {|f|
+ begin
+ old = STDIN.dup
+ begin
+ STDIN.reopen(filename)
+ yield
+ ensure
+ STDIN.reopen(old)
+ end
+ ensure
+ old.close
+ end
+ }
+ end
+
+ def test_argv0_noarg
+ with_tmpchdir {|d|
+ open("t", "w") {|f| f.print "exit true" }
+ open("f", "w") {|f| f.print "exit false" }
+
+ with_stdin("t") { assert_equal(true, system([RUBY, "qaz"])) }
+ with_stdin("f") { assert_equal(false, system([RUBY, "wsx"])) }
+
+ with_stdin("t") { Process.wait spawn([RUBY, "edc"]) }
+ assert($?.success?)
+ with_stdin("f") { Process.wait spawn([RUBY, "rfv"]) }
+ assert(!$?.success?)
+
+ with_stdin("t") { IO.popen([[RUBY, "tgb"]]) {|io| assert_equal("", io.read) } }
+ assert($?.success?)
+ with_stdin("f") { IO.popen([[RUBY, "yhn"]]) {|io| assert_equal("", io.read) } }
+ assert(!$?.success?)
+
+ status = run_in_child "STDIN.reopen('t'); exec([#{RUBY.dump}, 'ujm'])"
+ assert(status.success?)
+ status = run_in_child "STDIN.reopen('f'); exec([#{RUBY.dump}, 'ik,'])"
+ assert(!status.success?)
+ }
+ end
+
+ def test_status
+ with_tmpchdir do
+ s = run_in_child("exit 1")
+ assert_equal("#<Process::Status: pid #{ s.pid } exit #{ s.exitstatus }>", s.inspect)
+
+ assert_equal(s, s)
+ assert_equal(s, s.to_i)
+
+ assert_equal(s.to_i & 0x55555555, s & 0x55555555)
+ assert_equal(s.to_i >> 1, s >> 1)
+ assert_equal(false, s.stopped?)
+ assert_equal(nil, s.stopsig)
+ end
+ end
+
+ def test_status_kill
+ return unless Process.respond_to?(:kill)
+ return unless Signal.list.include?("QUIT")
+
+ with_tmpchdir do
+ write_file("foo", "sleep 30")
+ pid = spawn(RUBY, "foo")
+ Thread.new { sleep 1; Process.kill(:SIGQUIT, pid) }
+ Process.wait(pid)
+ s = $?
+ assert_send(
+ [["#<Process::Status: pid #{ s.pid } SIGQUIT (signal #{ s.termsig })>",
+ "#<Process::Status: pid #{ s.pid } SIGQUIT (signal #{ s.termsig }) (core dumped)>"],
+ :include?,
+ s.inspect])
+ assert_equal(false, s.exited?)
+ assert_equal(nil, s.success?)
+ end
+ end
+
+ def test_wait_without_arg
+ with_tmpchdir do
+ write_file("foo", "sleep 0.1")
+ pid = spawn(RUBY, "foo")
+ assert_equal(pid, Process.wait)
+ end
+ end
+
+ def test_wait2
+ with_tmpchdir do
+ write_file("foo", "sleep 0.1")
+ pid = spawn(RUBY, "foo")
+ assert_equal([pid, 0], Process.wait2)
+ end
+ end
+
+ def test_waitall
+ with_tmpchdir do
+ write_file("foo", "sleep 0.1")
+ ps = (0...3).map { spawn(RUBY, "foo") }.sort
+ ss = Process.waitall.sort
+ ps.zip(ss) do |p1, (p2, s)|
+ assert_equal(p1, p2)
+ assert_equal(p1, s.pid)
+ end
+ end
+ end
+
+ def test_abort
+ with_tmpchdir do
+ s = run_in_child("abort")
+ assert_not_equal(0, s.exitstatus)
+ end
+ end
+
+ def test_sleep
+ assert_raise(ArgumentError) { sleep(1, 1) }
+ end
+
+ def test_getpgid
+ assert_kind_of(Integer, Process.getpgid(Process.ppid))
+ rescue NotImplementedError
+ end
+
+ def test_getpriority
+ assert_kind_of(Integer, Process.getpriority(Process::PRIO_PROCESS, $$))
+ rescue NameError, NotImplementedError
+ end
+
+ def test_setpriority
+ if defined? Process::PRIO_USER
+ assert_nothing_raised do
+ pr = Process.getpriority(Process::PRIO_PROCESS, $$)
+ Process.setpriority(Process::PRIO_PROCESS, $$, pr)
+ end
+ end
+ end
+
+ def test_getuid
+ assert_kind_of(Integer, Process.uid)
+ end
+
+ def test_groups
+ gs = Process.groups
+ assert_instance_of(Array, gs)
+ gs.each {|g| assert_kind_of(Integer, g) }
+ rescue NotImplementedError
+ end
+
+ def test_maxgroups
+ assert_kind_of(Integer, Process.maxgroups)
+ end
+
+ def test_geteuid
+ assert_kind_of(Integer, Process.egid)
+ end
+
+ def test_uid_re_exchangeable_p
+ r = Process::UID.re_exchangeable?
+ assert(true == r || false == r)
+ end
+
+ def test_gid_re_exchangeable_p
+ r = Process::GID.re_exchangeable?
+ assert(true == r || false == r)
+ end
+
+ def test_uid_sid_available?
+ r = Process::UID.sid_available?
+ assert(true == r || false == r)
+ end
+
+ def test_gid_sid_available?
+ r = Process::GID.sid_available?
+ assert(true == r || false == r)
+ end
+
+ def test_pst_inspect
+ assert_nothing_raised { Process::Status.allocate.inspect }
+ end
+end
diff --git a/trunk/test/ruby/test_rand.rb b/trunk/test/ruby/test_rand.rb
new file mode 100644
index 0000000000..b7d841dbba
--- /dev/null
+++ b/trunk/test/ruby/test_rand.rb
@@ -0,0 +1,167 @@
+require 'test/unit'
+
+class TestRand < Test::Unit::TestCase
+ def test_mt
+ srand(0x00000456_00000345_00000234_00000123)
+ %w(1067595299 955945823 477289528 4107218783 4228976476).each {|w|
+ assert_equal(w.to_i, rand(0x100000000))
+ }
+ end
+
+ def test_0x3fffffff
+ srand(0)
+ %w(209652396 398764591 924231285 404868288 441365315).each {|w|
+ assert_equal(w.to_i, rand(0x3fffffff))
+ }
+ end
+
+ def test_0x40000000
+ srand(0)
+ %w(209652396 398764591 924231285 404868288 441365315).each {|w|
+ assert_equal(w.to_i, rand(0x40000000))
+ }
+ end
+
+ def test_0x40000001
+ srand(0)
+ %w(209652396 398764591 924231285 441365315 192771779).each {|w|
+ assert_equal(w.to_i, rand(0x40000001))
+ }
+ end
+
+ def test_0xffffffff
+ srand(0)
+ %w(2357136044 2546248239 3071714933 3626093760 2588848963).each {|w|
+ assert_equal(w.to_i, rand(0xffffffff))
+ }
+ end
+
+ def test_0x100000000
+ srand(0)
+ %w(2357136044 2546248239 3071714933 3626093760 2588848963).each {|w|
+ assert_equal(w.to_i, rand(0x100000000))
+ }
+ end
+
+ def test_0x100000001
+ srand(0)
+ %w(2546248239 1277901399 243580376 1171049868 2051556033).each {|w|
+ assert_equal(w.to_i, rand(0x100000001))
+ }
+ end
+
+ def test_rand_0x100000000
+ srand(311702798)
+ %w(4119812344 3870378946 80324654 4294967296 410016213).each {|w|
+ assert_equal(w.to_i, rand(0x100000001))
+ }
+ end
+
+ def test_0x1000000000000
+ srand(0)
+ %w(11736396900911
+ 183025067478208
+ 197104029029115
+ 130583529618791
+ 180361239846611).each {|w|
+ assert_equal(w.to_i, rand(0x1000000000000))
+ }
+ end
+
+ def test_0x1000000000001
+ srand(0)
+ %w(187121911899765
+ 197104029029115
+ 180361239846611
+ 236336749852452
+ 208739549485656).each {|w|
+ assert_equal(w.to_i, rand(0x1000000000001))
+ }
+ end
+
+ def test_0x3fffffffffffffff
+ srand(0)
+ %w(900450186894289455
+ 3969543146641149120
+ 1895649597198586619
+ 827948490035658087
+ 3203365596207111891).each {|w|
+ assert_equal(w.to_i, rand(0x3fffffffffffffff))
+ }
+ end
+
+ def test_0x4000000000000000
+ srand(0)
+ %w(900450186894289455
+ 3969543146641149120
+ 1895649597198586619
+ 827948490035658087
+ 3203365596207111891).each {|w|
+ assert_equal(w.to_i, rand(0x4000000000000000))
+ }
+ end
+
+ def test_0x4000000000000001
+ srand(0)
+ %w(900450186894289455
+ 3969543146641149120
+ 1895649597198586619
+ 827948490035658087
+ 2279347887019741461).each {|w|
+ assert_equal(w.to_i, rand(0x4000000000000001))
+ }
+ end
+
+ def test_neg_0x10000000000
+ ws = %w(455570294424 1073054410371 790795084744 2445173525 1088503892627)
+ srand(3)
+ ws.each {|w| assert_equal(w.to_i, rand(0x10000000000)) }
+ srand(3)
+ ws.each {|w| assert_equal(w.to_i, rand(-0x10000000000)) }
+ end
+
+ def test_neg_0x10000
+ ws = %w(2732 43567 42613 52416 45891)
+ srand(0)
+ ws.each {|w| assert_equal(w.to_i, rand(0x10000)) }
+ srand(0)
+ ws.each {|w| assert_equal(w.to_i, rand(-0x10000)) }
+ end
+
+ def test_types
+ srand(0)
+ assert_equal(44, rand(100.0))
+ assert_equal(1245085576965981900420779258691, rand((2**100).to_f))
+ assert_equal(914679880601515615685077935113, rand(-(2**100).to_f))
+
+ srand(0)
+ assert_equal(997707939797331598305742933184, rand(2**100))
+ assert_in_delta(0.602763376071644, rand((2**100).coerce(0).first),
+ 0.000000000000001)
+
+ srand(0)
+ assert_in_delta(0.548813503927325, rand(nil),
+ 0.000000000000001)
+ srand(0)
+ o = Object.new
+ def o.to_i; 100; end
+ assert_equal(44, rand(o))
+ assert_equal(47, rand(o))
+ assert_equal(64, rand(o))
+ end
+
+ def test_srand
+ srand
+ assert_kind_of(Integer, rand(2))
+
+ srand(2**100)
+ %w(3258412053).each {|w|
+ assert_equal(w.to_i, rand(0x100000000))
+ }
+ end
+
+ def test_shuffle
+ srand(0)
+ assert_equal([1,4,2,5,3], [1,2,3,4,5].shuffle)
+ end
+end
diff --git a/trunk/test/ruby/test_range.rb b/trunk/test/ruby/test_range.rb
new file mode 100644
index 0000000000..81be101857
--- /dev/null
+++ b/trunk/test/ruby/test_range.rb
@@ -0,0 +1,270 @@
+require 'test/unit'
+
+class TestRange < Test::Unit::TestCase
+ def test_range_string
+ # XXX: Is this really the test of Range?
+ assert_equal([], ("a" ... "a").to_a)
+ assert_equal(["a"], ("a" .. "a").to_a)
+ assert_equal(["a"], ("a" ... "b").to_a)
+ assert_equal(["a", "b"], ("a" .. "b").to_a)
+ end
+
+ def test_evaluation_order
+ arr = [1,2]
+ r = (arr.shift)..(arr.shift)
+ assert_equal(1..2, r, "[ruby-dev:26383]")
+ end
+
+ class DuckRange
+ def initialize(b,e,excl=false)
+ @begin = b
+ @end = e
+ @excl = excl
+ end
+ attr_reader :begin, :end
+
+ def exclude_end?
+ @excl
+ end
+ end
+
+ def test_duckrange
+ assert_equal("bc", "abcd"[DuckRange.new(1,2)])
+ end
+
+ def test_min
+ assert_equal(1, (1..2).min)
+ assert_equal(nil, (2..1).min)
+ assert_equal(1, (1...2).min)
+
+ assert_equal(1.0, (1.0..2.0).min)
+ assert_equal(nil, (2.0..1.0).min)
+ assert_equal(1, (1.0...2.0).min)
+
+ assert_equal(0, (0..0).min)
+ assert_equal(nil, (0...0).min)
+ end
+
+ def test_max
+ assert_equal(2, (1..2).max)
+ assert_equal(nil, (2..1).max)
+ assert_equal(1, (1...2).max)
+
+ assert_equal(2.0, (1.0..2.0).max)
+ assert_equal(nil, (2.0..1.0).max)
+ assert_raise(TypeError) { (1.0...2.0).max }
+
+ assert_equal(-0x80000002, ((-0x80000002)...(-0x80000001)).max)
+
+ assert_equal(0, (0..0).max)
+ assert_equal(nil, (0...0).max)
+ end
+
+ def test_initialize_twice
+ r = eval("1..2")
+ assert_raise(NameError) { r.instance_eval { initialize 3, 4 } }
+ end
+
+ def test_uninitialized_range
+ r = Range.allocate
+ s = Marshal.dump(r)
+ r = Marshal.load(s)
+ assert_nothing_raised { r.instance_eval { initialize 5, 6} }
+ end
+
+ def test_bad_value
+ assert_raise(ArgumentError) { (1 .. :a) }
+ end
+
+ def test_exclude_end
+ assert(!((0..1).exclude_end?))
+ assert((0...1).exclude_end?)
+ end
+
+ def test_eq
+ r = (0..1)
+ assert(r == r)
+ assert(r == (0..1))
+ assert(r != 0)
+ assert(r != (1..2))
+ assert(r != (0..2))
+ assert(r != (0...1))
+ end
+
+ def test_eql
+ r = (0..1)
+ assert(r.eql?(r))
+ assert(r.eql?(0..1))
+ assert(!r.eql?(0))
+ assert(!r.eql?(1..2))
+ assert(!r.eql?(0..2))
+ assert(!r.eql?(0...1))
+ end
+
+ def test_hash
+ assert((0..1).hash.is_a?(Fixnum))
+ end
+
+ def test_step
+ a = []
+ (0..10).step {|x| a << x }
+ assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a)
+
+ a = []
+ (0..10).step(2) {|x| a << x }
+ assert_equal([0, 2, 4, 6, 8, 10], a)
+
+ assert_raise(ArgumentError) { (0..10).step(-1) { } }
+ assert_raise(ArgumentError) { (0..10).step(0) { } }
+
+ a = []
+ ("a" .. "z").step(2) {|x| a << x }
+ assert_equal(%w(a c e g i k m o q s u w y), a)
+
+ a = []
+ ("a" .. "z").step(2**32) {|x| a << x }
+ assert_equal(["a"], a)
+
+ a = []
+ (2**32-1 .. 2**32+1).step(2) {|x| a << x }
+ assert_equal([4294967295, 4294967297], a)
+ zero = (2**32).coerce(0).first
+ assert_raise(ArgumentError) { (2**32-1 .. 2**32+1).step(zero) { } }
+
+ o1 = Object.new
+ o2 = Object.new
+ def o1.<=>(x); -1; end
+ def o2.<=>(x); 0; end
+ assert_raise(TypeError) { (o1..o2).step(1) { } }
+
+ class << o1; self; end.class_eval do
+ define_method(:succ) { o2 }
+ end
+ a = []
+ (o1..o2).step(1) {|x| a << x }
+ assert_equal([o1, o2], a)
+
+ a = []
+ (o1...o2).step(1) {|x| a << x }
+ assert_equal([o1], a)
+
+ assert_nothing_raised("[ruby-dev:34557]") { (0..2).step(0.5) {|x| } }
+
+ a = []
+ (0..2).step(0.5) {|x| a << x }
+ assert_equal([0, 0.5, 1.0, 1.5, 2.0], a)
+
+ a = []
+ (0x40000000..0x40000002).step(0.5) {|x| a << x }
+ assert_equal([1073741824, 1073741824.5, 1073741825.0, 1073741825.5, 1073741826], a)
+
+ o = Object.new
+ def o.to_int() 1 end
+ assert_nothing_raised("[ruby-dev:34558]") { (0..2).step(o) {|x| } }
+ end
+
+ def test_each
+ a = []
+ (0..10).each {|x| a << x }
+ assert_equal([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a)
+
+ o1 = Object.new
+ o2 = Object.new
+ def o1.<=>(x); -1; end
+ def o2.<=>(x); 0; end
+ class << o1; self; end.class_eval do
+ define_method(:succ) { o2 }
+ end
+
+ r1 = (o1..o2)
+ r2 = (o1...o2)
+
+ a = []
+ r1.each {|x| a << x }
+ assert_equal([o1, o2], a)
+
+ a = []
+ r2.each {|x| a << x }
+ assert_equal([o1], a)
+
+ def o2.<=>(x); 1; end
+
+ a = []
+ r1.each {|x| a << x }
+ assert_equal([o1], a)
+
+ def o2.<=>(x); nil; end
+
+ a = []
+ r1.each {|x| a << x }
+ assert_equal([o1], a)
+
+ def o1.<=>(x); nil; end
+
+ a = []
+ r2.each {|x| a << x }
+ assert_equal([], a)
+ end
+
+ def test_begin_end
+ assert_equal(0, (0..1).begin)
+ assert_equal(1, (0..1).end)
+ end
+
+ def test_first_last
+ assert_equal([0, 1, 2], (0..10).first(3))
+ assert_equal([8, 9, 10], (0..10).last(3))
+ end
+
+ def test_to_s
+ assert_equal("0..1", (0..1).to_s)
+ assert_equal("0...1", (0...1).to_s)
+ end
+
+ def test_inspect
+ assert_equal("0..1", (0..1).inspect)
+ assert_equal("0...1", (0...1).inspect)
+ end
+
+ def test_eqq
+ assert((0..10) === 5)
+ assert(!((0..10) === 11))
+ end
+
+ def test_include
+ assert(("a".."z").include?("c"))
+ assert(!(("a".."z").include?("5")))
+ assert(("a"..."z").include?("y"))
+ assert(!(("a"..."z").include?("z")))
+ assert(!(("a".."z").include?("cc")))
+ assert((0...10).include?(5))
+ end
+
+ def test_cover
+ assert(("a".."z").cover?("c"))
+ assert(!(("a".."z").cover?("5")))
+ assert(("a"..."z").cover?("y"))
+ assert(!(("a"..."z").cover?("z")))
+ assert(("a".."z").cover?("cc"))
+ end
+
+ def test_beg_len
+ o = Object.new
+ assert_raise(TypeError) { [][o] }
+ def o.begin; -10; end
+ assert_raise(TypeError) { [][o] }
+ def o.end; 0; end
+ assert_raise(NoMethodError) { [][o] }
+ def o.exclude_end?; false; end
+ assert_nil([0][o])
+ assert_raise(RangeError) { [0][o] = 1 }
+ def o.begin; 10; end
+ def o.end; 10; end
+ assert_nil([0][o])
+ def o.begin; 0; end
+ assert_equal([0], [0][o])
+ def o.begin; 2; end
+ def o.end; 0; end
+ assert_equal([], [0, 1, 2][o])
+ end
+end
diff --git a/trunk/test/ruby/test_rational.rb b/trunk/test/ruby/test_rational.rb
new file mode 100644
index 0000000000..eb52e3e193
--- /dev/null
+++ b/trunk/test/ruby/test_rational.rb
@@ -0,0 +1,1074 @@
+require 'test/unit'
+
+class RationalSub < Rational; end
+
+class Rational_Test < Test::Unit::TestCase
+
+ def test_ratsub
+ c = RationalSub.__send__(:new, 1)
+ cc = RationalSub.__send__(:convert, 1)
+ if defined?(RationalSub::Unify)
+ assert_instance_of(Fixnum, c)
+ assert_instance_of(Fixnum, cc)
+ else
+ assert_instance_of(RationalSub, c)
+ assert_instance_of(RationalSub, cc)
+
+ c2 = c + 1
+ assert_instance_of(RationalSub, c2)
+ c2 = c - 1
+ assert_instance_of(RationalSub, c2)
+
+ c3 = c - c2
+ assert_instance_of(RationalSub, c3)
+
+ s = Marshal.dump(c)
+ c5 = Marshal.load(s)
+ assert_equal(c, c5)
+ assert_instance_of(RationalSub, c5)
+ end
+ end
+
+ def test_hash
+ assert_instance_of(Fixnum, Rational(1,2).hash)
+
+ h = {}
+ h[Rational(0)] = 0
+ h[Rational(1,1)] = 1
+ h[Rational(2,1)] = 2
+ h[Rational(3,1)] = 3
+
+ assert_equal(4, h.size)
+ assert_equal(2, h[Rational(2,1)])
+
+ h[Rational(0,1)] = 9
+ assert_equal(4, h.size)
+ end
+
+ def test_freeze
+ c = Rational(1)
+ c.freeze
+ unless defined?(Rational::Unify)
+ assert_equal(true, c.frozen?)
+ end
+ assert_instance_of(String, c.to_s)
+ end
+
+ def test_new_bang # no unify & no reduce
+ assert_instance_of(Rational, Rational.__send__(:new!, 2,1))
+ assert_equal([2,1], Rational.__send__(:new!, 2,1).
+ instance_eval{[numerator, denominator]})
+ assert_equal([2,4], Rational.__send__(:new!, 2,4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([-2,4], Rational.__send__(:new!, -2,4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([-2,4], Rational.__send__(:new!, 2,-4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([2,4], Rational.__send__(:new!, -2,-4).
+ instance_eval{[numerator, denominator]})
+
+ # to_i
+ assert_equal([2,1], Rational.__send__(:new!, Rational(2)).
+ instance_eval{[numerator, denominator]})
+ assert_equal([2,3], Rational.__send__(:new!, Rational(2), Rational(3)).
+ instance_eval{[numerator, denominator]})
+ assert_equal([2,3], Rational.__send__(:new!, 2, Rational(3)).
+ instance_eval{[numerator, denominator]})
+
+ assert_equal([1,1], Rational.__send__(:new!, 1.1).
+ instance_eval{[numerator, denominator]})
+ assert_equal([-1,1], Rational.__send__(:new!, -1.1).
+ instance_eval{[numerator, denominator]})
+ assert_equal([1,1], Rational.__send__(:new!, '1').
+ instance_eval{[numerator, denominator]})
+ assert_equal([0,1], Rational.__send__(:new!, nil).
+ instance_eval{[numerator, denominator]})
+
+ assert_raise(ZeroDivisionError){Rational.__send__(:new!, 1, 0)}
+ end
+
+=begin
+ def test_reduce
+ if defined?(Rational::Unify)
+ assert_instance_of(Fixnum, Rational.__send__(:reduce, 2,1))
+ else
+ assert_instance_of(Rational, Rational.__send__(:reduce, 2,1))
+ assert_instance_of(Rational, Rational.__send__(:reduce, 2,1))
+ end
+ assert_equal([2,1], Rational.__send__(:reduce, 2,1).
+ instance_eval{[numerator, denominator]})
+ assert_equal([1,2], Rational.__send__(:reduce, 2,4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([-1,2], Rational.__send__(:reduce, -2,4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([-1,2], Rational.__send__(:reduce, 2,-4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([1,2], Rational.__send__(:reduce, -2,-4).
+ instance_eval{[numerator, denominator]})
+
+ assert_raise(ArgumentError){Rational.__send__(:reduce, Rational(1,2),2)}
+ assert_raise(ArgumentError){Rational.__send__(:reduce, 2,Rational(1,2))}
+ assert_raise(ArgumentError){Rational.
+ __send__(:reduce, Rational(1,2),Rational(1,2))}
+
+ assert_raise(ArgumentError){Rational.__send__(:reduce, 1.1)}
+ assert_raise(ArgumentError){Rational.__send__(:reduce, -1.1)}
+ assert_raise(ArgumentError){Rational.__send__(:reduce, '1')}
+ assert_raise(ArgumentError){Rational.__send__(:reduce, nil)}
+ end
+=end
+
+ def test_new
+ if defined?(Rational::Unify)
+ assert_instance_of(Fixnum, Rational.__send__(:new, 2,1))
+ else
+ assert_instance_of(Rational, Rational.__send__(:new, 2,1))
+ assert_equal([2,1], Rational.__send__(:new, 2,1).
+ instance_eval{[numerator, denominator]})
+ end
+ assert_equal([1,2], Rational.__send__(:new, 2,4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([-1,2], Rational.__send__(:new, -2,4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([-1,2], Rational.__send__(:new, 2,-4).
+ instance_eval{[numerator, denominator]})
+ assert_equal([1,2], Rational.__send__(:new, -2,-4).
+ instance_eval{[numerator, denominator]})
+
+ assert_raise(ArgumentError){Rational.__send__(:new, Rational(1,2),2)}
+ assert_raise(ArgumentError){Rational.__send__(:new, 2,Rational(1,2))}
+ assert_raise(ArgumentError){Rational.__send__(:new, Rational(1,2),Rational(1,2))}
+
+ assert_raise(ArgumentError){Rational.__send__(:new, 1.1)}
+ assert_raise(ArgumentError){Rational.__send__(:new, -1.1)}
+ assert_raise(ArgumentError){Rational.__send__(:new, '1')}
+ assert_raise(ArgumentError){Rational.__send__(:new, nil)}
+=begin
+ assert_raise(ArgumentError){Rational.__send__(:new, Rational(1))}
+ if defined?(Complex)
+ assert_raise(ArgumentError){Rational.__send__(:new, Complex(1))}
+ end
+=end
+ end
+
+ def test_conv
+ c = Rational(0,1)
+ assert_equal(Rational.__send__(:new, 0,1), c)
+
+ c = Rational(2**32, 2**32)
+ assert_equal(Rational.__send__(:new, 2**32,2**32), c)
+ assert_equal([1,1], [c.numerator,c.denominator])
+
+ c = Rational(-2**32, 2**32)
+ assert_equal(Rational.__send__(:new, -2**32,2**32), c)
+ assert_equal([-1,1], [c.numerator,c.denominator])
+
+ c = Rational(2**32, -2**32)
+ assert_equal(Rational.__send__(:new, 2**32,-2**32), c)
+ assert_equal([-1,1], [c.numerator,c.denominator])
+
+ c = Rational(-2**32, -2**32)
+ assert_equal(Rational.__send__(:new, -2**32,-2**32), c)
+ assert_equal([1,1], [c.numerator,c.denominator])
+
+ c = Rational(Rational(1,2),2)
+ assert_equal(Rational.__send__(:new, 1,4), c)
+
+ c = Rational(2,Rational(1,2))
+ assert_equal(Rational.__send__(:new, 4), c)
+
+ c = Rational(Rational(1,2),Rational(1,2))
+ assert_equal(Rational.__send__(:new, 1), c)
+
+ assert_equal(Rational.__send__(:new, 1),Rational(1))
+ assert_equal(1.1.to_r,Rational(1.1))
+ assert_equal(Rational.__send__(:new, 1),Rational('1'))
+ assert_raise(ArgumentError){Rational(nil)}
+ end
+
+ def test_attr
+ c = Rational(4)
+
+ assert_equal(4, c.numerator)
+ assert_equal(1, c.denominator)
+
+ c = Rational(4,5)
+
+ assert_equal(4, c.numerator)
+ assert_equal(5, c.denominator)
+
+ c = Rational.__send__(:new, 4)
+
+ assert_equal(4, c.numerator)
+ assert_equal(1, c.denominator)
+
+ c = Rational.__send__(:new, 4,5)
+
+ assert_equal(4, c.numerator)
+ assert_equal(5, c.denominator)
+
+ c = Rational.__send__(:new!, 4)
+
+ assert_equal(4, c.numerator)
+ assert_equal(1, c.denominator)
+
+ c = Rational.__send__(:new!, 4,5)
+
+ assert_equal(4, c.numerator)
+ assert_equal(5, c.denominator)
+ end
+
+ def test_attr2
+ c = Rational(1)
+
+ if defined?(Rational::Unify)
+ assert_equal(true, c.scalar?)
+=begin
+ assert_equal(true, c.finite?)
+ assert_equal(false, c.infinite?)
+ assert_equal(false, c.nan?)
+ assert_equal(true, c.integer?)
+ assert_equal(false, c.float?)
+ assert_equal(true, c.rational?)
+ assert_equal(true, c.real?)
+ assert_equal(false, c.complex?)
+ assert_equal(true, c.exact?)
+ assert_equal(false, c.inexact?)
+=end
+ else
+ assert_equal(true, c.scalar?)
+=begin
+ assert_equal(true, c.finite?)
+ assert_equal(false, c.infinite?)
+ assert_equal(false, c.nan?)
+ assert_equal(false, c.integer?)
+ assert_equal(false, c.float?)
+ assert_equal(true, c.rational?)
+ assert_equal(true, c.real?)
+ assert_equal(false, c.complex?)
+ assert_equal(true, c.exact?)
+ assert_equal(false, c.inexact?)
+=end
+ end
+
+=begin
+ assert_equal(true, Rational(0).positive?)
+ assert_equal(true, Rational(1).positive?)
+ assert_equal(false, Rational(-1).positive?)
+ assert_equal(false, Rational(0).negative?)
+ assert_equal(false, Rational(1).negative?)
+ assert_equal(true, Rational(-1).negative?)
+
+ assert_equal(0, Rational(0).sign)
+ assert_equal(1, Rational(2).sign)
+ assert_equal(-1, Rational(-2).sign)
+=end
+
+ assert_equal(true, Rational(0).zero?)
+ assert_equal(true, Rational(0,1).zero?)
+ assert_equal(false, Rational(1,1).zero?)
+
+ assert_equal(nil, Rational(0).nonzero?)
+ assert_equal(nil, Rational(0,1).nonzero?)
+ assert_equal(Rational(1,1), Rational(1,1).nonzero?)
+ end
+
+ def test_uplus
+ assert_equal(Rational(1), +Rational(1))
+ assert_equal(Rational(-1), +Rational(-1))
+ assert_equal(Rational(1,1), +Rational(1,1))
+ assert_equal(Rational(-1,1), +Rational(-1,1))
+ assert_equal(Rational(-1,1), +Rational(1,-1))
+ assert_equal(Rational(1,1), +Rational(-1,-1))
+ end
+
+ def test_negate
+ assert_equal(Rational(-1), -Rational(1))
+ assert_equal(Rational(1), -Rational(-1))
+ assert_equal(Rational(-1,1), -Rational(1,1))
+ assert_equal(Rational(1,1), -Rational(-1,1))
+ assert_equal(Rational(1,1), -Rational(1,-1))
+ assert_equal(Rational(-1,1), -Rational(-1,-1))
+
+=begin
+ assert_equal(0, Rational(0).negate)
+ assert_equal(-2, Rational(2).negate)
+ assert_equal(2, Rational(-2).negate)
+=end
+ end
+
+ def test_add
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(7,6), c + c2)
+
+ assert_equal(Rational(5,2), c + 2)
+ assert_equal(2.5, c + 2.0)
+ end
+
+ def test_sub
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(-1,6), c - c2)
+
+ assert_equal(Rational(-3,2), c - 2)
+ assert_equal(-1.5, c - 2.0)
+ end
+
+ def test_mul
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(1,3), c * c2)
+
+ assert_equal(Rational(1,1), c * 2)
+ assert_equal(1.0, c * 2.0)
+ end
+
+ def test_div
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(3,4), c / c2)
+
+ assert_equal(Rational(1,4), c / 2)
+ assert_equal(0.25, c / 2.0)
+ end
+
+ def assert_eql(exp, act, *args)
+ unless Array === exp
+ exp = [exp]
+ end
+ unless Array === act
+ act = [act]
+ end
+ exp.zip(act).each do |e, a|
+ na = [e, a] + args
+ assert_equal(*na)
+ na = [e.class, a] + args
+ assert_instance_of(*na)
+ end
+ end
+
+ def test_idiv
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql(0, c.div(c2))
+ assert_eql(0, c.div(2))
+ assert_eql(0, c.div(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal(2, c.div(c2))
+ assert_equal(-3, c.div(-c2))
+ assert_equal(-3, (-c).div(c2))
+ assert_equal(2, (-c).div(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal(1, c.div(c2))
+ assert_equal(-2, c.div(-c2))
+ assert_equal(-2, (-c).div(c2))
+ assert_equal(1, (-c).div(-c2))
+
+ unless defined?(Rational::Unify)
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal(3, c.div(c2))
+ assert_equal(-4, c.div(-c2))
+ assert_equal(-4, (-c).div(c2))
+ assert_equal(3, (-c).div(-c2))
+ end
+ end
+
+ def test_divmod
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql([0, Rational(1,2)], c.divmod(c2))
+ assert_eql([0, Rational(1,2)], c.divmod(2))
+ assert_eql([0, 0.5], c.divmod(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal([2, Rational(21,100)], c.divmod(c2))
+ assert_equal([-3, Rational(-119,100)], c.divmod(-c2))
+ assert_equal([-3, Rational(119,100)], (-c).divmod(c2))
+ assert_equal([2, Rational(-21,100)], (-c).divmod(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal([1, Rational(101,100)], c.divmod(c2))
+ assert_equal([-2, Rational(-99,100)], c.divmod(-c2))
+ assert_equal([-2, Rational(99,100)], (-c).divmod(c2))
+ assert_equal([1, Rational(-101,100)], (-c).divmod(-c2))
+
+ unless defined?(Rational::Unify)
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal([3,2], c.divmod(c2))
+ assert_equal([-4,-1], c.divmod(-c2))
+ assert_equal([-4,1], (-c).divmod(c2))
+ assert_equal([3,-2], (-c).divmod(-c2))
+ end
+ end
+
+=begin
+ def test_quot
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql(0, c.quot(c2))
+ assert_eql(0, c.quot(2))
+ assert_eql(0, c.quot(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal(2, c.quot(c2))
+ assert_equal(-2, c.quot(-c2))
+ assert_equal(-2, (-c).quot(c2))
+ assert_equal(2, (-c).quot(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal(1, c.quot(c2))
+ assert_equal(-1, c.quot(-c2))
+ assert_equal(-1, (-c).quot(c2))
+ assert_equal(1, (-c).quot(-c2))
+
+ unless defined?(Rational::Unify)
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal(3, c.quot(c2))
+ assert_equal(-3, c.quot(-c2))
+ assert_equal(-3, (-c).quot(c2))
+ assert_equal(3, (-c).quot(-c2))
+ end
+ end
+
+ def test_quotrem
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_eql([0, Rational(1,2)], c.quotrem(c2))
+ assert_eql([0, Rational(1,2)], c.quotrem(2))
+ assert_eql([0, 0.5], c.quotrem(2.0))
+
+ c = Rational(301,100)
+ c2 = Rational(7,5)
+
+ assert_equal([2, Rational(21,100)], c.quotrem(c2))
+ assert_equal([-2, Rational(21,100)], c.quotrem(-c2))
+ assert_equal([-2, Rational(-21,100)], (-c).quotrem(c2))
+ assert_equal([2, Rational(-21,100)], (-c).quotrem(-c2))
+
+ c = Rational(301,100)
+ c2 = Rational(2)
+
+ assert_equal([1, Rational(101,100)], c.quotrem(c2))
+ assert_equal([-1, Rational(101,100)], c.quotrem(-c2))
+ assert_equal([-1, Rational(-101,100)], (-c).quotrem(c2))
+ assert_equal([1, Rational(-101,100)], (-c).quotrem(-c2))
+
+ unless defined?(Rational::Unify)
+ c = Rational(11)
+ c2 = Rational(3)
+
+ assert_equal([3,2], c.quotrem(c2))
+ assert_equal([-3,2], c.quotrem(-c2))
+ assert_equal([-3,-2], (-c).quotrem(c2))
+ assert_equal([3,-2], (-c).quotrem(-c2))
+ end
+ end
+=end
+
+ def test_quo
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(Rational(3,4), c.quo(c2))
+
+ assert_equal(Rational(1,4), c.quo(2))
+ assert_equal(Rational(0.25), c.quo(2.0))
+ end
+
+ def test_fdiv
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ assert_equal(0.75, c.fdiv(c2))
+
+ assert_equal(0.25, c.fdiv(2))
+ assert_equal(0.25, c.fdiv(2.0))
+ end
+
+ def test_expt
+ c = Rational(1,2)
+ c2 = Rational(2,3)
+
+ r = c ** c2
+ assert_in_delta(0.6299, r, 0.001)
+
+ assert_equal(Rational(1,4), c ** 2)
+ assert_equal(Rational(4), c ** -2)
+ assert_equal(Rational(1,4), (-c) ** 2)
+ assert_equal(Rational(4), (-c) ** -2)
+
+ assert_equal(0.25, c ** 2.0)
+ assert_equal(4.0, c ** -2.0)
+
+ assert_equal(Rational(1,4), c ** Rational(2))
+ assert_equal(Rational(4), c ** Rational(-2))
+
+ assert_equal(Rational(1), 0 ** Rational(0))
+ assert_equal(Rational(1), Rational(0) ** 0)
+ assert_equal(Rational(1), Rational(0) ** Rational(0))
+
+ # p ** p
+ x = 2 ** Rational(2)
+ assert_equal(Rational(4), x)
+ unless defined?(Rational::Unify)
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ x = Rational(2) ** 2
+ assert_equal(Rational(4), x)
+ unless defined?(Rational::Unify)
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ x = Rational(2) ** Rational(2)
+ assert_equal(Rational(4), x)
+ unless defined?(Rational::Unify)
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ # -p ** p
+ x = (-2) ** Rational(2)
+ assert_equal(Rational(4), x)
+ unless defined?(Rational::Unify)
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ x = Rational(-2) ** 2
+ assert_equal(Rational(4), x)
+ unless defined?(Rational::Unify)
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ x = Rational(-2) ** Rational(2)
+ assert_equal(Rational(4), x)
+ unless defined?(Rational::Unify)
+ assert_instance_of(Rational, x)
+ end
+ assert_equal(4, x.numerator)
+ assert_equal(1, x.denominator)
+
+ # p ** -p
+ x = 2 ** Rational(-2)
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ x = Rational(2) ** -2
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ x = Rational(2) ** Rational(-2)
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ # -p ** -p
+ x = (-2) ** Rational(-2)
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ x = Rational(-2) ** -2
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ x = Rational(-2) ** Rational(-2)
+ assert_equal(Rational(1,4), x)
+ assert_instance_of(Rational, x)
+ assert_equal(1, x.numerator)
+ assert_equal(4, x.denominator)
+
+ unless defined?(Rational::Unify) # maybe bug mathn
+ assert_raise(ZeroDivisionError){0 ** -1}
+ end
+ end
+
+ def test_cmp
+ assert_equal(-1, Rational(-1) <=> Rational(0))
+ assert_equal(0, Rational(0) <=> Rational(0))
+ assert_equal(+1, Rational(+1) <=> Rational(0))
+
+ assert_equal(-1, Rational(-1) <=> 0)
+ assert_equal(0, Rational(0) <=> 0)
+ assert_equal(+1, Rational(+1) <=> 0)
+
+ assert_equal(-1, Rational(-1) <=> 0.0)
+ assert_equal(0, Rational(0) <=> 0.0)
+ assert_equal(+1, Rational(+1) <=> 0.0)
+
+ assert_equal(-1, Rational(1,2) <=> Rational(2,3))
+ assert_equal(0, Rational(2,3) <=> Rational(2,3))
+ assert_equal(+1, Rational(2,3) <=> Rational(1,2))
+
+ f = 2**30-1
+ b = 2**30
+
+ assert_equal(0, Rational(f) <=> Rational(f))
+ assert_equal(-1, Rational(f) <=> Rational(b))
+ assert_equal(+1, Rational(b) <=> Rational(f))
+ assert_equal(0, Rational(b) <=> Rational(b))
+
+ assert_equal(-1, Rational(f-1) <=> Rational(f))
+ assert_equal(+1, Rational(f) <=> Rational(f-1))
+ assert_equal(-1, Rational(b-1) <=> Rational(b))
+ assert_equal(+1, Rational(b) <=> Rational(b-1))
+
+ assert_equal(false, Rational(0) < Rational(0))
+ assert_equal(true, Rational(0) <= Rational(0))
+ assert_equal(true, Rational(0) >= Rational(0))
+ assert_equal(false, Rational(0) > Rational(0))
+ end
+
+ def test_equal
+ assert(Rational(1,1) == Rational(1))
+ assert(Rational(1,1) == Rational.__send__(:new, 1))
+ assert(Rational(1,1) == Rational.__send__(:new, 1,1))
+ assert(Rational(1,1) == Rational.__send__(:new!, 1))
+ assert(Rational(1,1) == Rational.__send__(:new!, 1,1))
+
+ assert(Rational(-1,1) == Rational(-1))
+ assert(Rational(-1,1) == Rational.__send__(:new, -1))
+ assert(Rational(-1,1) == Rational.__send__(:new, -1,1))
+ assert(Rational(-1,1) == Rational.__send__(:new!, -1))
+ assert(Rational(-1,1) == Rational.__send__(:new!, -1,1))
+
+ assert_equal(false, Rational(2,1) == Rational(1))
+ assert_equal(true, Rational(2,1) != Rational(1))
+ assert_equal(false, Rational(1) == nil)
+ assert_equal(false, Rational(1) == '')
+ end
+
+ def test_unify
+ if defined?(Rational::Unify)
+ assert_instance_of(Fixnum, Rational(1,2) + Rational(1,2))
+ assert_instance_of(Fixnum, Rational(1,2) - Rational(1,2))
+ assert_instance_of(Fixnum, Rational(1,2) * 2)
+ assert_instance_of(Fixnum, Rational(1,2) / Rational(1,2))
+ assert_instance_of(Fixnum, Rational(1,2).div(Rational(1,2)))
+ assert_instance_of(Fixnum, Rational(1,2).quo(Rational(1,2)))
+ assert_instance_of(Fixnum, Rational(1,2) ** -2)
+ end
+ end
+
+ def test_to_s
+ c = Rational(1,2)
+
+ assert_instance_of(String, c.to_s)
+ assert_equal('1/2', c.to_s)
+
+ if defined?(Rational::Unify)
+ assert_equal('0', Rational(0,2).to_s)
+ assert_equal('0', Rational(0,-2).to_s)
+ else
+ assert_equal('0/1', Rational(0,2).to_s)
+ assert_equal('0/1', Rational(0,-2).to_s)
+ end
+ assert_equal('1/2', Rational(1,2).to_s)
+ assert_equal('-1/2', Rational(-1,2).to_s)
+ assert_equal('1/2', Rational(-1,-2).to_s)
+ assert_equal('-1/2', Rational(1,-2).to_s)
+ assert_equal('1/2', Rational(-1,-2).to_s)
+ end
+
+ def test_inspect
+ c = Rational(1,2)
+
+ assert_instance_of(String, c.inspect)
+ assert_equal('(1/2)', c.inspect)
+ end
+
+ def test_marshal
+ c = Rational(1,2)
+
+ s = Marshal.dump(c)
+ c2 = Marshal.load(s)
+ assert_equal(c, c2)
+ assert_instance_of(Rational, c2)
+
+ assert_raise(ZeroDivisionError){
+ Marshal.load("\x04\bU:\rRational[\ai\x06i\x05")
+ }
+ end
+
+ def test_parse
+ assert_equal(Rational(0), ''.to_r)
+ assert_equal(Rational(0), ' '.to_r)
+ assert_equal(Rational(5), '5'.to_r)
+ assert_equal(Rational(-5), '-5'.to_r)
+ assert_equal(Rational(5,3), '5/3'.to_r)
+ assert_equal(Rational(-5,3), '-5/3'.to_r)
+# assert_equal(Rational(5,-3), '5/-3'.to_r)
+# assert_equal(Rational(-5,-3), '-5/-3'.to_r)
+
+ assert_equal(Rational(5), '5.0'.to_r)
+ assert_equal(Rational(-5), '-5.0'.to_r)
+ assert_equal(Rational(5,3), '5.0/3'.to_r)
+ assert_equal(Rational(-5,3), '-5.0/3'.to_r)
+# assert_equal(Rational(5,-3), '5.0/-3'.to_r)
+# assert_equal(Rational(-5,-3), '-5.0/-3'.to_r)
+
+ assert_equal(Rational(5), '5e0'.to_r)
+ assert_equal(Rational(-5), '-5e0'.to_r)
+ assert_equal(Rational(5,3), '5e0/3'.to_r)
+ assert_equal(Rational(-5,3), '-5e0/3'.to_r)
+# assert_equal(Rational(5,-3), '5e0/-3'.to_r)
+# assert_equal(Rational(-5,-3), '-5e0/-3'.to_r)
+
+ assert_equal(Rational(33,100), '0.33'.to_r)
+ assert_equal(Rational(-33,100), '-0.33'.to_r)
+ assert_equal(Rational(-33,100), '-0.3_3'.to_r)
+
+ assert_equal(Rational(1,2), '5e-1'.to_r)
+ assert_equal(Rational(50), '5e+1'.to_r)
+ assert_equal(Rational(1,2), '5.0e-1'.to_r)
+ assert_equal(Rational(50), '5.0e+1'.to_r)
+ assert_equal(Rational(50), '5e1'.to_r)
+ assert_equal(Rational(50), '5E1'.to_r)
+ assert_equal(Rational(500), '5e2'.to_r)
+ assert_equal(Rational(5000), '5e3'.to_r)
+ assert_equal(Rational(500000000000), '5e1_1'.to_r)
+
+ assert_equal(Rational(5), Rational('5'))
+ assert_equal(Rational(-5), Rational('-5'))
+ assert_equal(Rational(5,3), Rational('5/3'))
+ assert_equal(Rational(-5,3), Rational('-5/3'))
+# assert_equal(Rational(5,-3), Rational('5/-3'))
+# assert_equal(Rational(-5,-3), Rational('-5/-3'))
+
+ assert_equal(Rational(33,100), Rational('0.33'))
+ assert_equal(Rational(-33,100), Rational('-0.33'))
+ assert_equal(Rational(-33,100), Rational('-0.3_3'))
+
+ assert_equal(Rational(1,2), Rational('5e-1'))
+ assert_equal(Rational(50), Rational('5e1'))
+ assert_equal(Rational(50), Rational('5E1'))
+ assert_equal(Rational(500), Rational('5e2'))
+ assert_equal(Rational(5000), Rational('5e3'))
+ assert_equal(Rational(500000000000), Rational('5e1_1'))
+
+ assert_equal(Rational(5.0), Rational('5.0'))
+ assert_equal(Rational(-5.0), Rational('-5.0'))
+ assert_equal(Rational(5.0,3), Rational('5.0/3'))
+ assert_equal(Rational(-5.0,3), Rational('-5.0/3'))
+# assert_equal(Rational(5.0,-3), Rational('5.0/-3'))
+# assert_equal(Rational(-5.0,-3), Rational('-5.0/-3'))
+
+ assert_equal(Rational(0), '_'.to_r)
+ assert_equal(Rational(0), '_5'.to_r)
+ assert_equal(Rational(5), '5_'.to_r)
+ assert_equal(Rational(5), '5x'.to_r)
+ assert_equal(Rational(5), '5/_3'.to_r)
+ assert_equal(Rational(5,3), '5/3_'.to_r)
+ assert_equal(Rational(5,3), '5/3.3'.to_r)
+ assert_equal(Rational(5,3), '5/3x'.to_r)
+ assert_raise(ArgumentError){ Rational('')}
+ assert_raise(ArgumentError){ Rational('_')}
+ assert_raise(ArgumentError){ Rational('_5')}
+ assert_raise(ArgumentError){ Rational('5_')}
+ assert_raise(ArgumentError){ Rational('5x')}
+ assert_raise(ArgumentError){ Rational('5/_3')}
+ assert_raise(ArgumentError){ Rational('5/3_')}
+ assert_raise(ArgumentError){ Rational('5/3.3')}
+ assert_raise(ArgumentError){ Rational('5/3x')}
+ end
+
+=begin
+ def test_reciprocal
+ assert_equal(Rational(1,9), Rational(9,1).reciprocal)
+ assert_equal(Rational(9,1), Rational(1,9).reciprocal)
+ assert_equal(Rational(-1,9), Rational(-9,1).reciprocal)
+ assert_equal(Rational(-9,1), Rational(-1,9).reciprocal)
+ end
+=end
+
+ def test_to_i
+ assert_equal(1, Rational(3,2).to_i)
+ assert_equal(1, Integer(Rational(3,2)))
+ end
+
+ def test_to_f
+ assert_equal(1.5, Rational(3,2).to_f)
+ assert_equal(1.5, Float(Rational(3,2)))
+ end
+
+ def test_to_c
+ if defined?(Complex) && !Complex.instance_variable_get('@RCS_ID')
+ if defined?(Rational::Unify)
+ assert_equal(Rational(3,2), Rational(3,2).to_c)
+ assert_equal(Rational(3,2), Complex(Rational(3,2)))
+ else
+ assert_equal(Complex(Rational(3,2)), Rational(3,2).to_c)
+ assert_equal(Complex(Rational(3,2)), Complex(Rational(3,2)))
+ end
+ end
+ end
+
+ def test_to_r
+ c = nil.to_r
+ assert_equal([0,1] , [c.numerator, c.denominator])
+
+ c = 0.to_r
+ assert_equal([0,1] , [c.numerator, c.denominator])
+
+ c = 1.to_r
+ assert_equal([1,1] , [c.numerator, c.denominator])
+
+ c = 1.1.to_r
+ assert_equal([2476979795053773, 2251799813685248],
+ [c.numerator, c.denominator])
+
+ c = Rational(1,2).to_r
+ assert_equal([1,2] , [c.numerator, c.denominator])
+
+ if defined?(Complex)
+ if Complex.instance_variable_get('@RCS_ID')
+ assert_raise(NoMethodError){Complex(1,2).to_r}
+ else
+ assert_raise(RangeError){Complex(1,2).to_r}
+ end
+ end
+ end
+
+ def test_prec
+ assert_equal(true, Rational < Precision)
+
+ c = Rational(3,2)
+
+ assert_eql(1, c.prec(Integer))
+ assert_eql(1.5, c.prec(Float))
+ assert_eql(c, c.prec(Rational))
+ end
+
+ def test_supp
+ assert_equal(true, 1.scalar?)
+ assert_equal(true, 1.1.scalar?)
+
+ if defined?(Complex)
+ assert_equal(1, 1.real)
+ assert_equal(0, 1.image)
+ assert_equal(0, 1.imag)
+
+ assert_equal(1.1, 1.1.real)
+ assert_equal(0, 1.1.image)
+ assert_equal(0, 1.1.imag)
+
+ assert_equal(0, 1.arg)
+ assert_equal(0, 1.angle)
+
+ assert_equal(0, 1.0.arg)
+ assert_equal(0, 1.0.angle)
+
+ assert_equal(Math::PI, -1.arg)
+ assert_equal(Math::PI, -1.angle)
+
+ assert_equal(Math::PI, -1.0.arg)
+ assert_equal(Math::PI, -1.0.angle)
+
+ assert_equal([1,0], 1.polar)
+ assert_equal([1, Math::PI], -1.polar)
+
+ assert_equal([1.0,0], 1.0.polar)
+ assert_equal([1.0, Math::PI], -1.0.polar)
+
+ assert_equal(1, 1.conjugate)
+ assert_equal(-1, -1.conjugate)
+ assert_equal(1, 1.conj)
+ assert_equal(-1, -1.conj)
+
+ assert_equal(1.1, 1.1.conjugate)
+ assert_equal(-1.1, -1.1.conjugate)
+ assert_equal(1.1, 1.1.conj)
+ assert_equal(-1.1, -1.1.conj)
+ end
+
+ assert_equal(1, 1.numerator)
+ assert_equal(9, 9.numerator)
+ assert_equal(1, 1.denominator)
+ assert_equal(1, 9.denominator)
+
+ assert_equal(1.0, 1.0.numerator)
+ assert_equal(9.0, 9.0.numerator)
+ assert_equal(1.0, 1.0.denominator)
+ assert_equal(1.0, 9.0.denominator)
+
+=begin
+ assert_equal(Rational(1,9), 9.reciprocal)
+ assert_equal(Rational(1,9), 9.0.reciprocal)
+ assert_equal(Rational(1,9), 9.inverse)
+ assert_equal(Rational(1,9), 9.0.inverse)
+=end
+
+ assert_equal(Rational(1,2), 1.quo(2))
+ assert_equal(Rational(5000000000), 10000000000.quo(2))
+ assert_equal(0.5, 1.0.quo(2))
+ assert_equal(Rational(1,4), Rational(1,2).quo(2))
+
+ assert_equal(0.5, 1.fdiv(2))
+ assert_equal(5000000000.0, 10000000000.fdiv(2))
+ assert_equal(0.5, 1.0.fdiv(2))
+ assert_equal(0.25, Rational(1,2).fdiv(2))
+ end
+
+=begin
+ def test_zero_div
+ assert_raise(ZeroDivisionError) { Rational(1, 0) }
+ assert_raise(ZeroDivisionError) { Rational(1, 1) / 0 }
+ end
+
+ def test_gcd
+ assert_equal(0, Rational(0, 2**100))
+ end
+
+ def test_unify2
+ f = defined?(Rational::Unify)
+ Rational.const_set(:Unify, true) unless f
+
+ assert_same(42, Rational(84, 2))
+ assert_same(1, Rational(1, 2) + Rational(1, 2))
+
+ Rational.instance_eval { remove_const(:Unify) } unless f
+ end
+
+ def test_coerce
+ r = Rational(7, 3)
+ assert_equal(Rational(42, 1), r.coerce(42).first)
+ assert_raise(TypeError) { r.coerce(Object.new) }
+
+ o = Object.new
+ def o.coerce(x); [x.numerator, x.denominator]; end
+ assert_equal(10, r + o)
+ assert_equal(4, r - o)
+ assert_equal(21, r * o)
+ assert_equal(2, r / o)
+ assert_equal(343, r ** o)
+ assert_equal(1, r <=> o)
+
+ b = 2**100
+ def b.<=>(x); 0; end rescue nil
+ assert_equal(1, r ** b)
+ b = 2**100
+ def b.**(x); -1; end rescue nil
+ assert_equal(-1, Rational(1, b)**3)
+ end
+
+ def test_modulo_remainder
+ assert_equal(Rational(1, 2), Rational(5, 2).modulo(1))
+ assert_equal(Rational(1, 2), Rational(5, 2).modulo(2))
+ assert_equal(Rational(5, 2), Rational(5, 2).modulo(3))
+ assert_equal(Rational(5, 6), Rational(5, 2).modulo(Rational(5, 3)))
+ assert_equal(Rational(1, 2), Rational(-5, 2).modulo(1))
+ assert_equal(Rational(-1, 2), Rational(5, 2).modulo(-1))
+ assert_equal(Rational(-1, 2), Rational(-5, 2).modulo(-1))
+
+ assert_equal(Rational(1, 2), Rational(5, 2).remainder(1))
+ assert_equal(Rational(1, 2), Rational(5, 2).remainder(2))
+ assert_equal(Rational(5, 2), Rational(5, 2).remainder(3))
+ assert_equal(Rational(5, 6), Rational(5, 2).remainder(Rational(5, 3)))
+ assert_equal(Rational(-1, 2), Rational(-5, 2).remainder(1))
+ assert_equal(Rational(1, 2), Rational(5, 2).remainder(-1))
+ assert_equal(Rational(-1, 2), Rational(-5, 2).remainder(-1))
+ end
+
+ def test_abs
+ assert_equal(Rational(1, 2), Rational(1, 2).abs)
+ assert_equal(Rational(1, 2), Rational(-1, 2).abs)
+ end
+
+ def test_floor_ceil_truncate_round
+ assert_equal( 2, Rational( 5, 2).floor)
+ assert_equal(-3, Rational(-5, 2).floor)
+ assert_equal( 3, Rational( 5, 2).ceil)
+ assert_equal(-2, Rational(-5, 2).ceil)
+ assert_equal( 2, Rational( 5, 2).truncate)
+ assert_equal(-2, Rational(-5, 2).truncate)
+ assert_equal( 3, Rational( 5, 2).round)
+ assert_equal(-3, Rational(-5, 2).round)
+ assert_equal( 1, Rational( 4, 3).round)
+ assert_equal(-1, Rational(-4, 3).round)
+ assert_equal( 2, Rational( 5, 3).round)
+ assert_equal(-2, Rational(-5, 3).round)
+ end
+
+ def test_convert
+ assert_equal(Rational(1, 2), Rational(Complex(1, 0), 2))
+ assert_raise(RangeError) { Rational(Complex(1, 1), 1) }
+ assert_equal(Rational(1, 2), Rational(1, Complex(2, 0)))
+ assert_raise(RangeError) { Rational(1, Complex(2, 1)) }
+ assert_equal(Rational(1, 2), Rational(0.25, 0.5))
+ assert_equal(Rational(1, 2), Rational('1', '2'))
+ end
+
+ def test_add2
+ assert_equal(Rational(2**100, 3), Rational(0, 1) + Rational(2**100, 3))
+ assert_equal(Rational(2, 3**100), Rational(0, 1) + Rational(2, 3**100))
+ end
+
+ def test_div2
+ assert_raise(ZeroDivisionError) { Rational(1, 1) / Rational(0, 1) }
+ end
+
+ def test_to_f2
+ assert_equal(1, Rational(2**5000,3).to_f.infinite?)
+ assert_equal(0, Rational(1, 2**5000).to_f)
+ end
+=end
+
+ def test_fixed_bug
+ if defined?(Rational::Unify)
+ assert_instance_of(Fixnum, Rational(1,2) ** 0) # mathn's bug
+ end
+
+ n = Float::MAX.to_i * 2
+ assert_equal(1.0, Rational(n + 2, n + 1).to_f, '[ruby-dev:33852]')
+ end
+
+ def test_known_bug
+ end
+
+end
diff --git a/trunk/test/ruby/test_rational2.rb b/trunk/test/ruby/test_rational2.rb
new file mode 100644
index 0000000000..641bfea565
--- /dev/null
+++ b/trunk/test/ruby/test_rational2.rb
@@ -0,0 +1,1360 @@
+require 'test/unit'
+
+class Rational_Test2 < Test::Unit::TestCase
+
+ def test_kumi
+ assert_equal(Rational(2, 1),
+ Rational(1, 1) + Rational(1, 1))
+ assert_equal(Rational(0, 1),
+ Rational(1, 1) - Rational(1, 1))
+ assert_equal(Rational(1, 1),
+ Rational(1, 1) * Rational(1, 1))
+ assert_equal(Rational(1, 1),
+ Rational(1, 1) / Rational(1, 1))
+ assert_equal(Rational(3, 1),
+ Rational(1, 1) + Rational(2, 1))
+ assert_equal(Rational(-1, 1),
+ Rational(1, 1) - Rational(2, 1))
+ assert_equal(Rational(2, 1),
+ Rational(1, 1) * Rational(2, 1))
+ assert_equal(Rational(1, 2),
+ Rational(1, 1) / Rational(2, 1))
+ assert_equal(Rational(4, 1),
+ Rational(1, 1) + Rational(3, 1))
+ assert_equal(Rational(-2, 1),
+ Rational(1, 1) - Rational(3, 1))
+ assert_equal(Rational(3, 1),
+ Rational(1, 1) * Rational(3, 1))
+ assert_equal(Rational(1, 3),
+ Rational(1, 1) / Rational(3, 1))
+ assert_equal(Rational(1073741790, 1),
+ Rational(1, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(-1073741788, 1),
+ Rational(1, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(1, 1073741789),
+ Rational(1, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(1073741828, 1),
+ Rational(1, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(-1073741826, 1),
+ Rational(1, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(1, 1073741827),
+ Rational(1, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(5, 3),
+ Rational(1, 1) + Rational(2, 3))
+ assert_equal(Rational(1, 3),
+ Rational(1, 1) - Rational(2, 3))
+ assert_equal(Rational(2, 3),
+ Rational(1, 1) * Rational(2, 3))
+ assert_equal(Rational(3, 2),
+ Rational(1, 1) / Rational(2, 3))
+ assert_equal(Rational(5, 2),
+ Rational(1, 1) + Rational(3, 2))
+ assert_equal(Rational(-1, 2),
+ Rational(1, 1) - Rational(3, 2))
+ assert_equal(Rational(3, 2),
+ Rational(1, 1) * Rational(3, 2))
+ assert_equal(Rational(2, 3),
+ Rational(1, 1) / Rational(3, 2))
+ assert_equal(Rational(1073741792, 1073741789),
+ Rational(1, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(1073741786, 1073741789),
+ Rational(1, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(3, 1073741789),
+ Rational(1, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(1073741792, 3),
+ Rational(1, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(-1073741786, 3),
+ Rational(1, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(3, 1073741789),
+ Rational(1, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(1073741830, 1073741827),
+ Rational(1, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(1073741824, 1073741827),
+ Rational(1, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(3, 1073741827),
+ Rational(1, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(1073741830, 3),
+ Rational(1, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(-1073741824, 3),
+ Rational(1, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(3, 1073741827),
+ Rational(1, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(2147483616, 1073741827),
+ Rational(1, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(38, 1073741827),
+ Rational(1, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483616, 1073741789),
+ Rational(1, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-38, 1073741789),
+ Rational(1, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 1),
+ Rational(2, 1) + Rational(1, 1))
+ assert_equal(Rational(1, 1),
+ Rational(2, 1) - Rational(1, 1))
+ assert_equal(Rational(2, 1),
+ Rational(2, 1) * Rational(1, 1))
+ assert_equal(Rational(2, 1),
+ Rational(2, 1) / Rational(1, 1))
+ assert_equal(Rational(4, 1),
+ Rational(2, 1) + Rational(2, 1))
+ assert_equal(Rational(0, 1),
+ Rational(2, 1) - Rational(2, 1))
+ assert_equal(Rational(4, 1),
+ Rational(2, 1) * Rational(2, 1))
+ assert_equal(Rational(1, 1),
+ Rational(2, 1) / Rational(2, 1))
+ assert_equal(Rational(5, 1),
+ Rational(2, 1) + Rational(3, 1))
+ assert_equal(Rational(-1, 1),
+ Rational(2, 1) - Rational(3, 1))
+ assert_equal(Rational(6, 1),
+ Rational(2, 1) * Rational(3, 1))
+ assert_equal(Rational(2, 3),
+ Rational(2, 1) / Rational(3, 1))
+ assert_equal(Rational(1073741791, 1),
+ Rational(2, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(-1073741787, 1),
+ Rational(2, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(2147483578, 1),
+ Rational(2, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(2, 1073741789),
+ Rational(2, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(1073741829, 1),
+ Rational(2, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(-1073741825, 1),
+ Rational(2, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(2147483654, 1),
+ Rational(2, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(2, 1073741827),
+ Rational(2, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(8, 3),
+ Rational(2, 1) + Rational(2, 3))
+ assert_equal(Rational(4, 3),
+ Rational(2, 1) - Rational(2, 3))
+ assert_equal(Rational(4, 3),
+ Rational(2, 1) * Rational(2, 3))
+ assert_equal(Rational(3, 1),
+ Rational(2, 1) / Rational(2, 3))
+ assert_equal(Rational(7, 2),
+ Rational(2, 1) + Rational(3, 2))
+ assert_equal(Rational(1, 2),
+ Rational(2, 1) - Rational(3, 2))
+ assert_equal(Rational(3, 1),
+ Rational(2, 1) * Rational(3, 2))
+ assert_equal(Rational(4, 3),
+ Rational(2, 1) / Rational(3, 2))
+ assert_equal(Rational(2147483581, 1073741789),
+ Rational(2, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(2147483575, 1073741789),
+ Rational(2, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(6, 1073741789),
+ Rational(2, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(2147483578, 3),
+ Rational(2, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(1073741795, 3),
+ Rational(2, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(-1073741783, 3),
+ Rational(2, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(2147483578, 3),
+ Rational(2, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(6, 1073741789),
+ Rational(2, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(2147483657, 1073741827),
+ Rational(2, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(2147483651, 1073741827),
+ Rational(2, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(6, 1073741827),
+ Rational(2, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(2147483654, 3),
+ Rational(2, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(1073741833, 3),
+ Rational(2, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(-1073741821, 3),
+ Rational(2, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(2147483654, 3),
+ Rational(2, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(6, 1073741827),
+ Rational(2, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(3221225443, 1073741827),
+ Rational(2, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741865, 1073741827),
+ Rational(2, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483578, 1073741827),
+ Rational(2, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483654, 1073741789),
+ Rational(2, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225405, 1073741789),
+ Rational(2, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741751, 1073741789),
+ Rational(2, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483654, 1073741789),
+ Rational(2, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483578, 1073741827),
+ Rational(2, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(4, 1),
+ Rational(3, 1) + Rational(1, 1))
+ assert_equal(Rational(2, 1),
+ Rational(3, 1) - Rational(1, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 1) * Rational(1, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 1) / Rational(1, 1))
+ assert_equal(Rational(5, 1),
+ Rational(3, 1) + Rational(2, 1))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1) - Rational(2, 1))
+ assert_equal(Rational(6, 1),
+ Rational(3, 1) * Rational(2, 1))
+ assert_equal(Rational(3, 2),
+ Rational(3, 1) / Rational(2, 1))
+ assert_equal(Rational(6, 1),
+ Rational(3, 1) + Rational(3, 1))
+ assert_equal(Rational(0, 1),
+ Rational(3, 1) - Rational(3, 1))
+ assert_equal(Rational(9, 1),
+ Rational(3, 1) * Rational(3, 1))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1) / Rational(3, 1))
+ assert_equal(Rational(1073741792, 1),
+ Rational(3, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(-1073741786, 1),
+ Rational(3, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(3221225367, 1),
+ Rational(3, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(1073741830, 1),
+ Rational(3, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(-1073741824, 1),
+ Rational(3, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(3221225481, 1),
+ Rational(3, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(11, 3),
+ Rational(3, 1) + Rational(2, 3))
+ assert_equal(Rational(7, 3),
+ Rational(3, 1) - Rational(2, 3))
+ assert_equal(Rational(2, 1),
+ Rational(3, 1) * Rational(2, 3))
+ assert_equal(Rational(9, 2),
+ Rational(3, 1) / Rational(2, 3))
+ assert_equal(Rational(9, 2),
+ Rational(3, 1) + Rational(3, 2))
+ assert_equal(Rational(3, 2),
+ Rational(3, 1) - Rational(3, 2))
+ assert_equal(Rational(9, 2),
+ Rational(3, 1) * Rational(3, 2))
+ assert_equal(Rational(2, 1),
+ Rational(3, 1) / Rational(3, 2))
+ assert_equal(Rational(3221225370, 1073741789),
+ Rational(3, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(3221225364, 1073741789),
+ Rational(3, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(9, 1073741789),
+ Rational(3, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741789, 1),
+ Rational(3, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(1073741798, 3),
+ Rational(3, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(-1073741780, 3),
+ Rational(3, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741789, 1),
+ Rational(3, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(9, 1073741789),
+ Rational(3, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(3221225484, 1073741827),
+ Rational(3, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(3221225478, 1073741827),
+ Rational(3, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(9, 1073741827),
+ Rational(3, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741827, 1),
+ Rational(3, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(1073741836, 3),
+ Rational(3, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(-1073741818, 3),
+ Rational(3, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741827, 1),
+ Rational(3, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(9, 1073741827),
+ Rational(3, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(4294967270, 1073741827),
+ Rational(3, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483692, 1073741827),
+ Rational(3, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(3, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(3, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(4294967194, 1073741789),
+ Rational(3, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483540, 1073741789),
+ Rational(3, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(3, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(3, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741790, 1),
+ Rational(1073741789, 1) + Rational(1, 1))
+ assert_equal(Rational(1073741788, 1),
+ Rational(1073741789, 1) - Rational(1, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741789, 1) * Rational(1, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741789, 1) / Rational(1, 1))
+ assert_equal(Rational(1073741791, 1),
+ Rational(1073741789, 1) + Rational(2, 1))
+ assert_equal(Rational(1073741787, 1),
+ Rational(1073741789, 1) - Rational(2, 1))
+ assert_equal(Rational(2147483578, 1),
+ Rational(1073741789, 1) * Rational(2, 1))
+ assert_equal(Rational(1073741789, 2),
+ Rational(1073741789, 1) / Rational(2, 1))
+ assert_equal(Rational(1073741792, 1),
+ Rational(1073741789, 1) + Rational(3, 1))
+ assert_equal(Rational(1073741786, 1),
+ Rational(1073741789, 1) - Rational(3, 1))
+ assert_equal(Rational(3221225367, 1),
+ Rational(1073741789, 1) * Rational(3, 1))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 1) / Rational(3, 1))
+ assert_equal(Rational(2147483578, 1),
+ Rational(1073741789, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(0, 1),
+ Rational(1073741789, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921429444920521, 1),
+ Rational(1073741789, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(2147483616, 1),
+ Rational(1073741789, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(-38, 1),
+ Rational(1073741789, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921470247108503, 1),
+ Rational(1073741789, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(3221225369, 3),
+ Rational(1073741789, 1) + Rational(2, 3))
+ assert_equal(Rational(3221225365, 3),
+ Rational(1073741789, 1) - Rational(2, 3))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 1) * Rational(2, 3))
+ assert_equal(Rational(3221225367, 2),
+ Rational(1073741789, 1) / Rational(2, 3))
+ assert_equal(Rational(2147483581, 2),
+ Rational(1073741789, 1) + Rational(3, 2))
+ assert_equal(Rational(2147483575, 2),
+ Rational(1073741789, 1) - Rational(3, 2))
+ assert_equal(Rational(3221225367, 2),
+ Rational(1073741789, 1) * Rational(3, 2))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 1) / Rational(3, 2))
+ assert_equal(Rational(1152921429444920524, 1073741789),
+ Rational(1073741789, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920518, 1073741789),
+ Rational(1073741789, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(3, 1),
+ Rational(1073741789, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920521, 3),
+ Rational(1073741789, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(4294967156, 3),
+ Rational(1073741789, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921429444920521, 3),
+ Rational(1073741789, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(3, 1),
+ Rational(1073741789, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921470247108506, 1073741827),
+ Rational(1073741789, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108500, 1073741827),
+ Rational(1073741789, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(1073741789, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741789, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(4294967194, 3),
+ Rational(1073741789, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(2147483540, 3),
+ Rational(1073741789, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741789, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(1073741789, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921471320850292, 1073741827),
+ Rational(1073741789, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921469173366714, 1073741827),
+ Rational(1073741789, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921429444920521, 1073741827),
+ Rational(1073741789, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741789, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921430518662348, 1073741789),
+ Rational(1073741789, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921428371178694, 1073741789),
+ Rational(1073741789, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741789, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921429444920521, 1073741827),
+ Rational(1073741789, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741828, 1),
+ Rational(1073741827, 1) + Rational(1, 1))
+ assert_equal(Rational(1073741826, 1),
+ Rational(1073741827, 1) - Rational(1, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741827, 1) * Rational(1, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741827, 1) / Rational(1, 1))
+ assert_equal(Rational(1073741829, 1),
+ Rational(1073741827, 1) + Rational(2, 1))
+ assert_equal(Rational(1073741825, 1),
+ Rational(1073741827, 1) - Rational(2, 1))
+ assert_equal(Rational(2147483654, 1),
+ Rational(1073741827, 1) * Rational(2, 1))
+ assert_equal(Rational(1073741827, 2),
+ Rational(1073741827, 1) / Rational(2, 1))
+ assert_equal(Rational(1073741830, 1),
+ Rational(1073741827, 1) + Rational(3, 1))
+ assert_equal(Rational(1073741824, 1),
+ Rational(1073741827, 1) - Rational(3, 1))
+ assert_equal(Rational(3221225481, 1),
+ Rational(1073741827, 1) * Rational(3, 1))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 1) / Rational(3, 1))
+ assert_equal(Rational(2147483616, 1),
+ Rational(1073741827, 1) + Rational(1073741789, 1))
+ assert_equal(Rational(38, 1),
+ Rational(1073741827, 1) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921470247108503, 1),
+ Rational(1073741827, 1) * Rational(1073741789, 1))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 1) / Rational(1073741789, 1))
+ assert_equal(Rational(2147483654, 1),
+ Rational(1073741827, 1) + Rational(1073741827, 1))
+ assert_equal(Rational(0, 1),
+ Rational(1073741827, 1) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921511049297929, 1),
+ Rational(1073741827, 1) * Rational(1073741827, 1))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 1) / Rational(1073741827, 1))
+ assert_equal(Rational(3221225483, 3),
+ Rational(1073741827, 1) + Rational(2, 3))
+ assert_equal(Rational(3221225479, 3),
+ Rational(1073741827, 1) - Rational(2, 3))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 1) * Rational(2, 3))
+ assert_equal(Rational(3221225481, 2),
+ Rational(1073741827, 1) / Rational(2, 3))
+ assert_equal(Rational(2147483657, 2),
+ Rational(1073741827, 1) + Rational(3, 2))
+ assert_equal(Rational(2147483651, 2),
+ Rational(1073741827, 1) - Rational(3, 2))
+ assert_equal(Rational(3221225481, 2),
+ Rational(1073741827, 1) * Rational(3, 2))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 1) / Rational(3, 2))
+ assert_equal(Rational(1152921470247108506, 1073741789),
+ Rational(1073741827, 1) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108500, 1073741789),
+ Rational(1073741827, 1) - Rational(3, 1073741789))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(1073741827, 1) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741827, 1) / Rational(3, 1073741789))
+ assert_equal(Rational(4294967270, 3),
+ Rational(1073741827, 1) + Rational(1073741789, 3))
+ assert_equal(Rational(2147483692, 3),
+ Rational(1073741827, 1) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741827, 1) * Rational(1073741789, 3))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(1073741827, 1) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921511049297932, 1073741827),
+ Rational(1073741827, 1) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297926, 1073741827),
+ Rational(1073741827, 1) - Rational(3, 1073741827))
+ assert_equal(Rational(3, 1),
+ Rational(1073741827, 1) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297929, 3),
+ Rational(1073741827, 1) / Rational(3, 1073741827))
+ assert_equal(Rational(4294967308, 3),
+ Rational(1073741827, 1) + Rational(1073741827, 3))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 1) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921511049297929, 3),
+ Rational(1073741827, 1) * Rational(1073741827, 3))
+ assert_equal(Rational(3, 1),
+ Rational(1073741827, 1) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921512123039718, 1073741827),
+ Rational(1073741827, 1) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921509975556140, 1073741827),
+ Rational(1073741827, 1) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741827, 1) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921511049297929, 1073741789),
+ Rational(1073741827, 1) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921471320850330, 1073741789),
+ Rational(1073741827, 1) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921469173366676, 1073741789),
+ Rational(1073741827, 1) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921511049297929, 1073741789),
+ Rational(1073741827, 1) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741827, 1) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(5, 3),
+ Rational(2, 3) + Rational(1, 1))
+ assert_equal(Rational(-1, 3),
+ Rational(2, 3) - Rational(1, 1))
+ assert_equal(Rational(2, 3),
+ Rational(2, 3) * Rational(1, 1))
+ assert_equal(Rational(2, 3),
+ Rational(2, 3) / Rational(1, 1))
+ assert_equal(Rational(8, 3),
+ Rational(2, 3) + Rational(2, 1))
+ assert_equal(Rational(-4, 3),
+ Rational(2, 3) - Rational(2, 1))
+ assert_equal(Rational(4, 3),
+ Rational(2, 3) * Rational(2, 1))
+ assert_equal(Rational(1, 3),
+ Rational(2, 3) / Rational(2, 1))
+ assert_equal(Rational(11, 3),
+ Rational(2, 3) + Rational(3, 1))
+ assert_equal(Rational(-7, 3),
+ Rational(2, 3) - Rational(3, 1))
+ assert_equal(Rational(2, 1),
+ Rational(2, 3) * Rational(3, 1))
+ assert_equal(Rational(2, 9),
+ Rational(2, 3) / Rational(3, 1))
+ assert_equal(Rational(3221225369, 3),
+ Rational(2, 3) + Rational(1073741789, 1))
+ assert_equal(Rational(-3221225365, 3),
+ Rational(2, 3) - Rational(1073741789, 1))
+ assert_equal(Rational(2147483578, 3),
+ Rational(2, 3) * Rational(1073741789, 1))
+ assert_equal(Rational(2, 3221225367),
+ Rational(2, 3) / Rational(1073741789, 1))
+ assert_equal(Rational(3221225483, 3),
+ Rational(2, 3) + Rational(1073741827, 1))
+ assert_equal(Rational(-3221225479, 3),
+ Rational(2, 3) - Rational(1073741827, 1))
+ assert_equal(Rational(2147483654, 3),
+ Rational(2, 3) * Rational(1073741827, 1))
+ assert_equal(Rational(2, 3221225481),
+ Rational(2, 3) / Rational(1073741827, 1))
+ assert_equal(Rational(4, 3),
+ Rational(2, 3) + Rational(2, 3))
+ assert_equal(Rational(0, 1),
+ Rational(2, 3) - Rational(2, 3))
+ assert_equal(Rational(4, 9),
+ Rational(2, 3) * Rational(2, 3))
+ assert_equal(Rational(1, 1),
+ Rational(2, 3) / Rational(2, 3))
+ assert_equal(Rational(13, 6),
+ Rational(2, 3) + Rational(3, 2))
+ assert_equal(Rational(-5, 6),
+ Rational(2, 3) - Rational(3, 2))
+ assert_equal(Rational(1, 1),
+ Rational(2, 3) * Rational(3, 2))
+ assert_equal(Rational(4, 9),
+ Rational(2, 3) / Rational(3, 2))
+ assert_equal(Rational(2147483587, 3221225367),
+ Rational(2, 3) + Rational(3, 1073741789))
+ assert_equal(Rational(2147483569, 3221225367),
+ Rational(2, 3) - Rational(3, 1073741789))
+ assert_equal(Rational(2, 1073741789),
+ Rational(2, 3) * Rational(3, 1073741789))
+ assert_equal(Rational(2147483578, 9),
+ Rational(2, 3) / Rational(3, 1073741789))
+ assert_equal(Rational(1073741791, 3),
+ Rational(2, 3) + Rational(1073741789, 3))
+ assert_equal(Rational(-357913929, 1),
+ Rational(2, 3) - Rational(1073741789, 3))
+ assert_equal(Rational(2147483578, 9),
+ Rational(2, 3) * Rational(1073741789, 3))
+ assert_equal(Rational(2, 1073741789),
+ Rational(2, 3) / Rational(1073741789, 3))
+ assert_equal(Rational(2147483663, 3221225481),
+ Rational(2, 3) + Rational(3, 1073741827))
+ assert_equal(Rational(2147483645, 3221225481),
+ Rational(2, 3) - Rational(3, 1073741827))
+ assert_equal(Rational(2, 1073741827),
+ Rational(2, 3) * Rational(3, 1073741827))
+ assert_equal(Rational(2147483654, 9),
+ Rational(2, 3) / Rational(3, 1073741827))
+ assert_equal(Rational(357913943, 1),
+ Rational(2, 3) + Rational(1073741827, 3))
+ assert_equal(Rational(-1073741825, 3),
+ Rational(2, 3) - Rational(1073741827, 3))
+ assert_equal(Rational(2147483654, 9),
+ Rational(2, 3) * Rational(1073741827, 3))
+ assert_equal(Rational(2, 1073741827),
+ Rational(2, 3) / Rational(1073741827, 3))
+ assert_equal(Rational(5368709021, 3221225481),
+ Rational(2, 3) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(-1073741713, 3221225481),
+ Rational(2, 3) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483578, 3221225481),
+ Rational(2, 3) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483654, 3221225367),
+ Rational(2, 3) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(5368709059, 3221225367),
+ Rational(2, 3) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-1073741903, 3221225367),
+ Rational(2, 3) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483654, 3221225367),
+ Rational(2, 3) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483578, 3221225481),
+ Rational(2, 3) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(5, 2),
+ Rational(3, 2) + Rational(1, 1))
+ assert_equal(Rational(1, 2),
+ Rational(3, 2) - Rational(1, 1))
+ assert_equal(Rational(3, 2),
+ Rational(3, 2) * Rational(1, 1))
+ assert_equal(Rational(3, 2),
+ Rational(3, 2) / Rational(1, 1))
+ assert_equal(Rational(7, 2),
+ Rational(3, 2) + Rational(2, 1))
+ assert_equal(Rational(-1, 2),
+ Rational(3, 2) - Rational(2, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 2) * Rational(2, 1))
+ assert_equal(Rational(3, 4),
+ Rational(3, 2) / Rational(2, 1))
+ assert_equal(Rational(9, 2),
+ Rational(3, 2) + Rational(3, 1))
+ assert_equal(Rational(-3, 2),
+ Rational(3, 2) - Rational(3, 1))
+ assert_equal(Rational(9, 2),
+ Rational(3, 2) * Rational(3, 1))
+ assert_equal(Rational(1, 2),
+ Rational(3, 2) / Rational(3, 1))
+ assert_equal(Rational(2147483581, 2),
+ Rational(3, 2) + Rational(1073741789, 1))
+ assert_equal(Rational(-2147483575, 2),
+ Rational(3, 2) - Rational(1073741789, 1))
+ assert_equal(Rational(3221225367, 2),
+ Rational(3, 2) * Rational(1073741789, 1))
+ assert_equal(Rational(3, 2147483578),
+ Rational(3, 2) / Rational(1073741789, 1))
+ assert_equal(Rational(2147483657, 2),
+ Rational(3, 2) + Rational(1073741827, 1))
+ assert_equal(Rational(-2147483651, 2),
+ Rational(3, 2) - Rational(1073741827, 1))
+ assert_equal(Rational(3221225481, 2),
+ Rational(3, 2) * Rational(1073741827, 1))
+ assert_equal(Rational(3, 2147483654),
+ Rational(3, 2) / Rational(1073741827, 1))
+ assert_equal(Rational(13, 6),
+ Rational(3, 2) + Rational(2, 3))
+ assert_equal(Rational(5, 6),
+ Rational(3, 2) - Rational(2, 3))
+ assert_equal(Rational(1, 1),
+ Rational(3, 2) * Rational(2, 3))
+ assert_equal(Rational(9, 4),
+ Rational(3, 2) / Rational(2, 3))
+ assert_equal(Rational(3, 1),
+ Rational(3, 2) + Rational(3, 2))
+ assert_equal(Rational(0, 1),
+ Rational(3, 2) - Rational(3, 2))
+ assert_equal(Rational(9, 4),
+ Rational(3, 2) * Rational(3, 2))
+ assert_equal(Rational(1, 1),
+ Rational(3, 2) / Rational(3, 2))
+ assert_equal(Rational(3221225373, 2147483578),
+ Rational(3, 2) + Rational(3, 1073741789))
+ assert_equal(Rational(3221225361, 2147483578),
+ Rational(3, 2) - Rational(3, 1073741789))
+ assert_equal(Rational(9, 2147483578),
+ Rational(3, 2) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741789, 2),
+ Rational(3, 2) / Rational(3, 1073741789))
+ assert_equal(Rational(2147483587, 6),
+ Rational(3, 2) + Rational(1073741789, 3))
+ assert_equal(Rational(-2147483569, 6),
+ Rational(3, 2) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741789, 2),
+ Rational(3, 2) * Rational(1073741789, 3))
+ assert_equal(Rational(9, 2147483578),
+ Rational(3, 2) / Rational(1073741789, 3))
+ assert_equal(Rational(3221225487, 2147483654),
+ Rational(3, 2) + Rational(3, 1073741827))
+ assert_equal(Rational(3221225475, 2147483654),
+ Rational(3, 2) - Rational(3, 1073741827))
+ assert_equal(Rational(9, 2147483654),
+ Rational(3, 2) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741827, 2),
+ Rational(3, 2) / Rational(3, 1073741827))
+ assert_equal(Rational(2147483663, 6),
+ Rational(3, 2) + Rational(1073741827, 3))
+ assert_equal(Rational(-2147483645, 6),
+ Rational(3, 2) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741827, 2),
+ Rational(3, 2) * Rational(1073741827, 3))
+ assert_equal(Rational(9, 2147483654),
+ Rational(3, 2) / Rational(1073741827, 3))
+ assert_equal(Rational(5368709059, 2147483654),
+ Rational(3, 2) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741903, 2147483654),
+ Rational(3, 2) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225367, 2147483654),
+ Rational(3, 2) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225481, 2147483578),
+ Rational(3, 2) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(5368709021, 2147483578),
+ Rational(3, 2) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741713, 2147483578),
+ Rational(3, 2) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225481, 2147483578),
+ Rational(3, 2) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225367, 2147483654),
+ Rational(3, 2) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741792, 1073741789),
+ Rational(3, 1073741789) + Rational(1, 1))
+ assert_equal(Rational(-1073741786, 1073741789),
+ Rational(3, 1073741789) - Rational(1, 1))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1073741789) * Rational(1, 1))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1073741789) / Rational(1, 1))
+ assert_equal(Rational(2147483581, 1073741789),
+ Rational(3, 1073741789) + Rational(2, 1))
+ assert_equal(Rational(-2147483575, 1073741789),
+ Rational(3, 1073741789) - Rational(2, 1))
+ assert_equal(Rational(6, 1073741789),
+ Rational(3, 1073741789) * Rational(2, 1))
+ assert_equal(Rational(3, 2147483578),
+ Rational(3, 1073741789) / Rational(2, 1))
+ assert_equal(Rational(3221225370, 1073741789),
+ Rational(3, 1073741789) + Rational(3, 1))
+ assert_equal(Rational(-3221225364, 1073741789),
+ Rational(3, 1073741789) - Rational(3, 1))
+ assert_equal(Rational(9, 1073741789),
+ Rational(3, 1073741789) * Rational(3, 1))
+ assert_equal(Rational(1, 1073741789),
+ Rational(3, 1073741789) / Rational(3, 1))
+ assert_equal(Rational(1152921429444920524, 1073741789),
+ Rational(3, 1073741789) + Rational(1073741789, 1))
+ assert_equal(Rational(-1152921429444920518, 1073741789),
+ Rational(3, 1073741789) - Rational(1073741789, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 1073741789) * Rational(1073741789, 1))
+ assert_equal(Rational(3, 1152921429444920521),
+ Rational(3, 1073741789) / Rational(1073741789, 1))
+ assert_equal(Rational(1152921470247108506, 1073741789),
+ Rational(3, 1073741789) + Rational(1073741827, 1))
+ assert_equal(Rational(-1152921470247108500, 1073741789),
+ Rational(3, 1073741789) - Rational(1073741827, 1))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(3, 1073741789) * Rational(1073741827, 1))
+ assert_equal(Rational(3, 1152921470247108503),
+ Rational(3, 1073741789) / Rational(1073741827, 1))
+ assert_equal(Rational(2147483587, 3221225367),
+ Rational(3, 1073741789) + Rational(2, 3))
+ assert_equal(Rational(-2147483569, 3221225367),
+ Rational(3, 1073741789) - Rational(2, 3))
+ assert_equal(Rational(2, 1073741789),
+ Rational(3, 1073741789) * Rational(2, 3))
+ assert_equal(Rational(9, 2147483578),
+ Rational(3, 1073741789) / Rational(2, 3))
+ assert_equal(Rational(3221225373, 2147483578),
+ Rational(3, 1073741789) + Rational(3, 2))
+ assert_equal(Rational(-3221225361, 2147483578),
+ Rational(3, 1073741789) - Rational(3, 2))
+ assert_equal(Rational(9, 2147483578),
+ Rational(3, 1073741789) * Rational(3, 2))
+ assert_equal(Rational(2, 1073741789),
+ Rational(3, 1073741789) / Rational(3, 2))
+ assert_equal(Rational(6, 1073741789),
+ Rational(3, 1073741789) + Rational(3, 1073741789))
+ assert_equal(Rational(0, 1),
+ Rational(3, 1073741789) - Rational(3, 1073741789))
+ assert_equal(Rational(9, 1152921429444920521),
+ Rational(3, 1073741789) * Rational(3, 1073741789))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1073741789) / Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920530, 3221225367),
+ Rational(3, 1073741789) + Rational(1073741789, 3))
+ assert_equal(Rational(-1152921429444920512, 3221225367),
+ Rational(3, 1073741789) - Rational(1073741789, 3))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1073741789) * Rational(1073741789, 3))
+ assert_equal(Rational(9, 1152921429444920521),
+ Rational(3, 1073741789) / Rational(1073741789, 3))
+ assert_equal(Rational(6442450848, 1152921470247108503),
+ Rational(3, 1073741789) + Rational(3, 1073741827))
+ assert_equal(Rational(114, 1152921470247108503),
+ Rational(3, 1073741789) - Rational(3, 1073741827))
+ assert_equal(Rational(9, 1152921470247108503),
+ Rational(3, 1073741789) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(3, 1073741789) / Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108512, 3221225367),
+ Rational(3, 1073741789) + Rational(1073741827, 3))
+ assert_equal(Rational(-1152921470247108494, 3221225367),
+ Rational(3, 1073741789) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(3, 1073741789) * Rational(1073741827, 3))
+ assert_equal(Rational(9, 1152921470247108503),
+ Rational(3, 1073741789) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921432666146002, 1152921470247108503),
+ Rational(3, 1073741789) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(-1152921426223695040, 1152921470247108503),
+ Rational(3, 1073741789) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1073741789) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225481, 1152921429444920521),
+ Rational(3, 1073741789) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741830, 1073741789),
+ Rational(3, 1073741789) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-1073741824, 1073741789),
+ Rational(3, 1073741789) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225481, 1152921429444920521),
+ Rational(3, 1073741789) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1073741789) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741792, 3),
+ Rational(1073741789, 3) + Rational(1, 1))
+ assert_equal(Rational(1073741786, 3),
+ Rational(1073741789, 3) - Rational(1, 1))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 3) * Rational(1, 1))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 3) / Rational(1, 1))
+ assert_equal(Rational(1073741795, 3),
+ Rational(1073741789, 3) + Rational(2, 1))
+ assert_equal(Rational(1073741783, 3),
+ Rational(1073741789, 3) - Rational(2, 1))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 3) * Rational(2, 1))
+ assert_equal(Rational(1073741789, 6),
+ Rational(1073741789, 3) / Rational(2, 1))
+ assert_equal(Rational(1073741798, 3),
+ Rational(1073741789, 3) + Rational(3, 1))
+ assert_equal(Rational(1073741780, 3),
+ Rational(1073741789, 3) - Rational(3, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741789, 3) * Rational(3, 1))
+ assert_equal(Rational(1073741789, 9),
+ Rational(1073741789, 3) / Rational(3, 1))
+ assert_equal(Rational(4294967156, 3),
+ Rational(1073741789, 3) + Rational(1073741789, 1))
+ assert_equal(Rational(-2147483578, 3),
+ Rational(1073741789, 3) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921429444920521, 3),
+ Rational(1073741789, 3) * Rational(1073741789, 1))
+ assert_equal(Rational(1, 3),
+ Rational(1073741789, 3) / Rational(1073741789, 1))
+ assert_equal(Rational(4294967270, 3),
+ Rational(1073741789, 3) + Rational(1073741827, 1))
+ assert_equal(Rational(-2147483692, 3),
+ Rational(1073741789, 3) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741789, 3) * Rational(1073741827, 1))
+ assert_equal(Rational(1073741789, 3221225481),
+ Rational(1073741789, 3) / Rational(1073741827, 1))
+ assert_equal(Rational(1073741791, 3),
+ Rational(1073741789, 3) + Rational(2, 3))
+ assert_equal(Rational(357913929, 1),
+ Rational(1073741789, 3) - Rational(2, 3))
+ assert_equal(Rational(2147483578, 9),
+ Rational(1073741789, 3) * Rational(2, 3))
+ assert_equal(Rational(1073741789, 2),
+ Rational(1073741789, 3) / Rational(2, 3))
+ assert_equal(Rational(2147483587, 6),
+ Rational(1073741789, 3) + Rational(3, 2))
+ assert_equal(Rational(2147483569, 6),
+ Rational(1073741789, 3) - Rational(3, 2))
+ assert_equal(Rational(1073741789, 2),
+ Rational(1073741789, 3) * Rational(3, 2))
+ assert_equal(Rational(2147483578, 9),
+ Rational(1073741789, 3) / Rational(3, 2))
+ assert_equal(Rational(1152921429444920530, 3221225367),
+ Rational(1073741789, 3) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920512, 3221225367),
+ Rational(1073741789, 3) - Rational(3, 1073741789))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 3) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920521, 9),
+ Rational(1073741789, 3) / Rational(3, 1073741789))
+ assert_equal(Rational(2147483578, 3),
+ Rational(1073741789, 3) + Rational(1073741789, 3))
+ assert_equal(Rational(0, 1),
+ Rational(1073741789, 3) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921429444920521, 9),
+ Rational(1073741789, 3) * Rational(1073741789, 3))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 3) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921470247108512, 3221225481),
+ Rational(1073741789, 3) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108494, 3221225481),
+ Rational(1073741789, 3) - Rational(3, 1073741827))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 3) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921470247108503, 9),
+ Rational(1073741789, 3) / Rational(3, 1073741827))
+ assert_equal(Rational(715827872, 1),
+ Rational(1073741789, 3) + Rational(1073741827, 3))
+ assert_equal(Rational(-38, 3),
+ Rational(1073741789, 3) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921470247108503, 9),
+ Rational(1073741789, 3) * Rational(1073741827, 3))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 3) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921473468333870, 3221225481),
+ Rational(1073741789, 3) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921467025883136, 3221225481),
+ Rational(1073741789, 3) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921429444920521, 3221225481),
+ Rational(1073741789, 3) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741789, 3) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921432666146002, 3221225367),
+ Rational(1073741789, 3) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921426223695040, 3221225367),
+ Rational(1073741789, 3) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741789, 3) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921429444920521, 3221225481),
+ Rational(1073741789, 3) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741830, 1073741827),
+ Rational(3, 1073741827) + Rational(1, 1))
+ assert_equal(Rational(-1073741824, 1073741827),
+ Rational(3, 1073741827) - Rational(1, 1))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1073741827) * Rational(1, 1))
+ assert_equal(Rational(3, 1073741827),
+ Rational(3, 1073741827) / Rational(1, 1))
+ assert_equal(Rational(2147483657, 1073741827),
+ Rational(3, 1073741827) + Rational(2, 1))
+ assert_equal(Rational(-2147483651, 1073741827),
+ Rational(3, 1073741827) - Rational(2, 1))
+ assert_equal(Rational(6, 1073741827),
+ Rational(3, 1073741827) * Rational(2, 1))
+ assert_equal(Rational(3, 2147483654),
+ Rational(3, 1073741827) / Rational(2, 1))
+ assert_equal(Rational(3221225484, 1073741827),
+ Rational(3, 1073741827) + Rational(3, 1))
+ assert_equal(Rational(-3221225478, 1073741827),
+ Rational(3, 1073741827) - Rational(3, 1))
+ assert_equal(Rational(9, 1073741827),
+ Rational(3, 1073741827) * Rational(3, 1))
+ assert_equal(Rational(1, 1073741827),
+ Rational(3, 1073741827) / Rational(3, 1))
+ assert_equal(Rational(1152921470247108506, 1073741827),
+ Rational(3, 1073741827) + Rational(1073741789, 1))
+ assert_equal(Rational(-1152921470247108500, 1073741827),
+ Rational(3, 1073741827) - Rational(1073741789, 1))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(3, 1073741827) * Rational(1073741789, 1))
+ assert_equal(Rational(3, 1152921470247108503),
+ Rational(3, 1073741827) / Rational(1073741789, 1))
+ assert_equal(Rational(1152921511049297932, 1073741827),
+ Rational(3, 1073741827) + Rational(1073741827, 1))
+ assert_equal(Rational(-1152921511049297926, 1073741827),
+ Rational(3, 1073741827) - Rational(1073741827, 1))
+ assert_equal(Rational(3, 1),
+ Rational(3, 1073741827) * Rational(1073741827, 1))
+ assert_equal(Rational(3, 1152921511049297929),
+ Rational(3, 1073741827) / Rational(1073741827, 1))
+ assert_equal(Rational(2147483663, 3221225481),
+ Rational(3, 1073741827) + Rational(2, 3))
+ assert_equal(Rational(-2147483645, 3221225481),
+ Rational(3, 1073741827) - Rational(2, 3))
+ assert_equal(Rational(2, 1073741827),
+ Rational(3, 1073741827) * Rational(2, 3))
+ assert_equal(Rational(9, 2147483654),
+ Rational(3, 1073741827) / Rational(2, 3))
+ assert_equal(Rational(3221225487, 2147483654),
+ Rational(3, 1073741827) + Rational(3, 2))
+ assert_equal(Rational(-3221225475, 2147483654),
+ Rational(3, 1073741827) - Rational(3, 2))
+ assert_equal(Rational(9, 2147483654),
+ Rational(3, 1073741827) * Rational(3, 2))
+ assert_equal(Rational(2, 1073741827),
+ Rational(3, 1073741827) / Rational(3, 2))
+ assert_equal(Rational(6442450848, 1152921470247108503),
+ Rational(3, 1073741827) + Rational(3, 1073741789))
+ assert_equal(Rational(-114, 1152921470247108503),
+ Rational(3, 1073741827) - Rational(3, 1073741789))
+ assert_equal(Rational(9, 1152921470247108503),
+ Rational(3, 1073741827) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(3, 1073741827) / Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108512, 3221225481),
+ Rational(3, 1073741827) + Rational(1073741789, 3))
+ assert_equal(Rational(-1152921470247108494, 3221225481),
+ Rational(3, 1073741827) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(3, 1073741827) * Rational(1073741789, 3))
+ assert_equal(Rational(9, 1152921470247108503),
+ Rational(3, 1073741827) / Rational(1073741789, 3))
+ assert_equal(Rational(6, 1073741827),
+ Rational(3, 1073741827) + Rational(3, 1073741827))
+ assert_equal(Rational(0, 1),
+ Rational(3, 1073741827) - Rational(3, 1073741827))
+ assert_equal(Rational(9, 1152921511049297929),
+ Rational(3, 1073741827) * Rational(3, 1073741827))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1073741827) / Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297938, 3221225481),
+ Rational(3, 1073741827) + Rational(1073741827, 3))
+ assert_equal(Rational(-1152921511049297920, 3221225481),
+ Rational(3, 1073741827) - Rational(1073741827, 3))
+ assert_equal(Rational(1, 1),
+ Rational(3, 1073741827) * Rational(1073741827, 3))
+ assert_equal(Rational(9, 1152921511049297929),
+ Rational(3, 1073741827) / Rational(1073741827, 3))
+ assert_equal(Rational(1073741792, 1073741827),
+ Rational(3, 1073741827) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(-1073741786, 1073741827),
+ Rational(3, 1073741827) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(3221225367, 1152921511049297929),
+ Rational(3, 1073741827) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1073741827) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921514270523296, 1152921470247108503),
+ Rational(3, 1073741827) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-1152921507828072562, 1152921470247108503),
+ Rational(3, 1073741827) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(3, 1073741789),
+ Rational(3, 1073741827) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(3221225367, 1152921511049297929),
+ Rational(3, 1073741827) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741830, 3),
+ Rational(1073741827, 3) + Rational(1, 1))
+ assert_equal(Rational(1073741824, 3),
+ Rational(1073741827, 3) - Rational(1, 1))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 3) * Rational(1, 1))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 3) / Rational(1, 1))
+ assert_equal(Rational(1073741833, 3),
+ Rational(1073741827, 3) + Rational(2, 1))
+ assert_equal(Rational(1073741821, 3),
+ Rational(1073741827, 3) - Rational(2, 1))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 3) * Rational(2, 1))
+ assert_equal(Rational(1073741827, 6),
+ Rational(1073741827, 3) / Rational(2, 1))
+ assert_equal(Rational(1073741836, 3),
+ Rational(1073741827, 3) + Rational(3, 1))
+ assert_equal(Rational(1073741818, 3),
+ Rational(1073741827, 3) - Rational(3, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741827, 3) * Rational(3, 1))
+ assert_equal(Rational(1073741827, 9),
+ Rational(1073741827, 3) / Rational(3, 1))
+ assert_equal(Rational(4294967194, 3),
+ Rational(1073741827, 3) + Rational(1073741789, 1))
+ assert_equal(Rational(-2147483540, 3),
+ Rational(1073741827, 3) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921470247108503, 3),
+ Rational(1073741827, 3) * Rational(1073741789, 1))
+ assert_equal(Rational(1073741827, 3221225367),
+ Rational(1073741827, 3) / Rational(1073741789, 1))
+ assert_equal(Rational(4294967308, 3),
+ Rational(1073741827, 3) + Rational(1073741827, 1))
+ assert_equal(Rational(-2147483654, 3),
+ Rational(1073741827, 3) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921511049297929, 3),
+ Rational(1073741827, 3) * Rational(1073741827, 1))
+ assert_equal(Rational(1, 3),
+ Rational(1073741827, 3) / Rational(1073741827, 1))
+ assert_equal(Rational(357913943, 1),
+ Rational(1073741827, 3) + Rational(2, 3))
+ assert_equal(Rational(1073741825, 3),
+ Rational(1073741827, 3) - Rational(2, 3))
+ assert_equal(Rational(2147483654, 9),
+ Rational(1073741827, 3) * Rational(2, 3))
+ assert_equal(Rational(1073741827, 2),
+ Rational(1073741827, 3) / Rational(2, 3))
+ assert_equal(Rational(2147483663, 6),
+ Rational(1073741827, 3) + Rational(3, 2))
+ assert_equal(Rational(2147483645, 6),
+ Rational(1073741827, 3) - Rational(3, 2))
+ assert_equal(Rational(1073741827, 2),
+ Rational(1073741827, 3) * Rational(3, 2))
+ assert_equal(Rational(2147483654, 9),
+ Rational(1073741827, 3) / Rational(3, 2))
+ assert_equal(Rational(1152921470247108512, 3221225367),
+ Rational(1073741827, 3) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108494, 3221225367),
+ Rational(1073741827, 3) - Rational(3, 1073741789))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 3) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921470247108503, 9),
+ Rational(1073741827, 3) / Rational(3, 1073741789))
+ assert_equal(Rational(715827872, 1),
+ Rational(1073741827, 3) + Rational(1073741789, 3))
+ assert_equal(Rational(38, 3),
+ Rational(1073741827, 3) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921470247108503, 9),
+ Rational(1073741827, 3) * Rational(1073741789, 3))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 3) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921511049297938, 3221225481),
+ Rational(1073741827, 3) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297920, 3221225481),
+ Rational(1073741827, 3) - Rational(3, 1073741827))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 3) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297929, 9),
+ Rational(1073741827, 3) / Rational(3, 1073741827))
+ assert_equal(Rational(2147483654, 3),
+ Rational(1073741827, 3) + Rational(1073741827, 3))
+ assert_equal(Rational(0, 1),
+ Rational(1073741827, 3) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921511049297929, 9),
+ Rational(1073741827, 3) * Rational(1073741827, 3))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 3) / Rational(1073741827, 3))
+ assert_equal(Rational(1152921514270523296, 3221225481),
+ Rational(1073741827, 3) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921507828072562, 3221225481),
+ Rational(1073741827, 3) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741827, 3) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921511049297929, 3221225367),
+ Rational(1073741827, 3) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921473468333984, 3221225367),
+ Rational(1073741827, 3) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921467025883022, 3221225367),
+ Rational(1073741827, 3) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921511049297929, 3221225367),
+ Rational(1073741827, 3) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741827, 3) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483616, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(1, 1))
+ assert_equal(Rational(-38, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(1, 1))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(1, 1))
+ assert_equal(Rational(1073741789, 1073741827),
+ Rational(1073741789, 1073741827) / Rational(1, 1))
+ assert_equal(Rational(3221225443, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(2, 1))
+ assert_equal(Rational(-1073741865, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(2, 1))
+ assert_equal(Rational(2147483578, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(2, 1))
+ assert_equal(Rational(1073741789, 2147483654),
+ Rational(1073741789, 1073741827) / Rational(2, 1))
+ assert_equal(Rational(4294967270, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(3, 1))
+ assert_equal(Rational(-2147483692, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(3, 1))
+ assert_equal(Rational(3221225367, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(3, 1))
+ assert_equal(Rational(1073741789, 3221225481),
+ Rational(1073741789, 1073741827) / Rational(3, 1))
+ assert_equal(Rational(1152921471320850292, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(1073741789, 1))
+ assert_equal(Rational(-1152921469173366714, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(1073741789, 1))
+ assert_equal(Rational(1152921429444920521, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(1073741789, 1))
+ assert_equal(Rational(1, 1073741827),
+ Rational(1073741789, 1073741827) / Rational(1073741789, 1))
+ assert_equal(Rational(1152921512123039718, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(1073741827, 1))
+ assert_equal(Rational(-1152921509975556140, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(1073741827, 1))
+ assert_equal(Rational(1073741789, 1),
+ Rational(1073741789, 1073741827) * Rational(1073741827, 1))
+ assert_equal(Rational(1073741789, 1152921511049297929),
+ Rational(1073741789, 1073741827) / Rational(1073741827, 1))
+ assert_equal(Rational(5368709021, 3221225481),
+ Rational(1073741789, 1073741827) + Rational(2, 3))
+ assert_equal(Rational(1073741713, 3221225481),
+ Rational(1073741789, 1073741827) - Rational(2, 3))
+ assert_equal(Rational(2147483578, 3221225481),
+ Rational(1073741789, 1073741827) * Rational(2, 3))
+ assert_equal(Rational(3221225367, 2147483654),
+ Rational(1073741789, 1073741827) / Rational(2, 3))
+ assert_equal(Rational(5368709059, 2147483654),
+ Rational(1073741789, 1073741827) + Rational(3, 2))
+ assert_equal(Rational(-1073741903, 2147483654),
+ Rational(1073741789, 1073741827) - Rational(3, 2))
+ assert_equal(Rational(3221225367, 2147483654),
+ Rational(1073741789, 1073741827) * Rational(3, 2))
+ assert_equal(Rational(2147483578, 3221225481),
+ Rational(1073741789, 1073741827) / Rational(3, 2))
+ assert_equal(Rational(1152921432666146002, 1152921470247108503),
+ Rational(1073741789, 1073741827) + Rational(3, 1073741789))
+ assert_equal(Rational(1152921426223695040, 1152921470247108503),
+ Rational(1073741789, 1073741827) - Rational(3, 1073741789))
+ assert_equal(Rational(3, 1073741827),
+ Rational(1073741789, 1073741827) * Rational(3, 1073741789))
+ assert_equal(Rational(1152921429444920521, 3221225481),
+ Rational(1073741789, 1073741827) / Rational(3, 1073741789))
+ assert_equal(Rational(1152921473468333870, 3221225481),
+ Rational(1073741789, 1073741827) + Rational(1073741789, 3))
+ assert_equal(Rational(-1152921467025883136, 3221225481),
+ Rational(1073741789, 1073741827) - Rational(1073741789, 3))
+ assert_equal(Rational(1152921429444920521, 3221225481),
+ Rational(1073741789, 1073741827) * Rational(1073741789, 3))
+ assert_equal(Rational(3, 1073741827),
+ Rational(1073741789, 1073741827) / Rational(1073741789, 3))
+ assert_equal(Rational(1073741792, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(3, 1073741827))
+ assert_equal(Rational(1073741786, 1073741827),
+ Rational(1073741789, 1073741827) - Rational(3, 1073741827))
+ assert_equal(Rational(3221225367, 1152921511049297929),
+ Rational(1073741789, 1073741827) * Rational(3, 1073741827))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 1073741827) / Rational(3, 1073741827))
+ assert_equal(Rational(1152921514270523296, 3221225481),
+ Rational(1073741789, 1073741827) + Rational(1073741827, 3))
+ assert_equal(Rational(-1152921507828072562, 3221225481),
+ Rational(1073741789, 1073741827) - Rational(1073741827, 3))
+ assert_equal(Rational(1073741789, 3),
+ Rational(1073741789, 1073741827) * Rational(1073741827, 3))
+ assert_equal(Rational(3221225367, 1152921511049297929),
+ Rational(1073741789, 1073741827) / Rational(1073741827, 3))
+ assert_equal(Rational(2147483578, 1073741827),
+ Rational(1073741789, 1073741827) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(0, 1),
+ Rational(1073741789, 1073741827) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921429444920521, 1152921511049297929),
+ Rational(1073741789, 1073741827) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 1073741827) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(2305842940494218450, 1152921470247108503),
+ Rational(1073741789, 1073741827) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(-81604377408, 1152921470247108503),
+ Rational(1073741789, 1073741827) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1, 1),
+ Rational(1073741789, 1073741827) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921429444920521, 1152921511049297929),
+ Rational(1073741789, 1073741827) / Rational(1073741827, 1073741789))
+ assert_equal(Rational(2147483616, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(1, 1))
+ assert_equal(Rational(38, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(1, 1))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(1, 1))
+ assert_equal(Rational(1073741827, 1073741789),
+ Rational(1073741827, 1073741789) / Rational(1, 1))
+ assert_equal(Rational(3221225405, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(2, 1))
+ assert_equal(Rational(-1073741751, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(2, 1))
+ assert_equal(Rational(2147483654, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(2, 1))
+ assert_equal(Rational(1073741827, 2147483578),
+ Rational(1073741827, 1073741789) / Rational(2, 1))
+ assert_equal(Rational(4294967194, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(3, 1))
+ assert_equal(Rational(-2147483540, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(3, 1))
+ assert_equal(Rational(3221225481, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(3, 1))
+ assert_equal(Rational(1073741827, 3221225367),
+ Rational(1073741827, 1073741789) / Rational(3, 1))
+ assert_equal(Rational(1152921430518662348, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(1073741789, 1))
+ assert_equal(Rational(-1152921428371178694, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(1073741789, 1))
+ assert_equal(Rational(1073741827, 1),
+ Rational(1073741827, 1073741789) * Rational(1073741789, 1))
+ assert_equal(Rational(1073741827, 1152921429444920521),
+ Rational(1073741827, 1073741789) / Rational(1073741789, 1))
+ assert_equal(Rational(1152921471320850330, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(1073741827, 1))
+ assert_equal(Rational(-1152921469173366676, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(1073741827, 1))
+ assert_equal(Rational(1152921511049297929, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(1073741827, 1))
+ assert_equal(Rational(1, 1073741789),
+ Rational(1073741827, 1073741789) / Rational(1073741827, 1))
+ assert_equal(Rational(5368709059, 3221225367),
+ Rational(1073741827, 1073741789) + Rational(2, 3))
+ assert_equal(Rational(1073741903, 3221225367),
+ Rational(1073741827, 1073741789) - Rational(2, 3))
+ assert_equal(Rational(2147483654, 3221225367),
+ Rational(1073741827, 1073741789) * Rational(2, 3))
+ assert_equal(Rational(3221225481, 2147483578),
+ Rational(1073741827, 1073741789) / Rational(2, 3))
+ assert_equal(Rational(5368709021, 2147483578),
+ Rational(1073741827, 1073741789) + Rational(3, 2))
+ assert_equal(Rational(-1073741713, 2147483578),
+ Rational(1073741827, 1073741789) - Rational(3, 2))
+ assert_equal(Rational(3221225481, 2147483578),
+ Rational(1073741827, 1073741789) * Rational(3, 2))
+ assert_equal(Rational(2147483654, 3221225367),
+ Rational(1073741827, 1073741789) / Rational(3, 2))
+ assert_equal(Rational(1073741830, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(3, 1073741789))
+ assert_equal(Rational(1073741824, 1073741789),
+ Rational(1073741827, 1073741789) - Rational(3, 1073741789))
+ assert_equal(Rational(3221225481, 1152921429444920521),
+ Rational(1073741827, 1073741789) * Rational(3, 1073741789))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 1073741789) / Rational(3, 1073741789))
+ assert_equal(Rational(1152921432666146002, 3221225367),
+ Rational(1073741827, 1073741789) + Rational(1073741789, 3))
+ assert_equal(Rational(-1152921426223695040, 3221225367),
+ Rational(1073741827, 1073741789) - Rational(1073741789, 3))
+ assert_equal(Rational(1073741827, 3),
+ Rational(1073741827, 1073741789) * Rational(1073741789, 3))
+ assert_equal(Rational(3221225481, 1152921429444920521),
+ Rational(1073741827, 1073741789) / Rational(1073741789, 3))
+ assert_equal(Rational(1152921514270523296, 1152921470247108503),
+ Rational(1073741827, 1073741789) + Rational(3, 1073741827))
+ assert_equal(Rational(1152921507828072562, 1152921470247108503),
+ Rational(1073741827, 1073741789) - Rational(3, 1073741827))
+ assert_equal(Rational(3, 1073741789),
+ Rational(1073741827, 1073741789) * Rational(3, 1073741827))
+ assert_equal(Rational(1152921511049297929, 3221225367),
+ Rational(1073741827, 1073741789) / Rational(3, 1073741827))
+ assert_equal(Rational(1152921473468333984, 3221225367),
+ Rational(1073741827, 1073741789) + Rational(1073741827, 3))
+ assert_equal(Rational(-1152921467025883022, 3221225367),
+ Rational(1073741827, 1073741789) - Rational(1073741827, 3))
+ assert_equal(Rational(1152921511049297929, 3221225367),
+ Rational(1073741827, 1073741789) * Rational(1073741827, 3))
+ assert_equal(Rational(3, 1073741789),
+ Rational(1073741827, 1073741789) / Rational(1073741827, 3))
+ assert_equal(Rational(2305842940494218450, 1152921470247108503),
+ Rational(1073741827, 1073741789) + Rational(1073741789, 1073741827))
+ assert_equal(Rational(81604377408, 1152921470247108503),
+ Rational(1073741827, 1073741789) - Rational(1073741789, 1073741827))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 1073741789) * Rational(1073741789, 1073741827))
+ assert_equal(Rational(1152921511049297929, 1152921429444920521),
+ Rational(1073741827, 1073741789) / Rational(1073741789, 1073741827))
+ assert_equal(Rational(2147483654, 1073741789),
+ Rational(1073741827, 1073741789) + Rational(1073741827, 1073741789))
+ assert_equal(Rational(0, 1),
+ Rational(1073741827, 1073741789) - Rational(1073741827, 1073741789))
+ assert_equal(Rational(1152921511049297929, 1152921429444920521),
+ Rational(1073741827, 1073741789) * Rational(1073741827, 1073741789))
+ assert_equal(Rational(1, 1),
+ Rational(1073741827, 1073741789) / Rational(1073741827, 1073741789))
+ end
+
+end
diff --git a/trunk/test/ruby/test_readpartial.rb b/trunk/test/ruby/test_readpartial.rb
new file mode 100644
index 0000000000..c4f9d193f2
--- /dev/null
+++ b/trunk/test/ruby/test_readpartial.rb
@@ -0,0 +1,70 @@
+require 'test/unit'
+require 'timeout'
+require 'fcntl'
+
+class TestReadPartial < Test::Unit::TestCase
+ def make_pipe
+ r, w = IO.pipe
+ begin
+ yield r, w
+ ensure
+ r.close unless r.closed?
+ w.close unless w.closed?
+ end
+ end
+
+ def pipe
+ make_pipe {|r, w|
+ yield r, w
+ }
+ return unless defined?(Fcntl::F_SETFL)
+ return unless defined?(Fcntl::F_GETFL)
+ return unless defined?(Fcntl::O_NONBLOCK)
+ make_pipe {|r, w|
+ r.fcntl(Fcntl::F_SETFL, r.fcntl(Fcntl::F_GETFL) | Fcntl::O_NONBLOCK)
+ yield r, w
+ }
+ end
+
+ def test_length_zero
+ pipe {|r, w|
+ assert_equal('', r.readpartial(0))
+ }
+ end
+
+ def test_closed_pipe
+ pipe {|r, w|
+ w << 'abc'
+ w.close
+ assert_equal('ab', r.readpartial(2))
+ assert_equal('c', r.readpartial(2))
+ assert_raises(EOFError) { r.readpartial(2) }
+ assert_raises(EOFError) { r.readpartial(2) }
+ }
+ end
+
+ def test_open_pipe
+ pipe {|r, w|
+ w << 'abc'
+ assert_equal('ab', r.readpartial(2))
+ assert_equal('c', r.readpartial(2))
+ assert_raises(TimeoutError) {
+ timeout(0.1) { r.readpartial(2) }
+ }
+ }
+ end
+
+ def test_with_stdio
+ pipe {|r, w|
+ w << "abc\ndef\n"
+ assert_equal("abc\n", r.gets)
+ w << "ghi\n"
+ assert_equal("de", r.readpartial(2))
+ assert_equal("f\n", r.readpartial(4096))
+ assert_equal("ghi\n", r.readpartial(4096))
+ assert_raises(TimeoutError) {
+ timeout(0.1) { r.readpartial(2) }
+ }
+ }
+ end
+end
diff --git a/trunk/test/ruby/test_regexp.rb b/trunk/test/ruby/test_regexp.rb
new file mode 100644
index 0000000000..ad222c5483
--- /dev/null
+++ b/trunk/test/ruby/test_regexp.rb
@@ -0,0 +1,758 @@
+require 'test/unit'
+
+class TestRegexp < Test::Unit::TestCase
+ def setup
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+ end
+
+ def teardown
+ $VERBOSE = @verbose
+ end
+
+ def test_ruby_dev_24643
+ assert_nothing_raised("[ruby-dev:24643]") {
+ /(?:(?:[a]*[a])?b)*a*$/ =~ "aabaaca"
+ }
+ end
+
+ def test_ruby_talk_116455
+ assert_match(/^(\w{2,}).* ([A-Za-z\xa2\xc0-\xff]{2,}?)$/n, "Hallo Welt")
+ end
+
+ def test_ruby_dev_24887
+ assert_equal("a".gsub(/a\Z/, ""), "")
+ end
+
+ def test_yoshidam_net_20041111_1
+ s = "[\xC2\xA0-\xC3\xBE]"
+ assert_match(Regexp.new(s, nil, "u"), "\xC3\xBE")
+ end
+
+ def test_yoshidam_net_20041111_2
+ assert_raise(RegexpError) do
+ s = "[\xFF-\xFF]".force_encoding("utf-8")
+ Regexp.new(s, nil, "u")
+ end
+ end
+
+ def test_ruby_dev_31309
+ assert_equal('Ruby', 'Ruby'.sub(/[^a-z]/i, '-'))
+ end
+
+ def test_assert_normal_exit
+ # moved from knownbug. It caused core.
+ Regexp.union("a", "a")
+ end
+
+ def test_to_s
+ assert_equal '(?-mix:\x00)', Regexp.new("\0").to_s
+ end
+
+ def test_union
+ assert_equal :ok, begin
+ Regexp.union(
+ "a",
+ Regexp.new("\xc2\xa1".force_encoding("euc-jp")),
+ Regexp.new("\xc2\xa1".force_encoding("utf-8")))
+ :ng
+ rescue ArgumentError
+ :ok
+ end
+ end
+
+ def test_named_capture
+ m = /&(?<foo>.*?);/.match("aaa &amp; yyy")
+ assert_equal("amp", m["foo"])
+ assert_equal("amp", m[:foo])
+ assert_equal(5, m.begin(:foo))
+ assert_equal(8, m.end(:foo))
+ assert_equal([5,8], m.offset(:foo))
+
+ assert_equal("aaa [amp] yyy",
+ "aaa &amp; yyy".sub(/&(?<foo>.*?);/, '[\k<foo>]'))
+
+ assert_equal('#<MatchData "&amp; y" foo:"amp">',
+ /&(?<foo>.*?); (y)/.match("aaa &amp; yyy").inspect)
+ assert_equal('#<MatchData "&amp; y" 1:"amp" 2:"y">',
+ /&(.*?); (y)/.match("aaa &amp; yyy").inspect)
+ assert_equal('#<MatchData "&amp; y" foo:"amp" bar:"y">',
+ /&(?<foo>.*?); (?<bar>y)/.match("aaa &amp; yyy").inspect)
+ assert_equal('#<MatchData "&amp; y" foo:"amp" foo:"y">',
+ /&(?<foo>.*?); (?<foo>y)/.match("aaa &amp; yyy").inspect)
+
+ /(?<id>[A-Za-z_]+)/ =~ "!abc"
+ assert_equal("abc", Regexp.last_match(:id))
+
+ /a/ =~ "b" # doesn't match.
+ assert_equal(nil, Regexp.last_match)
+ assert_equal(nil, Regexp.last_match(1))
+ assert_equal(nil, Regexp.last_match(:foo))
+
+ assert_equal(["foo", "bar"], /(?<foo>.)(?<bar>.)/.names)
+ assert_equal(["foo"], /(?<foo>.)(?<foo>.)/.names)
+ assert_equal([], /(.)(.)/.names)
+
+ assert_equal(["foo", "bar"], /(?<foo>.)(?<bar>.)/.match("ab").names)
+ assert_equal(["foo"], /(?<foo>.)(?<foo>.)/.match("ab").names)
+ assert_equal([], /(.)(.)/.match("ab").names)
+
+ assert_equal({"foo"=>[1], "bar"=>[2]},
+ /(?<foo>.)(?<bar>.)/.named_captures)
+ assert_equal({"foo"=>[1, 2]},
+ /(?<foo>.)(?<foo>.)/.named_captures)
+ assert_equal({}, /(.)(.)/.named_captures)
+
+ assert_equal("a[b]c", "abc".sub(/(?<x>[bc])/, "[\\k<x>]"))
+ end
+
+ def test_assign_named_capture
+ assert_equal("a", eval('/(?<foo>.)/ =~ "a"; foo'))
+ assert_equal("a", eval('foo = 1; /(?<foo>.)/ =~ "a"; foo'))
+ assert_equal("a", eval('1.times {|foo| /(?<foo>.)/ =~ "a"; break foo }'))
+ assert_nothing_raised { eval('/(?<Foo>.)/ =~ "a"') }
+ assert_nil(eval('/(?<Foo>.)/ =~ "a"; defined? Foo'))
+ end
+
+ def test_assign_named_capture_to_reserved_word
+ /(?<nil>.)/ =~ "a"
+ assert(!local_variables.include?(:nil), "[ruby-dev:32675]")
+ end
+
+ def test_match_regexp
+ r = /./
+ m = r.match("a")
+ assert_equal(r, m.regexp)
+ re = /foo/
+ assert_equal(re, re.match("foo").regexp)
+ end
+
+ def test_source
+ assert_equal('', //.source)
+ end
+
+ def test_inspect
+ assert_equal('//', //.inspect)
+ assert_equal('//i', //i.inspect)
+ assert_equal('/\//i', /\//i.inspect)
+ assert_equal('/\//i', /#{'/'}/i.inspect)
+ assert_equal('/\/x/i', /\/x/i.inspect)
+ assert_equal('/\x00/i', /#{"\0"}/i.inspect)
+ assert_equal("/\n/i", /#{"\n"}/i.inspect)
+ s = [0xff].pack("C")
+ assert_equal('/\/'+s+'/i', /\/#{s}/i.inspect)
+ end
+
+ def test_char_to_option
+ assert_equal("BAR", "FOOBARBAZ"[/b../i])
+ assert_equal("bar", "foobarbaz"[/ b . . /x])
+ assert_equal("bar\n", "foo\nbar\nbaz"[/b.../m])
+ assert_raise(SyntaxError) { eval('//z') }
+ end
+
+ def test_char_to_option_kcode
+ assert_equal("bar", "foobarbaz"[/b../s])
+ assert_equal("bar", "foobarbaz"[/b../e])
+ assert_equal("bar", "foobarbaz"[/b../u])
+ end
+
+ def test_to_s2
+ assert_equal('(?-mix:foo)', /(?:foo)/.to_s)
+ assert_equal('(?m-ix:foo)', /(?:foo)/m.to_s)
+ assert_equal('(?mi-x:foo)', /(?:foo)/mi.to_s)
+ assert_equal('(?mix:foo)', /(?:foo)/mix.to_s)
+ assert_equal('(?m-ix:foo)', /(?m-ix:foo)/.to_s)
+ assert_equal('(?mi-x:foo)', /(?mi-x:foo)/.to_s)
+ assert_equal('(?mix:foo)', /(?mix:foo)/.to_s)
+ assert_equal('(?mix:)', /(?mix)/.to_s)
+ assert_equal('(?-mix:(?mix:foo) )', /(?mix:foo) /.to_s)
+ end
+
+ def test_casefold_p
+ assert_equal(false, /a/.casefold?)
+ assert_equal(true, /a/i.casefold?)
+ assert_equal(false, /(?i:a)/.casefold?)
+ end
+
+ def test_options
+ assert_equal(Regexp::IGNORECASE, /a/i.options)
+ assert_equal(Regexp::EXTENDED, /a/x.options)
+ assert_equal(Regexp::MULTILINE, /a/m.options)
+ end
+
+ def test_match_init_copy
+ m = /foo/.match("foo")
+ assert_equal(/foo/, m.dup.regexp)
+ assert_raise(TypeError) do
+ m.instance_eval { initialize_copy(nil) }
+ end
+ assert_equal([0, 3], m.offset(0))
+ assert_equal(/foo/, m.dup.regexp)
+ end
+
+ def test_match_size
+ m = /(.)(.)(\d+)(\d)/.match("THX1138.")
+ assert_equal(5, m.size)
+ end
+
+ def test_match_offset_begin_end
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal([3, 6], m.offset("x"))
+ assert_equal(3, m.begin("x"))
+ assert_equal(6, m.end("x"))
+ assert_raise(IndexError) { m.offset("y") }
+ assert_raise(IndexError) { m.offset(2) }
+ assert_raise(IndexError) { m.begin(2) }
+ assert_raise(IndexError) { m.end(2) }
+
+ m = /(?<x>q..)?/.match("foobarbaz")
+ assert_equal([nil, nil], m.offset("x"))
+ assert_equal(nil, m.begin("x"))
+ assert_equal(nil, m.end("x"))
+
+ m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044")
+ assert_equal([1, 2], m.offset(1))
+ assert_equal([nil, nil], m.offset(2))
+ assert_equal([2, 3], m.offset(3))
+ end
+
+ def test_match_to_s
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal("bar", m.to_s)
+ end
+
+ def test_match_pre_post
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal("foo", m.pre_match)
+ assert_equal("baz", m.post_match)
+ end
+
+ def test_match_array
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal(["foobarbaz", "foo", "bar", "baz", nil], m.to_a)
+ end
+
+ def test_match_captures
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal(["foo", "bar", "baz", nil], m.captures)
+ end
+
+ def test_match_aref
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal("foo", m[1])
+ assert_equal(["foo", "bar", "baz"], m[1..3])
+ assert_nil(m[5])
+ assert_raise(IndexError) { m[:foo] }
+ end
+
+ def test_match_values_at
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal(["foo", "bar", "baz"], m.values_at(1, 2, 3))
+ end
+
+ def test_match_string
+ m = /(?<x>b..)/.match("foobarbaz")
+ assert_equal("foobarbaz", m.string)
+ end
+
+ def test_match_inspect
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal('#<MatchData "foobarbaz" 1:"foo" 2:"bar" 3:"baz" 4:nil>', m.inspect)
+ end
+
+ def test_initialize
+ assert_raise(ArgumentError) { Regexp.new }
+ assert_equal(/foo/, Regexp.new(/foo/, Regexp::IGNORECASE))
+ re = /foo/
+ assert_raise(SecurityError) do
+ Thread.new { $SAFE = 4; re.instance_eval { initialize(re) } }.join
+ end
+ re.taint
+ assert_raise(SecurityError) do
+ Thread.new { $SAFE = 4; re.instance_eval { initialize(re) } }.join
+ end
+
+ assert_equal(Encoding.find("ASCII-8BIT"), Regexp.new("b..", nil, "n").encoding)
+ assert_equal("bar", "foobarbaz"[Regexp.new("b..", nil, "n")])
+
+ assert_raise(RegexpError) { Regexp.new(")(") }
+ end
+
+ def test_unescape
+ assert_raise(ArgumentError) { s = '\\'; /#{ s }/ }
+ assert_equal(/\177/, (s = '\177'; /#{ s }/))
+ assert_raise(ArgumentError) { s = '\u'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u{ ffffffff }'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u{ ffffff }'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u{ ffff X }'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u{ }'; /#{ s }/ }
+ assert_equal("b", "abc"[(s = '\u{0062}'; /#{ s }/)])
+ assert_equal("b", "abc"[(s = '\u0062'; /#{ s }/)])
+ assert_raise(ArgumentError) { s = '\u0'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u000X'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = "\xff" + '\u3042'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\u3042' + [0xff].pack("C"); /#{ s }/ }
+ assert_raise(SyntaxError) { s = ''; eval(%q(/\u#{ s }/)) }
+
+ assert_equal(/a/, eval(%q(s="\u0061";/#{s}/n)))
+ assert_raise(RegexpError) { s = "\u3042"; eval(%q(/#{s}/n)) }
+ assert_raise(RegexpError) { s = "\u0061"; eval(%q(/\u3042#{s}/n)) }
+ assert_raise(ArgumentError) { s1=[0xff].pack("C"); s2="\u3042"; eval(%q(/#{s1}#{s2}/)) }
+
+ assert_raise(ArgumentError) { s = '\x'; /#{ s }/ }
+
+ assert_equal("\xe1", [0x00, 0xe1, 0xff].pack("C*")[/\M-a/])
+ assert_equal("\xdc", [0x00, 0xdc, 0xff].pack("C*")[/\M-\\/])
+ assert_equal("\x8a", [0x00, 0x8a, 0xff].pack("C*")[/\M-\n/])
+ assert_equal("\x89", [0x00, 0x89, 0xff].pack("C*")[/\M-\t/])
+ assert_equal("\x8d", [0x00, 0x8d, 0xff].pack("C*")[/\M-\r/])
+ assert_equal("\x8c", [0x00, 0x8c, 0xff].pack("C*")[/\M-\f/])
+ assert_equal("\x8b", [0x00, 0x8b, 0xff].pack("C*")[/\M-\v/])
+ assert_equal("\x87", [0x00, 0x87, 0xff].pack("C*")[/\M-\a/])
+ assert_equal("\x9b", [0x00, 0x9b, 0xff].pack("C*")[/\M-\e/])
+ assert_equal("\x01", [0x00, 0x01, 0xff].pack("C*")[/\C-a/])
+
+ assert_raise(ArgumentError) { s = '\M'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\M-\M-a'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\M-\\'; /#{ s }/ }
+
+ assert_raise(ArgumentError) { s = '\C'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\c'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\C-\C-a'; /#{ s }/ }
+
+ assert_raise(ArgumentError) { s = '\M-\z'; /#{ s }/ }
+ assert_raise(ArgumentError) { s = '\M-\777'; /#{ s }/ }
+
+ assert_equal("\u3042\u3042", "\u3042\u3042"[(s = "\u3042" + %q(\xe3\x81\x82); /#{s}/)])
+ assert_raise(ArgumentError) { s = "\u3042" + %q(\xe3); /#{s}/ }
+ assert_raise(ArgumentError) { s = "\u3042" + %q(\xe3\xe3); /#{s}/ }
+ assert_raise(ArgumentError) { s = '\u3042' + [0xff].pack("C"); /#{s}/ }
+
+ assert_raise(SyntaxError) { eval("/\u3042/n") }
+
+ s = ".........."
+ 5.times { s.sub!(".", "") }
+ assert_equal(".....", s)
+ end
+
+ def test_equal
+ assert_equal(true, /abc/ == /abc/)
+ assert_equal(false, /abc/ == /abc/m)
+ assert_equal(false, /abc/ == /abd/)
+ end
+
+ def test_match
+ assert_nil(//.match(nil))
+ assert_equal("abc", /.../.match(:abc)[0])
+ assert_raise(TypeError) { /.../.match(Object.new)[0] }
+ assert_equal("bc", /../.match('abc', 1)[0])
+ assert_equal("bc", /../.match('abc', -2)[0])
+ assert_nil(/../.match("abc", -4))
+ assert_nil(/../.match("abc", 4))
+ assert_equal('\x', /../n.match("\u3042" + '\x', 1)[0])
+
+ r = nil
+ /.../.match("abc") {|m| r = m[0] }
+ assert_equal("abc", r)
+
+ $_ = "abc"; assert_equal(1, ~/bc/)
+ $_ = "abc"; assert_nil(~/d/)
+ $_ = nil; assert_nil(~/./)
+ end
+
+ def test_eqq
+ assert_equal(false, /../ === nil)
+ end
+
+ def test_quote
+ assert_equal("\xff", Regexp.quote([0xff].pack("C")))
+ assert_equal("\\ ", Regexp.quote("\ "))
+ assert_equal("\\t", Regexp.quote("\t"))
+ assert_equal("\\n", Regexp.quote("\n"))
+ assert_equal("\\r", Regexp.quote("\r"))
+ assert_equal("\\f", Regexp.quote("\f"))
+ assert_equal("\\v", Regexp.quote("\v"))
+ assert_equal("\u3042\\t", Regexp.quote("\u3042\t"))
+ assert_equal("\\t\xff", Regexp.quote("\t" + [0xff].pack("C")))
+ end
+
+ def test_try_convert
+ assert_equal(/re/, Regexp.try_convert(/re/))
+ assert_nil(Regexp.try_convert("re"))
+
+ o = Object.new
+ assert_nil(Regexp.try_convert(o))
+ def o.to_regexp() /foo/ end
+ assert_equal(/foo/, Regexp.try_convert(o))
+ end
+
+ def test_union2
+ assert_equal(/(?!)/, Regexp.union)
+ assert_equal(/foo/, Regexp.union(/foo/))
+ assert_equal(/foo/, Regexp.union([/foo/]))
+ assert_equal(/\t/, Regexp.union("\t"))
+ assert_equal(/(?-mix:\u3042)|(?-mix:\u3042)/, Regexp.union(/\u3042/, /\u3042/))
+ assert_equal("\u3041", "\u3041"[Regexp.union(/\u3042/, "\u3041")])
+ end
+
+ def test_dup
+ assert_equal(//, //.dup)
+ assert_raise(TypeError) { //.instance_eval { initialize_copy(nil) } }
+ end
+
+ def test_regsub
+ assert_equal("fooXXXbaz", "foobarbaz".sub!(/bar/, "XXX"))
+ s = [0xff].pack("C")
+ assert_equal(s, "X".sub!(/./, s))
+ assert_equal('\\' + s, "X".sub!(/./, '\\' + s))
+ assert_equal('\k', "foo".sub!(/.../, '\k'))
+ assert_raise(RuntimeError) { "foo".sub!(/(?<x>o)/, '\k<x') }
+ assert_equal('foo[bar]baz', "foobarbaz".sub!(/(b..)/, '[\0]'))
+ assert_equal('foo[foo]baz', "foobarbaz".sub!(/(b..)/, '[\`]'))
+ assert_equal('foo[baz]baz', "foobarbaz".sub!(/(b..)/, '[\\\']'))
+ assert_equal('foo[r]baz', "foobarbaz".sub!(/(b)(.)(.)/, '[\+]'))
+ assert_equal('foo[\\]baz', "foobarbaz".sub!(/(b..)/, '[\\\\]'))
+ assert_equal('foo[\z]baz', "foobarbaz".sub!(/(b..)/, '[\z]'))
+ end
+
+ def test_KCODE
+ assert_nil($KCODE)
+ assert_nothing_raised { $KCODE = nil }
+ assert_equal(false, $=)
+ assert_nothing_raised { $= = nil }
+ end
+
+ def test_match_setter
+ /foo/ =~ "foo"
+ m = $~
+ /bar/ =~ "bar"
+ $~ = m
+ assert_equal("foo", $&)
+ end
+
+ def test_last_match
+ /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal("foobarbaz", Regexp.last_match(0))
+ assert_equal("foo", Regexp.last_match(1))
+ assert_nil(Regexp.last_match(5))
+ assert_nil(Regexp.last_match(-1))
+ end
+
+ def test_getter
+ alias $__REGEXP_TEST_LASTMATCH__ $&
+ alias $__REGEXP_TEST_PREMATCH__ $`
+ alias $__REGEXP_TEST_POSTMATCH__ $'
+ alias $__REGEXP_TEST_LASTPARENMATCH__ $+
+ /(b)(.)(.)/.match("foobarbaz")
+ assert_equal("bar", $__REGEXP_TEST_LASTMATCH__)
+ assert_equal("foo", $__REGEXP_TEST_PREMATCH__)
+ assert_equal("baz", $__REGEXP_TEST_POSTMATCH__)
+ assert_equal("r", $__REGEXP_TEST_LASTPARENMATCH__)
+
+ /(...)(...)(...)/.match("foobarbaz")
+ assert_equal("baz", $+)
+ end
+
+ def test_rindex_regexp
+ assert_equal(3, "foobarbaz\u3042".rindex(/b../n, 5))
+ end
+
+ def test_taint
+ m = Thread.new do
+ "foo"[/foo/]
+ $SAFE = 4
+ /foo/.match("foo")
+ end.value
+ assert(m.tainted?)
+ end
+
+ def check(re, ss, fs = [])
+ re = Regexp.new(re) unless re.is_a?(Regexp)
+ ss = [ss] unless ss.is_a?(Array)
+ ss.each do |e, s|
+ s ||= e
+ assert_match(re, s)
+ m = re.match(s)
+ assert_equal(e, m[0])
+ end
+ fs = [fs] unless fs.is_a?(Array)
+ fs.each {|s| assert_no_match(re, s) }
+ end
+
+ def failcheck(re)
+ assert_raise(RegexpError) { /#{ re }/ }
+ end
+
+ def test_parse
+ check(/\*\+\?\{\}\|\(\)\<\>\`\'/, "*+?{}|()<>`'")
+ check(/\A\w\W\z/, %w(a. b!), %w(.. ab))
+ check(/\A.\b.\b.\B.\B.\z/, %w(a.aaa .a...), %w(aaaaa .....))
+ check(/\A\s\S\z/, [' a', "\n."], [' ', "\n\n", 'a '])
+ check(/\A\d\D\z/, '0a', %w(00 aa))
+ check(/\A\h\H\z/, %w(0g ag BH), %w(a0 af GG))
+ check(/\Afoo\Z\s\z/, "foo\n", ["foo", "foo\nbar"])
+ assert_equal(%w(a b c), "abc def".scan(/\G\w/))
+ check(/\A\u3042\z/, "\u3042", ["", "\u3043", "a"])
+ check(/\A(..)\1\z/, %w(abab ....), %w(abba aba))
+ failcheck('\1')
+ check(/\A\80\z/, "80", ["\100", ""])
+ check(/\A\77\z/, "?")
+ check(/\A\78\z/, "\7" + '8', ["\100", ""])
+ check(/\A\Qfoo\E\z/, "QfooE")
+ check(/\Aa++\z/, "aaa")
+ check('\Ax]\z', "x]")
+ check(/x#foo/x, "x", "#foo")
+ check(/\Ax#foo#{ "\n" }x\z/x, "xx", ["x", "x#foo\nx"])
+ check(/\A\p{Alpha}\z/, ["a", "z"], [".", "", ".."])
+ check(/\A\p{^Alpha}\z/, [".", "!"], ["!a", ""])
+ check(/\A\n\z/, "\n")
+ check(/\A\t\z/, "\t")
+ check(/\A\r\z/, "\r")
+ check(/\A\f\z/, "\f")
+ check(/\A\a\z/, "\007")
+ check(/\A\e\z/, "\033")
+ check(/\A\v\z/, "\v")
+ failcheck('(')
+ failcheck('(?foo)')
+ failcheck('/\p{foobarbazqux}/')
+ failcheck('/\p{foobarbazqux' + 'a' * 1000 + '}/')
+ failcheck('/[1-\w]/')
+ end
+
+ def test_exec
+ check(/A*B/, %w(B AB AAB AAAB), %w(A))
+ check(/\w*!/, %w(! a! ab! abc!), %w(abc))
+ check(/\w*\W/, %w(! a" ab# abc$), %w(abc))
+ check(/\w*\w/, %w(z az abz abcz), %w(!))
+ check(/[a-z]*\w/, %w(z az abz abcz), %w(!))
+ check(/[a-z]*\W/, %w(! a" ab# abc$), %w(A))
+ check(/((a|bb|ccc|dddd)(1|22|333|4444))/i, %w(a1 bb1 a22), %w(a2 b1))
+ check(/\u0080/, (1..4).map {|i| ["\u0080", "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080/, (2..4).map {|i| ["\u0080" * 2, "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080\u0080/, (3..4).map {|i| ["\u0080" * 3, "\u0080" * i] }, ["\u0081"])
+ check(/\u0080\u0080\u0080\u0080/, (4..4).map {|i| ["\u0080" * 4, "\u0080" * i] }, ["\u0081"])
+ check(/[^\u3042\u3043\u3044]/, %W(a b \u0080 \u3041 \u3045), %W(\u3042 \u3043 \u3044))
+ check(/a.+/m, %W(a\u0080 a\u0080\u0080 a\u0080\u0080\u0080), %W(a))
+ check(/a.+z/m, %W(a\u0080z a\u0080\u0080z a\u0080\u0080\u0080z), %W(az))
+ check(/abc\B.\Bxyz/, %w(abcXxyz abc0xyz), %w(abc|xyz abc-xyz))
+ check(/\Bxyz/, [%w(xyz abcXxyz), %w(xyz abc0xyz)], %w(abc xyz abc-xyz))
+ check(/abc\B/, [%w(abc abcXxyz), %w(abc abc0xyz)], %w(abc xyz abc-xyz))
+ failcheck('(?<foo>abc)\1')
+ check(/^(A+|B+)(?>\g<1>)*[BC]$/, %w(AC BC ABC BAC AABBC), %w(AABB))
+ check(/^(A+|B(?>\g<1>)*)[AC]$/, %w(AAAC BBBAAAAC), %w(BBBAAA))
+ check(/^()(?>\g<1>)*$/, "", "a")
+ check(/^(?>(?=a)(#{ "a" * 1000 }|))++$/, ["a" * 1000, "a" * 2000, "a" * 3000], ["", "a" * 500, "b" * 1000])
+ check(eval('/^(?:a?)?$/'), ["", "a"], ["aa"])
+ check(eval('/^(?:a+)?$/'), ["", "a", "aa"], ["ab"])
+ check(/^(?:a?)+?$/, ["", "a", "aa"], ["ab"])
+ check(/^a??[ab]/, [["a", "a"], ["a", "aa"], ["b", "b"], ["a", "ab"]], ["c"])
+ check(/^(?:a*){3,5}$/, ["", "a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa"], ["b"])
+ check(/^(?:a+){3,5}$/, ["aaa", "aaaa", "aaaaa", "aaaaaa"], ["", "a", "aa", "b"])
+ end
+
+ def test_parse_look_behind
+ check(/(?<=A)B(?=C)/, [%w(B ABC)], %w(aBC ABc aBc))
+ check(/(?<!A)B(?!C)/, [%w(B aBc)], %w(ABC aBC ABc))
+ failcheck('(?<=.*)')
+ failcheck('(?<!.*)')
+ check(/(?<=A|B.)C/, [%w(C AC), %w(C BXC)], %w(C BC))
+ check(/(?<!A|B.)C/, [%w(C C), %w(C BC)], %w(AC BXC))
+ end
+
+ def test_parse_kg
+ check(/\A(.)(.)\k<1>(.)\z/, %w(abac abab ....), %w(abcd aaba xxx))
+ check(/\A(.)(.)\k<-1>(.)\z/, %w(abbc abba ....), %w(abcd aaba xxx))
+ check(/\A(?<n>.)(?<x>\g<n>){0}(?<y>\k<n+0>){0}\g<x>\g<y>\z/, "aba", "abb")
+ check(/\A(?<n>.)(?<x>\g<n>){0}(?<y>\k<n+1>){0}\g<x>\g<y>\z/, "abb", "aba")
+ check(/\A(?<x>..)\k<x>\z/, %w(abab ....), %w(abac abba xxx))
+ check(/\A(.)(..)\g<-1>\z/, "abcde", %w(.... ......))
+ failcheck('\k<x>')
+ failcheck('\k<')
+ failcheck('\k<>')
+ failcheck('\k<.>')
+ failcheck('\k<x.>')
+ failcheck('\k<1.>')
+ failcheck('\k<x')
+ failcheck('\k<x+')
+ failcheck('()\k<-2>')
+ failcheck('()\g<-2>')
+ check(/\A(?<x>.)(?<x>.)\k<x>\z/, %w(aba abb), %w(abc .. ....))
+ check(/\A(?<x>.)(?<x>.)\k<x>\z/i, %w(aba ABa abb ABb), %w(abc .. ....))
+ check(/\k\g/, "kg")
+ failcheck('(.\g<1>)')
+ failcheck('(.\g<2>)')
+ failcheck('(?=\g<1>)')
+ failcheck('((?=\g<1>))')
+ failcheck('(\g<1>|.)')
+ failcheck('(.|\g<1>)')
+ check(/(!)(?<=(a)|\g<1>)/, ["!"], %w(a))
+ check(/^(a|b\g<1>c)$/, %w(a bac bbacc bbbaccc), %w(bbac bacc))
+ check(/^(a|b\g<2>c)(B\g<1>C){0}$/, %w(a bBaCc bBbBaCcCc bBbBbBaCcCcCc), %w(bBbBaCcC BbBaCcCc))
+ check(/\A(?<n>.|X\g<n>)(?<x>\g<n>){0}(?<y>\k<n+0>){0}\g<x>\g<y>\z/, "XXaXbXXa", %w(XXabXa abb))
+ check(/\A(?<n>.|X\g<n>)(?<x>\g<n>){0}(?<y>\k<n+1>){0}\g<x>\g<y>\z/, "XaXXbXXb", %w(aXXbXb aba))
+ failcheck('(?<x>)(?<x>)(\g<x>)')
+ check(/^(?<x>foo)(bar)\k<x>/, %w(foobarfoo), %w(foobar barfoo))
+ check(/^(?<a>f)(?<a>o)(?<a>o)(?<a>b)(?<a>a)(?<a>r)(?<a>b)(?<a>a)(?<a>z)\k<a>{9}$/, %w(foobarbazfoobarbaz foobarbazbazbarfoo foobarbazzabraboof), %w(foobar barfoo))
+ end
+
+ def test_parse_curly_brace
+ check(/\A{/, ["{", ["{", "{x"]])
+ check(/\A{ /, ["{ ", ["{ ", "{ x"]])
+ check(/\A{,}\z/, "{,}")
+ check(/\A{}\z/, "{}")
+ check(/\Aa{0}+\z/, "", %w(a aa aab))
+ check(/\Aa{1}+\z/, %w(a aa), ["", "aab"])
+ check(/\Aa{1,2}b{1,2}\z/, %w(ab aab abb aabb), ["", "aaabb", "abbb"])
+ failcheck('.{100001}')
+ failcheck('.{0,100001}')
+ failcheck('.{1,0}')
+ failcheck('{0}')
+ failcheck('(?!x){0,1}')
+ end
+
+ def test_parse_comment
+ check(/\A(?#foo\)bar)\z/, "", "a")
+ failcheck('(?#')
+ end
+
+ def test_char_type
+ check(/\u3042\d/, ["\u30421", "\u30422"])
+
+ # CClassTable cache test
+ assert(/\u3042\d/.match("\u30421"))
+ assert(/\u3042\d/.match("\u30422"))
+ end
+
+ def test_char_class
+ failcheck('[]')
+ failcheck('[x')
+ check('\A[]]\z', "]", "")
+ check('\A[]\.]+\z', %w(] . ]..]), ["", "["])
+ check(/\A[\u3042]\z/, "\u3042", "\u3042aa")
+ check(/\A[\u3042\x61]+\z/, ["aa\u3042aa", "\u3042\u3042", "a"], ["", "b"])
+ check(/\A[\u3042\x61\x62]+\z/, "abab\u3042abab\u3042")
+ check(/\A[abc]+\z/, "abcba", ["", "ada"])
+ check(/\A[\w][\W]\z/, %w(a. b!), %w(.. ab))
+ check(/\A[\s][\S]\z/, [' a', "\n."], [' ', "\n\n", 'a '])
+ check(/\A[\d][\D]\z/, '0a', %w(00 aa))
+ check(/\A[\h][\H]\z/, %w(0g ag BH), %w(a0 af GG))
+ check(/\A[\p{Alpha}]\z/, ["a", "z"], [".", "", ".."])
+ check(/\A[\p{^Alpha}]\z/, [".", "!"], ["!a", ""])
+ check(/\A[\xff]\z/, "\xff", ["", "\xfe"])
+ check(/\A[\80]+\z/, "8008", ["\\80", "\100", "\1000"])
+ check(/\A[\77]+\z/, "???")
+ check(/\A[\78]+\z/, "\788\7")
+ check(/\A[\0]\z/, "\0")
+ check(/\A[[:0]]\z/, [":", "0"], ["", ":0"])
+ check(/\A[0-]\z/, ["0", "-"], "0-")
+ check('\A[a-&&\w]\z', "a", "-")
+ check('\A[--0]\z', ["-", "/", "0"], ["", "1"])
+ check('\A[\'--0]\z', %w(* + \( \) 0 ,), ["", ".", "1"])
+ check(/\A[a-b-]\z/, %w(a b -), ["", "c"])
+ check('\A[a-b-&&\w]\z', %w(a b), ["", "-"])
+ check('\A[a-b-&&\W]\z', "-", ["", "a", "b"])
+ check('\A[a-c-e]\z', %w(a b c e), %w(- d)) # is it OK?
+ check(/\A[a-f&&[^b-c]&&[^e]]\z/, %w(a d f), %w(b c e g 0))
+ check(/\A[[^b-c]&&[^e]&&a-f]\z/, %w(a d f), %w(b c e g 0))
+ check(/\A[\n\r\t]\z/, ["\n", "\r", "\t"])
+ failcheck('[9-1]')
+ end
+
+ def test_posix_bracket
+ check(/\A[[:alpha:]0]\z/, %w(0 a), %w(1 .))
+ check(/\A[[:^alpha:]0]\z/, %w(0 1 .), "a")
+ check(/\A[[:alpha\:]]\z/, %w(a l p h a :), %w(b 0 1 .))
+ check(/\A[[:alpha:foo]0]\z/, %w(0 a), %w(1 .))
+ check(/\A[[:xdigit:]&&[:alpha:]]\z/, "a", %w(g 0))
+ check('\A[[:abcdefghijklmnopqrstu:]]+\z', "[]")
+ failcheck('[[:alpha')
+ failcheck('[[:alpha:')
+ failcheck('[[:alp:]]')
+ end
+
+ def test_backward
+ assert_equal(3, "foobar".rindex(/b.r/i))
+ assert_equal(nil, "foovar".rindex(/b.r/i))
+ assert_equal(3, ("foo" + "bar" * 1000).rindex(/#{"bar"*1000}/))
+ assert_equal(4, ("foo\nbar\nbaz\n").rindex(/bar/i))
+ end
+
+ def test_uninitialized
+ assert_raise(TypeError) { Regexp.allocate.hash }
+ assert_raise(TypeError) { Regexp.allocate.eql? Regexp.allocate }
+ assert_raise(TypeError) { Regexp.allocate == Regexp.allocate }
+ assert_raise(TypeError) { Regexp.allocate =~ "" }
+ assert_equal(false, Regexp.allocate === Regexp.allocate)
+ assert_nil(~Regexp.allocate)
+ assert_raise(TypeError) { Regexp.allocate.match("") }
+ assert_raise(TypeError) { Regexp.allocate.to_s }
+ assert_match(/^#<Regexp:.*>$/, Regexp.allocate.inspect)
+ assert_raise(TypeError) { Regexp.allocate.source }
+ assert_raise(TypeError) { Regexp.allocate.casefold? }
+ assert_raise(TypeError) { Regexp.allocate.options }
+ assert_equal(Encoding.find("ASCII-8BIT"), Regexp.allocate.encoding)
+ assert_equal(false, Regexp.allocate.fixed_encoding?)
+ assert_raise(TypeError) { Regexp.allocate.names }
+ assert_raise(TypeError) { Regexp.allocate.named_captures }
+
+ assert_raise(TypeError) { MatchData.allocate.regexp }
+ assert_raise(TypeError) { MatchData.allocate.names }
+ assert_raise(TypeError) { MatchData.allocate.size }
+ assert_raise(TypeError) { MatchData.allocate.length }
+ assert_raise(TypeError) { MatchData.allocate.offset(0) }
+ assert_raise(TypeError) { MatchData.allocate.begin(0) }
+ assert_raise(TypeError) { MatchData.allocate.end(0) }
+ assert_raise(TypeError) { MatchData.allocate.to_a }
+ assert_raise(TypeError) { MatchData.allocate[:foo] }
+ assert_raise(TypeError) { MatchData.allocate.captures }
+ assert_raise(TypeError) { MatchData.allocate.values_at }
+ assert_raise(TypeError) { MatchData.allocate.pre_match }
+ assert_raise(TypeError) { MatchData.allocate.post_match }
+ assert_raise(TypeError) { MatchData.allocate.to_s }
+ assert_match(/^#<MatchData:.*>$/, MatchData.allocate.inspect)
+ assert_raise(TypeError) { MatchData.allocate.string }
+ $~ = MatchData.allocate
+ assert_raise(TypeError) { $& }
+ assert_raise(TypeError) { $` }
+ assert_raise(TypeError) { $' }
+ assert_raise(TypeError) { $+ }
+ end
+
+ def test_unicode
+ assert_match(/^\u3042{0}\p{Any}$/, "a")
+ assert_match(/^\u3042{0}\p{Any}$/, "\u3041")
+ assert_match(/^\u3042{0}\p{Any}$/, "\0")
+ assert_no_match(/^\u3042{0}\p{Any}$/, "\0\0")
+ assert_no_match(/^\u3042{0}\p{Any}$/, "")
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{' + "\u3042" + '}$/') }
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{' + 'a' * 1000 + '}$/') }
+ assert_raise(SyntaxError) { eval('/^\u3042{0}\p{foobarbazqux}$/') }
+ assert_match(/^(\uff21)(a)\1\2$/i, "\uff21A\uff41a")
+ assert_no_match(/^(\uff21)\1$/i, "\uff21A")
+ assert_no_match(/^(\uff41)\1$/i, "\uff41a")
+ assert_match(/^\u00df$/i, "\u00df")
+ assert_match(/^\u00df$/i, "ss")
+ #assert_match(/^(\u00df)\1$/i, "\u00dfss") # this must be bug...
+ assert_match(/^\u00df{2}$/i, "\u00dfss")
+ assert_match(/^\u00c5$/i, "\u00c5")
+ assert_match(/^\u00c5$/i, "\u00e5")
+ assert_match(/^\u00c5$/i, "\u212b")
+ assert_match(/^(\u00c5)\1\1$/i, "\u00c5\u00e5\u212b")
+ assert_match(/^\u0149$/i, "\u0149")
+ assert_match(/^\u0149$/i, "\u02bcn")
+ #assert_match(/^(\u0149)\1$/i, "\u0149\u02bcn") # this must be bug...
+ assert_match(/^\u0149{2}$/i, "\u0149\u02bcn")
+ assert_match(/^\u0390$/i, "\u0390")
+ assert_match(/^\u0390$/i, "\u03b9\u0308\u0301")
+ #assert_match(/^(\u0390)\1$/i, "\u0390\u03b9\u0308\u0301") # this must be bug...
+ assert_match(/^\u0390{2}$/i, "\u0390\u03b9\u0308\u0301")
+ assert_match(/^\ufb05$/i, "\ufb05")
+ assert_match(/^\ufb05$/i, "\ufb06")
+ assert_match(/^\ufb05$/i, "st")
+ #assert_match(/^(\ufb05)\1\1$/i, "\ufb05\ufb06st") # this must be bug...
+ assert_match(/^\ufb05{3}$/i, "\ufb05\ufb06st")
+ assert_match(/^\u03b9\u0308\u0301$/i, "\u0390")
+ assert_nothing_raised { 0x03ffffff.chr("utf-8").size }
+ assert_nothing_raised { 0x7fffffff.chr("utf-8").size }
+ end
+end
diff --git a/trunk/test/ruby/test_require.rb b/trunk/test/ruby/test_require.rb
new file mode 100644
index 0000000000..a5f453a055
--- /dev/null
+++ b/trunk/test/ruby/test_require.rb
@@ -0,0 +1,194 @@
+require 'test/unit'
+
+require 'tempfile'
+require_relative 'envutil'
+
+class TestRequire < Test::Unit::TestCase
+ def test_require_invalid_shared_object
+ t = Tempfile.new(["test_ruby_test_require", ".so"])
+ t.puts "dummy"
+ t.close
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ begin
+ require \"#{ t.path }\"
+ rescue LoadError
+ p :ok
+ end
+ INPUT
+ end
+
+ def test_require_too_long_filename
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ begin
+ require '#{ "foo/" * 10000 }foo'
+ rescue LoadError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err(["-S", "foo/" * 10000 + "foo"], "") do |r, e|
+ assert_equal([], r)
+ assert_operator(2, :<=, e.size)
+ assert_equal("openpath: pathname too long (ignored)", e.first)
+ assert_match(/\(LoadError\)/, e.last)
+ end
+ end
+
+ def test_require_path_home
+ env_rubypath, env_home = ENV["RUBYPATH"], ENV["HOME"]
+
+ ENV["RUBYPATH"] = "~"
+ ENV["HOME"] = "/foo" * 10000
+ assert_in_out_err(%w(-S test_ruby_test_require), "", [], /^.+$/)
+
+ ENV["RUBYPATH"] = "~" + "/foo" * 10000
+ ENV["HOME"] = "/foo"
+ assert_in_out_err(%w(-S test_ruby_test_require), "", [], /^.+$/)
+
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ t.puts "p :ok"
+ t.close
+ ENV["RUBYPATH"] = "~"
+ ENV["HOME"], name = File.split(t.path)
+ assert_in_out_err(["-S", name], "", %w(:ok), [])
+
+ ensure
+ env_rubypath ? ENV["RUBYPATH"] = env_rubypath : ENV.delete("RUBYPATH")
+ env_home ? ENV["HOME"] = env_home : ENV.delete("HOME")
+ end
+
+ def test_define_class
+ begin
+ require "socket"
+ rescue LoadError
+ return
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ BasicSocket = 1
+ begin
+ require 'socket'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ class BasicSocket; end
+ begin
+ require 'socket'
+ p :ng
+ rescue NameError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ class BasicSocket < IO; end
+ begin
+ require 'socket'
+ p :ok
+ rescue Exception
+ p :ng
+ end
+ INPUT
+ end
+
+ def test_define_class_under
+ begin
+ require "zlib"
+ rescue LoadError
+ return
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ module Zlib; end
+ Zlib::Error = 1
+ begin
+ require 'zlib'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ module Zlib; end
+ class Zlib::Error; end
+ begin
+ require 'zlib'
+ p :ng
+ rescue NameError
+ p :ok
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ module Zlib; end
+ class Zlib::Error < StandardError; end
+ begin
+ require 'zlib'
+ p :ok
+ rescue Exception
+ p :ng
+ end
+ INPUT
+ end
+
+ def test_define_module
+ begin
+ require "zlib"
+ rescue LoadError
+ return
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ Zlib = 1
+ begin
+ require 'zlib'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+ end
+
+ def test_define_module_under
+ begin
+ require "socket"
+ rescue LoadError
+ return
+ end
+
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
+ class BasicSocket < IO; end
+ class Socket < BasicSocket; end
+ Socket::Constants = 1
+ begin
+ require 'socket'
+ p :ng
+ rescue TypeError
+ p :ok
+ end
+ INPUT
+ end
+
+ def test_load
+ t = Tempfile.new(["test_ruby_test_require", ".rb"])
+ t.puts "module Foo; end"
+ t.puts "at_exit { p :wrap_end }"
+ t.puts "at_exit { raise 'error in at_exit test' }"
+ t.puts "p :ok"
+ t.close
+
+ assert_in_out_err([], <<-INPUT, %w(:ok :end :wrap_end), /error in at_exit test/)
+ load(#{ t.path.dump }, true)
+ GC.start
+ p :end
+ INPUT
+
+ assert_raise(ArgumentError) { at_exit }
+ end
+end
diff --git a/trunk/test/ruby/test_rubyoptions.rb b/trunk/test/ruby/test_rubyoptions.rb
new file mode 100644
index 0000000000..af4ca282ee
--- /dev/null
+++ b/trunk/test/ruby/test_rubyoptions.rb
@@ -0,0 +1,283 @@
+require 'test/unit'
+
+require 'tmpdir'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestRubyOptions < Test::Unit::TestCase
+ def test_source_file
+ assert_in_out_err([], "", [], [])
+ end
+
+ def test_usage
+ assert_in_out_err(%w(-h)) do |r, e|
+ assert_operator(r.size, :<=, 24)
+ assert_equal([], e)
+ end
+
+ assert_in_out_err(%w(--help)) do |r, e|
+ assert_operator(r.size, :<=, 24)
+ assert_equal([], e)
+ end
+ end
+
+ def test_option_variables
+ assert_in_out_err(["-e", 'p [$-p, $-l, $-a]']) do |r, e|
+ assert_equal(["[false, false, false]"], r)
+ assert_equal([], e)
+ end
+
+ assert_in_out_err(%w(-p -l -a -e) + ['p [$-p, $-l, $-a]'],
+ "foo\nbar\nbaz\n") do |r, e|
+ assert_equal(
+ [ '[true, true, true]', 'foo',
+ '[true, true, true]', 'bar',
+ '[true, true, true]', 'baz' ], r)
+ assert_equal([], e)
+ end
+ end
+
+ def test_warning
+ assert_in_out_err(%w(-W0 -e) + ['p $-W'], "", %w(0), [])
+ assert_in_out_err(%w(-W1 -e) + ['p $-W'], "", %w(1), [])
+ assert_in_out_err(%w(-Wx -e) + ['p $-W'], "", %w(1), [])
+ assert_in_out_err(%w(-W -e) + ['p $-W'], "", %w(2), [])
+ end
+
+ def test_safe_level
+ assert_in_out_err(%w(-T -e) + [""], "", [],
+ /no -e allowed in tainted mode \(SecurityError\)/)
+
+ assert_in_out_err(%w(-T4 -S foo.rb), "", [],
+ /no -S allowed in tainted mode \(SecurityError\)/)
+ end
+
+ def test_debug
+ assert_in_out_err(%w(-de) + ["p $DEBUG"], "", %w(true), [])
+
+ assert_in_out_err(%w(--debug -e) + ["p $DEBUG"], "", %w(true), [])
+ end
+
+ def test_verbose
+ assert_in_out_err(%w(-vve) + [""]) do |r, e|
+ assert_match(/^ruby #{RUBY_VERSION} .*? \[#{RUBY_PLATFORM}\]$/, r.join)
+ assert_equal RUBY_DESCRIPTION, r.join.chomp
+ assert_equal([], e)
+ end
+
+ assert_in_out_err(%w(--verbose -e) + ["p $VERBOSE"], "", %w(true), [])
+
+ assert_in_out_err(%w(--verbose), "", [], [])
+ end
+
+ def test_copyright
+ assert_in_out_err(%w(--copyright), "",
+ /^ruby - Copyright \(C\) 1993-\d+ Yukihiro Matsumoto$/, [])
+
+ assert_in_out_err(%w(--verbose -e) + ["p $VERBOSE"], "", %w(true), [])
+ end
+
+ def test_enable
+ assert_in_out_err(%w(--enable all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--enable-all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--enable=all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--enable foobarbazqux -e) + [""], "", [],
+ /unknown argument for --enable: `foobarbazqux'/)
+ assert_in_out_err(%w(--enable), "", [], /missing argument for --enable/)
+ end
+
+ def test_disable
+ assert_in_out_err(%w(--disable all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--disable-all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--disable=all -e) + [""], "", [], [])
+ assert_in_out_err(%w(--disable foobarbazqux -e) + [""], "", [],
+ /unknown argument for --disable: `foobarbazqux'/)
+ assert_in_out_err(%w(--disable), "", [], /missing argument for --disable/)
+ end
+
+ def test_kanji
+ assert_in_out_err(%w(-KU), "p '\u3042'") do |r, e|
+ assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+ end
+ assert_in_out_err(%w(-KE -e) + [""], "", [], [])
+ assert_in_out_err(%w(-KS -e) + [""], "", [], [])
+ assert_in_out_err(%w(-KN -e) + [""], "", [], [])
+ end
+
+ def test_version
+ assert_in_out_err(%w(--version)) do |r, e|
+ assert_match(/^ruby #{RUBY_VERSION} .*? \[#{RUBY_PLATFORM}\]$/, r.join)
+ assert_equal RUBY_DESCRIPTION, r.join.chomp
+ assert_equal([], e)
+ end
+ end
+
+ def test_eval
+ assert_in_out_err(%w(-e), "", [], /no code specified for -e \(RuntimeError\)/)
+ end
+
+ def test_require
+ require "pp"
+ assert_in_out_err(%w(-r pp -e) + ["pp 1"], "", %w(1), [])
+ assert_in_out_err(%w(-rpp -e) + ["pp 1"], "", %w(1), [])
+ rescue LoadError
+ end
+
+ def test_include
+ d = Dir.tmpdir
+ assert_in_out_err(["-I" + d, "-e", ""], "", [], [])
+ assert_in_out_err(["-I", d, "-e", ""], "", [], [])
+ end
+
+ def test_separator
+ assert_in_out_err(%w(-000 -e) + ["print gets"], "foo\nbar\0baz", %W(foo bar\0baz), [])
+
+ assert_in_out_err(%w(-0141 -e) + ["print gets"], "foo\nbar\0baz", %w(foo ba), [])
+
+ assert_in_out_err(%w(-0e) + ["print gets"], "foo\nbar\0baz", %W(foo bar\0), [])
+ end
+
+ def test_autosplit
+ assert_in_out_err(%w(-an -F: -e) + ["p $F"], "foo:bar:baz\nqux:quux:quuux\n",
+ ['["foo", "bar", "baz\n"]', '["qux", "quux", "quuux\n"]'], [])
+ end
+
+ def test_chdir
+ assert_in_out_err(%w(-C), "", [], /Can't chdir/)
+
+ assert_in_out_err(%w(-C test_ruby_test_rubyoptions_foobarbazqux), "", [], /Can't chdir/)
+
+ d = Dir.tmpdir
+ assert_in_out_err(["-C", d, "-e", "puts Dir.pwd"]) do |r, e|
+ assert(File.identical?(r.join, d))
+ assert_equal([], e)
+ end
+ end
+
+ def test_yydebug
+ assert_in_out_err(["-ye", ""]) do |r, e|
+ assert_equal([], r)
+ assert_not_equal([], e)
+ end
+
+ assert_in_out_err(%w(--yydebug -e) + [""]) do |r, e|
+ assert_equal([], r)
+ assert_not_equal([], e)
+ end
+ end
+
+ def test_encoding
+ assert_in_out_err(%w(-Eutf-8), "p '\u3042'", [], /invalid multibyte char/)
+
+ assert_in_out_err(%w(--encoding), "", [], /missing argument for --encoding/)
+
+ assert_in_out_err(%w(--encoding test_ruby_test_rubyoptions_foobarbazqux), "", [],
+ /unknown encoding name - test_ruby_test_rubyoptions_foobarbazqux \(RuntimeError\)/)
+
+ assert_in_out_err(%w(--encoding utf-8), "p '\u3042'", [], /invalid multibyte char/)
+ end
+
+ def test_syntax_check
+ assert_in_out_err(%w(-c -e 1+1), "", ["Syntax OK"], [])
+ end
+
+ def test_invalid_option
+ assert_in_out_err(%w(--foobarbazqux), "", [], /invalid option --foobarbazqux/)
+
+ assert_in_out_err(%W(-\r -e) + [""], "", [], [])
+
+ assert_in_out_err(%W(-\rx), "", [], /invalid option -\\x0D \(-h will show valid options\) \(RuntimeError\)/)
+
+ assert_in_out_err(%W(-\x01), "", [], /invalid option -\\x01 \(-h will show valid options\) \(RuntimeError\)/)
+
+ assert_in_out_err(%w(-Z), "", [], /invalid option -Z \(-h will show valid options\) \(RuntimeError\)/)
+ end
+
+ def test_rubyopt
+ rubyopt_orig = ENV['RUBYOPT']
+
+ ENV['RUBYOPT'] = ' - -'
+ assert_in_out_err([], "", [], [])
+
+ ENV['RUBYOPT'] = '-e "p 1"'
+ assert_in_out_err([], "", [], /invalid switch in RUBYOPT: -e \(RuntimeError\)/)
+
+ ENV['RUBYOPT'] = '-T1'
+ assert_in_out_err([], "", [], /no program input from stdin allowed in tainted mode \(SecurityError\)/)
+
+ ENV['RUBYOPT'] = '-T4'
+ assert_in_out_err([], "", [], /no program input from stdin allowed in tainted mode \(SecurityError\)/)
+
+ ENV['RUBYOPT'] = '-KN -Eus-ascii'
+ assert_in_out_err(%w(-KU -Eutf-8), "p '\u3042'") do |r, e|
+ assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+ assert_equal([], e)
+ end
+
+ ensure
+ if rubyopt_orig
+ ENV['RUBYOPT'] = rubyopt_orig
+ else
+ ENV.delete('RUBYOPT')
+ end
+ end
+
+ def test_search
+ rubypath_orig = ENV['RUBYPATH']
+ path_orig = ENV['PATH']
+
+ t = Tempfile.new(["test_ruby_test_rubyoption", ".rb"])
+ t.puts "p 1"
+ t.close
+
+ @verbose = $VERBOSE
+ $VERBOSE = nil
+
+ ENV['PATH'] = File.dirname(t.path)
+
+ assert_in_out_err(%w(-S) + [File.basename(t.path)], "", %w(1), [])
+
+ ENV['RUBYPATH'] = File.dirname(t.path)
+
+ assert_in_out_err(%w(-S) + [File.basename(t.path)], "", %w(1), [])
+
+ ensure
+ if rubypath_orig
+ ENV['RUBYPATH'] = rubypath_orig
+ else
+ ENV.delete('RUBYPATH')
+ end
+ if path_orig
+ ENV['PATH'] = path_orig
+ else
+ ENV.delete('PATH')
+ end
+ t.close(true) if t
+ $VERBOSE = @verbose
+ end
+
+ def test_shebang
+ assert_in_out_err([], "#! /test_r_u_b_y_test_r_u_b_y_options_foobarbazqux\r\np 1\r\n",
+ [], /Can't exec [\/\\]test_r_u_b_y_test_r_u_b_y_options_foobarbazqux \(fatal\)/)
+
+ assert_in_out_err([], "#! /test_r_u_b_y_test_r_u_b_y_options_foobarbazqux -foo -bar\r\np 1\r\n",
+ [], /Can't exec [\/\\]test_r_u_b_y_test_r_u_b_y_options_foobarbazqux \(fatal\)/)
+
+ assert_in_out_err([], "#!ruby -KU -Eutf-8\r\np \"\u3042\"\r\n") do |r, e|
+ assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+ assert_equal([], e)
+ end
+ end
+
+ def test_sflag
+ assert_in_out_err(%w(- -abc -def=foo -ghi-jkl -- -xyz),
+ "#!ruby -s\np [$abc, $def, $ghi_jkl, $xyz]\n",
+ ['[true, "foo", true, nil]'], [])
+
+ assert_in_out_err(%w(- -#), "#!ruby -s\n", [],
+ /invalid name for global variable - -# \(NameError\)/)
+
+ assert_in_out_err(%w(- -#=foo), "#!ruby -s\n", [],
+ /invalid name for global variable - -# \(NameError\)/)
+ end
+end
diff --git a/trunk/test/ruby/test_settracefunc.rb b/trunk/test/ruby/test_settracefunc.rb
new file mode 100644
index 0000000000..c098e548b8
--- /dev/null
+++ b/trunk/test/ruby/test_settracefunc.rb
@@ -0,0 +1,184 @@
+require 'test/unit'
+
+class TestSetTraceFunc < Test::Unit::TestCase
+ def setup
+ @original_compile_option = RubyVM::InstructionSequence.compile_option
+ RubyVM::InstructionSequence.compile_option = {
+ :trace_instruction => true,
+ :specialized_instruction => false
+ }
+ end
+
+ def teardown
+ set_trace_func(nil)
+ RubyVM::InstructionSequence.compile_option = @original_compile_option
+ end
+
+ def test_c_call
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: x = 1 + 1
+ 5: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 4, :+, Fixnum],
+ events.shift)
+ assert_equal(["c-return", 4, :+, Fixnum],
+ events.shift)
+ assert_equal(["line", 5, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 5, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_call
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: def add(x, y)
+ 5: x + y
+ 6: end
+ 7: x = add(1, 1)
+ 8: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 4, :method_added, Module],
+ events.shift)
+ assert_equal(["c-return", 4, :method_added, Module],
+ events.shift)
+ assert_equal(["line", 7, __method__, self.class],
+ events.shift)
+ assert_equal(["call", 6, :add, self.class],
+ events.shift)
+ assert_equal(["line", 5, :add, self.class],
+ events.shift)
+ assert_equal(["c-call", 5, :+, Fixnum],
+ events.shift)
+ assert_equal(["c-return", 5, :+, Fixnum],
+ events.shift)
+ assert_equal(["return", 6, :add, self.class],
+ events.shift)
+ assert_equal(["line", 8, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 8, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_class
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: class Foo
+ 5: def bar
+ 6: end
+ 7: end
+ 8: x = Foo.new.bar
+ 9: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 4, :inherited, Class],
+ events.shift)
+ assert_equal(["c-return", 4, :inherited, Class],
+ events.shift)
+ assert_equal(["class", 7, nil, nil],
+ events.shift)
+ assert_equal(["line", 5, nil, nil],
+ events.shift)
+ assert_equal(["c-call", 5, :method_added, Module],
+ events.shift)
+ assert_equal(["c-return", 5, :method_added, Module],
+ events.shift)
+ assert_equal(["end", 7, nil, nil],
+ events.shift)
+ assert_equal(["line", 8, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 8, :new, Class],
+ events.shift)
+ assert_equal(["c-call", 8, :initialize, BasicObject],
+ events.shift)
+ assert_equal(["c-return", 8, :initialize, BasicObject],
+ events.shift)
+ assert_equal(["c-return", 8, :new, Class],
+ events.shift)
+ assert_equal(["call", 6, :bar, Foo],
+ events.shift)
+ assert_equal(["return", 6, :bar, Foo],
+ events.shift)
+ assert_equal(["line", 9, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 9, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_raise
+ events = []
+ eval <<-EOF.gsub(/^.*?: /, "")
+ 1: set_trace_func(Proc.new { |event, file, lineno, mid, binding, klass|
+ 2: events << [event, lineno, mid, klass]
+ 3: })
+ 4: begin
+ 5: raise TypeError, "error"
+ 6: rescue TypeError
+ 7: end
+ 8: set_trace_func(nil)
+ EOF
+ assert_equal(["c-return", 3, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal(["line", 4, __method__, self.class],
+ events.shift)
+ assert_equal(["line", 5, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 5, :raise, Kernel],
+ events.shift)
+ assert_equal(["c-call", 5, :exception, Exception],
+ events.shift)
+ assert_equal(["c-call", 5, :initialize, Exception],
+ events.shift)
+ assert_equal(["c-return", 5, :initialize, Exception],
+ events.shift)
+ assert_equal(["c-return", 5, :exception, Exception],
+ events.shift)
+ assert_equal(["c-call", 5, :backtrace, Exception],
+ events.shift)
+ assert_equal(["c-return", 5, :backtrace, Exception],
+ events.shift)
+ assert_equal(["c-call", 5, :set_backtrace, Exception],
+ events.shift)
+ assert_equal(["c-return", 5, :set_backtrace, Exception],
+ events.shift)
+ assert_equal(["raise", 5, :test_raise, TestSetTraceFunc],
+ events.shift)
+ assert_equal(["c-call", 6, :===, Module],
+ events.shift)
+ assert_equal(["c-return", 6, :===, Module],
+ events.shift)
+ assert_equal(["line", 8, __method__, self.class],
+ events.shift)
+ assert_equal(["c-call", 8, :set_trace_func, Kernel],
+ events.shift)
+ assert_equal([], events)
+ end
+
+ def test_invalid_proc
+ assert_raise(TypeError) { set_trace_func(1) }
+ end
+end
diff --git a/trunk/test/ruby/test_signal.rb b/trunk/test/ruby/test_signal.rb
new file mode 100644
index 0000000000..0bc2078c18
--- /dev/null
+++ b/trunk/test/ruby/test_signal.rb
@@ -0,0 +1,166 @@
+require 'test/unit'
+require 'timeout'
+
+class TestSignal < Test::Unit::TestCase
+ def have_fork?
+ begin
+ Process.fork {}
+ return true
+ rescue NotImplementedError
+ return false
+ end
+ end
+
+ def test_signal
+ return unless Process.respond_to?(:kill)
+ begin
+ x = 0
+ oldtrap = Signal.trap(:INT) {|sig| x = 2 }
+ Process.kill :INT, Process.pid
+ sleep 0.1
+ assert_equal 2, x
+
+ Signal.trap(:INT) { raise "Interrupt" }
+ ex = assert_raises(RuntimeError) {
+ Process.kill :INT, Process.pid
+ sleep 0.1
+ }
+ assert_kind_of Exception, ex
+ assert_match(/Interrupt/, ex.message)
+ ensure
+ Signal.trap :INT, oldtrap if oldtrap
+ end
+ end
+
+ def test_exit_action
+ return unless have_fork? # snip this test
+ begin
+ r, w = IO.pipe
+ r0, w0 = IO.pipe
+ pid = Process.fork {
+ Signal.trap(:USR1, "EXIT")
+ w0.close
+ w.syswrite("a")
+ Thread.start { Thread.pass }
+ r0.sysread(4096)
+ }
+ r.sysread(1)
+ sleep 0.1
+ assert_nothing_raised("[ruby-dev:26128]") {
+ Process.kill(:USR1, pid)
+ begin
+ Timeout.timeout(3) {
+ Process.waitpid pid
+ }
+ rescue Timeout::Error
+ Process.kill(:TERM, pid)
+ raise
+ end
+ }
+ ensure
+ r.close
+ w.close
+ r0.close
+ w0.close
+ end
+ end
+
+ def test_invalid_signal_name
+ return unless Process.respond_to?(:kill)
+
+ assert_raise(ArgumentError) { Process.kill(:XXXXXXXXXX, $$) }
+ end
+
+ def test_signal_exception
+ assert_raise(ArgumentError) { SignalException.new }
+ assert_raise(ArgumentError) { SignalException.new(-1) }
+ assert_raise(ArgumentError) { SignalException.new(:XXXXXXXXXX) }
+ Signal.list.each do |signm, signo|
+ next if signm == "EXIT"
+ assert_equal(SignalException.new(signm).signo, signo)
+ assert_equal(SignalException.new(signm.to_sym).signo, signo)
+ assert_equal(SignalException.new(signo).signo, signo)
+ end
+ end
+
+ def test_interrupt
+ assert_raise(Interrupt) { raise Interrupt.new }
+ end
+
+ def test_signal2
+ return unless Process.respond_to?(:kill)
+ begin
+ x = false
+ oldtrap = Signal.trap(:INT) {|sig| x = true }
+ GC.start
+
+ assert_raise(ArgumentError) { Process.kill }
+
+ Timeout.timeout(10) do
+ x = false
+ Process.kill(SignalException.new(:INT).signo, $$)
+ nil until x
+
+ x = false
+ Process.kill("INT", $$)
+ nil until x
+
+ x = false
+ Process.kill("SIGINT", $$)
+ nil until x
+
+ x = false
+ o = Object.new
+ def o.to_str; "SIGINT"; end
+ Process.kill(o, $$)
+ nil until x
+ end
+
+ assert_raise(ArgumentError) { Process.kill(Object.new, $$) }
+
+ ensure
+ Signal.trap(:INT, oldtrap) if oldtrap
+ end
+ end
+
+ def test_trap
+ return unless Process.respond_to?(:kill)
+ begin
+ oldtrap = Signal.trap(:INT) {|sig| }
+
+ assert_raise(ArgumentError) { Signal.trap }
+
+ assert_raise(SecurityError) do
+ s = proc {}.taint
+ Signal.trap(:INT, s)
+ end
+
+ # FIXME!
+ Signal.trap(:INT, nil)
+ Signal.trap(:INT, "")
+ Signal.trap(:INT, "SIG_IGN")
+ Signal.trap(:INT, "IGNORE")
+
+ Signal.trap(:INT, "SIG_DFL")
+ Signal.trap(:INT, "SYSTEM_DEFAULT")
+
+ Signal.trap(:INT, "EXIT")
+
+ Signal.trap(:INT, "xxxxxx")
+ Signal.trap(:INT, "xxxx")
+
+ Signal.trap(SignalException.new(:INT).signo, "SIG_DFL")
+
+ assert_raise(ArgumentError) { Signal.trap(-1, "xxxx") }
+
+ o = Object.new
+ def o.to_str; "SIGINT"; end
+ Signal.trap(o, "SIG_DFL")
+
+ assert_raise(ArgumentError) { Signal.trap("XXXXXXXXXX", "SIG_DFL") }
+
+ ensure
+ Signal.trap(:INT, oldtrap) if oldtrap
+ end
+ end
+end
diff --git a/trunk/test/ruby/test_sleep.rb b/trunk/test/ruby/test_sleep.rb
new file mode 100644
index 0000000000..675fdc9747
--- /dev/null
+++ b/trunk/test/ruby/test_sleep.rb
@@ -0,0 +1,10 @@
+require 'test/unit'
+
+class TestSleep < Test::Unit::TestCase
+ def test_sleep_5sec
+ start = Time.now
+ sleep 5
+ slept = Time.now-start
+ assert_in_delta(5.0, slept, 0.1, "[ruby-core:18015]: longer than expected")
+ end
+end
diff --git a/trunk/test/ruby/test_sprintf.rb b/trunk/test/ruby/test_sprintf.rb
new file mode 100644
index 0000000000..cad9f5e031
--- /dev/null
+++ b/trunk/test/ruby/test_sprintf.rb
@@ -0,0 +1,273 @@
+require 'test/unit'
+
+class TestSprintf < Test::Unit::TestCase
+ def test_positional
+ assert_equal(" 00001", sprintf("%*1$.*2$3$d", 10, 5, 1))
+ end
+
+ def test_binary
+ assert_equal("0", sprintf("%b", 0))
+ assert_equal("1", sprintf("%b", 1))
+ assert_equal("10", sprintf("%b", 2))
+ assert_equal("..1", sprintf("%b", -1))
+
+ assert_equal(" 0", sprintf("%4b", 0))
+ assert_equal(" 1", sprintf("%4b", 1))
+ assert_equal(" 10", sprintf("%4b", 2))
+ assert_equal(" ..1", sprintf("%4b", -1))
+
+ assert_equal("0000", sprintf("%04b", 0))
+ assert_equal("0001", sprintf("%04b", 1))
+ assert_equal("0010", sprintf("%04b", 2))
+ assert_equal("..11", sprintf("%04b", -1))
+
+ assert_equal("0000", sprintf("%.4b", 0))
+ assert_equal("0001", sprintf("%.4b", 1))
+ assert_equal("0010", sprintf("%.4b", 2))
+ assert_equal("..11", sprintf("%.4b", -1))
+
+ assert_equal(" 0000", sprintf("%6.4b", 0))
+ assert_equal(" 0001", sprintf("%6.4b", 1))
+ assert_equal(" 0010", sprintf("%6.4b", 2))
+ assert_equal(" ..11", sprintf("%6.4b", -1))
+
+ assert_equal(" 0", sprintf("%#4b", 0))
+ assert_equal(" 0b1", sprintf("%#4b", 1))
+ assert_equal("0b10", sprintf("%#4b", 2))
+ assert_equal("0b..1", sprintf("%#4b", -1))
+
+ assert_equal("0000", sprintf("%#04b", 0))
+ assert_equal("0b01", sprintf("%#04b", 1))
+ assert_equal("0b10", sprintf("%#04b", 2))
+ assert_equal("0b..1", sprintf("%#04b", -1))
+
+ assert_equal("0000", sprintf("%#.4b", 0))
+ assert_equal("0b0001", sprintf("%#.4b", 1))
+ assert_equal("0b0010", sprintf("%#.4b", 2))
+ assert_equal("0b..11", sprintf("%#.4b", -1))
+
+ assert_equal(" 0000", sprintf("%#6.4b", 0))
+ assert_equal("0b0001", sprintf("%#6.4b", 1))
+ assert_equal("0b0010", sprintf("%#6.4b", 2))
+ assert_equal("0b..11", sprintf("%#6.4b", -1))
+
+ assert_equal("+0", sprintf("%+b", 0))
+ assert_equal("+1", sprintf("%+b", 1))
+ assert_equal("+10", sprintf("%+b", 2))
+ assert_equal("-1", sprintf("%+b", -1))
+
+ assert_equal(" +0", sprintf("%+4b", 0))
+ assert_equal(" +1", sprintf("%+4b", 1))
+ assert_equal(" +10", sprintf("%+4b", 2))
+ assert_equal(" -1", sprintf("%+4b", -1))
+
+ assert_equal("+000", sprintf("%+04b", 0))
+ assert_equal("+001", sprintf("%+04b", 1))
+ assert_equal("+010", sprintf("%+04b", 2))
+ assert_equal("-001", sprintf("%+04b", -1))
+
+ assert_equal("+0000", sprintf("%+.4b", 0))
+ assert_equal("+0001", sprintf("%+.4b", 1))
+ assert_equal("+0010", sprintf("%+.4b", 2))
+ assert_equal("-0001", sprintf("%+.4b", -1))
+
+ assert_equal(" +0000", sprintf("%+6.4b", 0))
+ assert_equal(" +0001", sprintf("%+6.4b", 1))
+ assert_equal(" +0010", sprintf("%+6.4b", 2))
+ assert_equal(" -0001", sprintf("%+6.4b", -1))
+ end
+
+ def test_nan
+ nan = 0.0 / 0.0
+ assert_equal("NaN", sprintf("%f", nan))
+ assert_equal("NaN", sprintf("%-f", nan))
+ assert_equal("+NaN", sprintf("%+f", nan))
+
+ assert_equal(" NaN", sprintf("%8f", nan))
+ assert_equal("NaN ", sprintf("%-8f", nan))
+ assert_equal(" +NaN", sprintf("%+8f", nan))
+
+ assert_equal(" NaN", sprintf("%08f", nan))
+ assert_equal("NaN ", sprintf("%-08f", nan))
+ assert_equal(" +NaN", sprintf("%+08f", nan))
+
+ assert_equal(" NaN", sprintf("% 8f", nan))
+ assert_equal(" NaN ", sprintf("%- 8f", nan))
+ assert_equal(" +NaN", sprintf("%+ 8f", nan))
+
+ assert_equal(" NaN", sprintf("% 08f", nan))
+ assert_equal(" NaN ", sprintf("%- 08f", nan))
+ assert_equal(" +NaN", sprintf("%+ 08f", nan))
+ end
+
+ def test_inf
+ inf = 1.0 / 0.0
+ assert_equal("Inf", sprintf("%f", inf))
+ assert_equal("Inf", sprintf("%-f", inf))
+ assert_equal("+Inf", sprintf("%+f", inf))
+
+ assert_equal(" Inf", sprintf("%8f", inf))
+ assert_equal("Inf ", sprintf("%-8f", inf))
+ assert_equal(" +Inf", sprintf("%+8f", inf))
+
+ assert_equal(" Inf", sprintf("%08f", inf))
+ assert_equal("Inf ", sprintf("%-08f", inf))
+ assert_equal(" +Inf", sprintf("%+08f", inf))
+
+ assert_equal(" Inf", sprintf("% 8f", inf))
+ assert_equal(" Inf ", sprintf("%- 8f", inf))
+ assert_equal(" +Inf", sprintf("%+ 8f", inf))
+
+ assert_equal(" Inf", sprintf("% 08f", inf))
+ assert_equal(" Inf ", sprintf("%- 08f", inf))
+ assert_equal(" +Inf", sprintf("%+ 08f", inf))
+
+ assert_equal("-Inf", sprintf("%f", -inf))
+ assert_equal("-Inf", sprintf("%-f", -inf))
+ assert_equal("-Inf", sprintf("%+f", -inf))
+
+ assert_equal(" -Inf", sprintf("%8f", -inf))
+ assert_equal("-Inf ", sprintf("%-8f", -inf))
+ assert_equal(" -Inf", sprintf("%+8f", -inf))
+
+ assert_equal(" -Inf", sprintf("%08f", -inf))
+ assert_equal("-Inf ", sprintf("%-08f", -inf))
+ assert_equal(" -Inf", sprintf("%+08f", -inf))
+
+ assert_equal(" -Inf", sprintf("% 8f", -inf))
+ assert_equal("-Inf ", sprintf("%- 8f", -inf))
+ assert_equal(" -Inf", sprintf("%+ 8f", -inf))
+
+ assert_equal(" -Inf", sprintf("% 08f", -inf))
+ assert_equal("-Inf ", sprintf("%- 08f", -inf))
+ assert_equal(" -Inf", sprintf("%+ 08f", -inf))
+ assert_equal('..f00000000',
+ sprintf("%x", -2**32), '[ruby-dev:32351]')
+ assert_equal("..101111111111111111111111111111111",
+ sprintf("%b", -2147483649), '[ruby-dev:32365]')
+ assert_equal(" Inf", sprintf("% e", inf), '[ruby-dev:34002]')
+ end
+
+ def test_invalid
+ # Star precision before star width:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.**d", 5, 10, 1)}
+
+ # Precision before flags and width:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.5+05d", 5)}
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%.5 5d", 5)}
+
+ # Overriding a star width with a numeric one:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%*1s", 5, 1)}
+
+ # Width before flags:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%5+0d", 1)}
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%5 0d", 1)}
+
+ # Specifying width multiple times:
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%50+30+20+10+5d", 5)}
+ assert_raise(ArgumentError, "[ruby-core:11569]") {sprintf("%50 30 20 10 5d", 5)}
+
+ # Specifying the precision multiple times with negative star arguments:
+ assert_raise(ArgumentError, "[ruby-core:11570]") {sprintf("%.*.*.*.*f", -1, -1, -1, 5, 1)}
+
+ # Null bytes after percent signs are removed:
+ assert_equal("%\0x hello", sprintf("%\0x hello"), "[ruby-core:11571]")
+
+ assert_raise(ArgumentError, "[ruby-core:11573]") {sprintf("%.25555555555555555555555555555555555555s", "hello")}
+
+ assert_raise(ArgumentError) { sprintf("%\1", 1) }
+ assert_raise(ArgumentError) { sprintf("%!", 1) }
+ assert_raise(ArgumentError) { sprintf("%1$1$d", 1) }
+ assert_raise(ArgumentError) { sprintf("%0%") }
+ assert_nothing_raised { sprintf("", 1) }
+ end
+
+ def test_float
+ assert_equal("36893488147419111424",
+ sprintf("%20.0f", 36893488147419107329.0))
+ assert_equal(" Inf", sprintf("% 0e", 1.0/0.0), "moved from btest/knownbug")
+ end
+
+ BSIZ = 120
+
+ def test_skip
+ assert_equal(" " * BSIZ + "1", sprintf(" " * BSIZ + "%d", 1))
+ end
+
+ def test_char
+ assert_equal("a", sprintf("%c", 97))
+ assert_equal("a", sprintf("%c", ?a))
+ assert_raise(ArgumentError) { sprintf("%c", sprintf("%c%c", ?a, ?a)) }
+ assert_equal(" " * (BSIZ - 1) + "a", sprintf(" " * (BSIZ - 1) + "%c", ?a))
+ assert_equal(" " * (BSIZ - 1) + "a", sprintf(" " * (BSIZ - 1) + "%-1c", ?a))
+ assert_equal(" " * BSIZ + "a", sprintf("%#{ BSIZ + 1 }c", ?a))
+ assert_equal("a" + " " * BSIZ, sprintf("%-#{ BSIZ + 1 }c", ?a))
+ end
+
+ def test_string
+ assert_equal("foo", sprintf("%s", "foo"))
+ assert_equal("fo", sprintf("%.2s", "foo"))
+ assert_equal(" " * BSIZ, sprintf("%s", " " * BSIZ))
+ assert_equal(" " * (BSIZ - 1) + "foo", sprintf("%#{ BSIZ - 1 + 3 }s", "foo"))
+ assert_equal(" " * BSIZ + "foo", sprintf("%#{ BSIZ + 3 }s", "foo"))
+ assert_equal("foo" + " " * BSIZ, sprintf("%-#{ BSIZ + 3 }s", "foo"))
+ end
+
+ def test_integer
+ assert_equal("01", sprintf("%#o", 1))
+ assert_equal("0x1", sprintf("%#x", 1))
+ assert_equal("0X1", sprintf("%#X", 1))
+ assert_equal("0b1", sprintf("%#b", 1))
+ assert_equal("0B1", sprintf("%#B", 1))
+ assert_equal("1", sprintf("%d", 1.0))
+ assert_equal("4294967296", sprintf("%d", (2**32).to_f))
+ assert_equal("-2147483648", sprintf("%d", -(2**31).to_f))
+ assert_equal("18446744073709551616", sprintf("%d", (2**64).to_f))
+ assert_equal("-9223372036854775808", sprintf("%d", -(2**63).to_f))
+ assert_equal("1", sprintf("%d", "1"))
+ o = Object.new; def o.to_int; 1; end
+ assert_equal("1", sprintf("%d", o))
+ assert_equal("+1", sprintf("%+d", 1))
+ assert_equal(" 1", sprintf("% d", 1))
+ assert_equal("..f", sprintf("%x", -1))
+ assert_equal("..7", sprintf("%o", -1))
+ one = (2**32).coerce(1).first
+ mone = (2**32).coerce(-1).first
+ assert_equal("+1", sprintf("%+d", one))
+ assert_equal(" 1", sprintf("% d", one))
+ assert_equal("..f", sprintf("%x", mone))
+ assert_equal("..7", sprintf("%o", mone))
+ assert_equal(" " * BSIZ + "1", sprintf("%#{ BSIZ + 1 }d", one))
+ assert_equal(" " * (BSIZ - 1) + "1", sprintf(" " * (BSIZ - 1) + "%d", 1))
+ end
+
+ def test_float2
+ inf = 1.0 / 0.0
+ assert_equal(" " * BSIZ + "Inf", sprintf("%#{ BSIZ + 3 }.1f", inf))
+ assert_equal("+Inf", sprintf("%+-f", inf))
+ assert_equal(" " * BSIZ + "1.0", sprintf("%#{ BSIZ + 3 }.1f", 1.0))
+ end
+
+ class T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+ end
+
+ def test_star
+ assert_equal("-1 ", sprintf("%*d", -3, -1))
+ end
+
+ def test_escape
+ assert_equal("%" * BSIZ, sprintf("%%" * BSIZ))
+ end
+
+ def test_rb_sprintf
+ assert(T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.new.inspect =~ /^#<TestSprintf::T012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789:0x[0-9a-f]+>$/)
+ end
+
+ def test_negative_hex
+ s1 = sprintf("%0x", -0x40000000)
+ s2 = sprintf("%0x", -0x40000001)
+ b1 = (/\.\./ =~ s1) != nil
+ b2 = (/\.\./ =~ s2) != nil
+ assert(b1 == b2, "[ruby-dev:33224]")
+ end
+end
diff --git a/trunk/test/ruby/test_sprintf_comb.rb b/trunk/test/ruby/test_sprintf_comb.rb
new file mode 100644
index 0000000000..8b2c1a7e05
--- /dev/null
+++ b/trunk/test/ruby/test_sprintf_comb.rb
@@ -0,0 +1,548 @@
+require 'test/unit'
+require_relative 'allpairs'
+
+class TestSprintfComb < Test::Unit::TestCase
+ VS = [
+ #-0x1000000000000000000000000000000000000000000000002,
+ #-0x1000000000000000000000000000000000000000000000001,
+ #-0x1000000000000000000000000000000000000000000000000,
+ #-0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ #-0x1000000000000000000000002,
+ #-0x1000000000000000000000001,
+ #-0x1000000000000000000000000,
+ #-0xffffffffffffffffffffffff,
+ -0x10000000000000002,
+ -0x10000000000000001,
+ -0x10000000000000000,
+ -0xffffffffffffffff,
+ -0x4000000000000002,
+ -0x4000000000000001,
+ -0x4000000000000000,
+ -0x3fffffffffffffff,
+ -0x100000002,
+ -0x100000001,
+ -0x100000000,
+ -0xffffffff,
+ #-0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001
+ -0x80000002,
+ -0x80000001,
+ -0x80000000,
+ -0x7fffffff,
+ #-0x524b2245,
+ -0x40000002,
+ -0x40000001,
+ -0x40000000,
+ -0x3fffffff,
+ #-0x10002,
+ #-0x10001,
+ #-0x10000,
+ #-0xffff,
+ #-0x8101, # 0x8101 * 0x7f01 = 0x40000001
+ #-0x8002,
+ #-0x8001,
+ #-0x8000,
+ #-0x7fff,
+ #-0x7f01,
+ #-65,
+ #-64,
+ #-63,
+ #-62,
+ #-33,
+ #-32,
+ #-31,
+ #-30,
+ -3,
+ -2,
+ -1,
+ 0,
+ 1,
+ 2,
+ 3,
+ #30,
+ #31,
+ #32,
+ #33,
+ #62,
+ #63,
+ #64,
+ #65,
+ #0x7f01,
+ #0x7ffe,
+ #0x7fff,
+ #0x8000,
+ #0x8001,
+ #0x8101,
+ #0xfffe,
+ #0xffff,
+ #0x10000,
+ #0x10001,
+ 0x3ffffffe,
+ 0x3fffffff,
+ 0x40000000,
+ 0x40000001,
+ #0x524b2245,
+ 0x7ffffffe,
+ 0x7fffffff,
+ 0x80000000,
+ 0x80000001,
+ #0xc717a08d,
+ 0xfffffffe,
+ 0xffffffff,
+ 0x100000000,
+ 0x100000001,
+ 0x3ffffffffffffffe,
+ 0x3fffffffffffffff,
+ 0x4000000000000000,
+ 0x4000000000000001,
+ 0xfffffffffffffffe,
+ 0xffffffffffffffff,
+ 0x10000000000000000,
+ 0x10000000000000001,
+ #0xffffffffffffffffffffffff,
+ #0x1000000000000000000000000,
+ #0x1000000000000000000000001,
+ #0xffffffffffffffffffffffffffffffffffffffffffffffff,
+ #0x1000000000000000000000000000000000000000000000000,
+ #0x1000000000000000000000000000000000000000000000001
+ ]
+ VS.reverse!
+
+ def combination(*args, &b)
+ #AllPairs.exhaustive_each(*args, &b)
+ AllPairs.each(*args, &b)
+ end
+
+ def emu_int(format, v)
+ /\A%( )?(\#)?(\+)?(-)?(0)?(\d+)?(?:\.(\d*))?(.)\z/ =~ format
+ sp = $1
+ hs = $2
+ pl = $3
+ mi = $4
+ zr = $5
+ width = $6
+ precision = $7
+ type = $8
+ width = width.to_i if width
+ precision = precision.to_i if precision
+ prefix = ''
+
+ zr = nil if precision
+
+ zr = nil if mi && zr
+
+ case type
+ when 'b'
+ radix = 2
+ digitmap = {0 => '0', 1 => '1'}
+ complement = !pl && !sp
+ prefix = '0b' if hs && v != 0
+ when 'd'
+ radix = 10
+ digitmap = {}
+ 10.times {|i| digitmap[i] = i.to_s }
+ complement = false
+ when 'o'
+ radix = 8
+ digitmap = {}
+ 8.times {|i| digitmap[i] = i.to_s }
+ complement = !pl && !sp
+ when 'X'
+ radix = 16
+ digitmap = {}
+ 16.times {|i| digitmap[i] = i.to_s(16).upcase }
+ complement = !pl && !sp
+ prefix = '0X' if hs && v != 0
+ when 'x'
+ radix = 16
+ digitmap = {}
+ 16.times {|i| digitmap[i] = i.to_s(16) }
+ complement = !pl && !sp
+ prefix = '0x' if hs && v != 0
+ else
+ raise "unexpected type: #{type.inspect}"
+ end
+
+ digits = []
+ abs = v.abs
+ sign = ''
+ while 0 < abs
+ digits << (abs % radix)
+ abs /= radix
+ end
+
+ if v < 0
+ if complement
+ digits.map! {|d| radix-1 - d }
+ carry = 1
+ digits.each_index {|i|
+ digits[i] += carry
+ carry = 0
+ if radix <= digits[i]
+ digits[i] -= radix
+ carry = 1
+ end
+ }
+ if digits.last != radix-1
+ digits << (radix-1)
+ end
+ sign = '..'
+ else
+ sign = '-'
+ end
+ else
+ if pl
+ sign = '+'
+ elsif sp
+ sign = ' '
+ end
+ end
+
+ dlen = digits.length
+ dlen += 2 if sign == '..'
+
+ if v < 0 && complement
+ d = radix - 1
+ else
+ d = 0
+ end
+ if precision
+ if dlen < precision
+ (precision - dlen).times {
+ digits << d
+ }
+ end
+ else
+ if dlen == 0
+ digits << d
+ end
+ end
+ if type == 'o' && hs
+ if digits.empty? || digits.last != d
+ digits << d
+ end
+ end
+
+ digits.reverse!
+
+ str = digits.map {|d| digitmap[d] }.join
+
+ pad = ''
+ nlen = prefix.length + sign.length + str.length
+ if width && nlen < width
+ len = width - nlen
+ if zr
+ if complement && v < 0
+ pad = digitmap[radix-1] * len
+ else
+ pad = '0' * len
+ end
+ else
+ pad = ' ' * len
+ end
+ end
+
+ if / / =~ pad
+ if sign == '..'
+ str = prefix + sign + str
+ else
+ str = sign + prefix + str
+ end
+ if mi
+ str = str + pad
+ else
+ str = pad + str
+ end
+ else
+ if sign == '..'
+ str = prefix + sign + pad + str
+ else
+ str = sign + prefix + pad + str
+ end
+ end
+
+ str
+ end
+
+ def test_format_integer
+ combination(
+ %w[b d o X x],
+ [nil, 0, 5, 20],
+ ["", ".", ".0", ".8", ".20"],
+ ['', ' '],
+ ['', '#'],
+ ['', '+'],
+ ['', '-'],
+ ['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
+ format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+ VS.each {|v|
+ r = sprintf format, v
+ e = emu_int format, v
+ if true
+ assert_equal(e, r, "sprintf(#{format.dump}, #{v})")
+ else
+ if e != r
+ puts "#{e.dump}\t#{r.dump}\tsprintf(#{format.dump}, #{v})"
+ end
+ end
+ }
+ }
+ end
+
+ FLOAT_VALUES = [
+ -1e100,
+ -123456789.0,
+ -1.0,
+ -0.0,
+ 0.0,
+ 0.01,
+ 1/3.0,
+ 2/3.0,
+ 1.0,
+ 2.0,
+ 9.99999999,
+ 123456789.0,
+ 1e100,
+ Float::MAX,
+ Float::MIN,
+ Float::EPSILON,
+ 1+Float::EPSILON,
+ #1-Float::EPSILON/2,
+ 10 + Float::EPSILON*10,
+ 10 - Float::EPSILON*5,
+ 1.0/0.0,
+ -1.0/0.0,
+ 0.0/0.0,
+ ]
+
+ def split_float10(v)
+ if v == 0
+ if 1/v < 0
+ sign = -1
+ v = -v
+ else
+ sign = 1
+ end
+ else
+ if v < 0
+ sign = -1
+ v = -v
+ else
+ sign = 1
+ end
+ end
+ exp = 0
+ int = v.floor
+ v -= int
+ while v != 0
+ v *= 2
+ int *= 2
+ i = v.floor
+ v -= i
+ int += i
+ exp -= 1
+ end
+ int *= 5 ** (-exp)
+ [sign, int, exp]
+ end
+
+ def emu_e(sp, hs, pl, mi, zr, width, precision, type, v, sign, int, exp)
+ precision = 6 unless precision
+ if int == 0
+ if precision == 0 && !hs
+ result = "0#{type}+00"
+ else
+ result = "0." + "0" * precision + "#{type}+00"
+ end
+ else
+ if int < 10**precision
+ int *= 10**precision
+ exp -= precision
+ end
+ digits = int.to_s.length
+ discard = digits - (precision+1)
+ if discard != 0
+ q, r = int.divmod(10**discard)
+ if r < 10**discard / 2
+ int = q
+ exp += discard
+ elsif (q+1).to_s.length == q.to_s.length
+ int = q+1
+ exp += discard
+ else
+ discard += 1
+ q, r = int.divmod(10**discard)
+ int = q+1
+ exp += discard
+ end
+ end
+ ints = int.to_s
+ frac = ints[1..-1]
+ result = ints[0,1]
+ e = exp + frac.length
+ if precision != 0 || hs
+ result << "."
+ if precision != 0
+ result << frac
+ end
+ end
+ result << type
+ if e == 0
+ if v.abs < 1
+ result << '-00' # glibc 2.7 causes '+00'
+ else
+ result << '+00'
+ end
+ else
+ result << sprintf("%+03d", e)
+ end
+ result
+ end
+ result
+ end
+
+ def emu_f(sp, hs, pl, mi, zr, width, precision, type, sign, int, exp)
+ precision = 6 unless precision
+ if int == 0
+ if precision == 0 && !hs
+ result = '0'
+ else
+ result = '0.' + '0' * precision
+ end
+ else
+ if -precision < exp
+ int *= 10 ** (precision+exp)
+ exp = -precision
+ end
+ if exp < -precision
+ discard = -exp - precision
+ q, r = int.divmod(10**discard)
+ if 10**discard / 2 <= r
+ q += 1
+ end
+ int = q
+ exp += discard
+ end
+ result = int.to_s
+ if result.length <= precision
+ result = '0' * (precision+1 - result.length) + result
+ end
+ if precision != 0 || hs
+ if precision == 0
+ result << '.'
+ else
+ result[-precision,0] = '.'
+ end
+ end
+ end
+ result
+ end
+
+ def emu_float(format, v)
+ /\A%( )?(\#)?(\+)?(-)?(0)?(\d+)?(?:\.(\d*))?(.)\z/ =~ format
+ sp = $1
+ hs = $2
+ pl = $3
+ mi = $4
+ zr = $5
+ width = $6
+ precision = $7
+ type = $8
+ width = width.to_i if width
+ precision = precision.to_i if precision
+
+ zr = nil if mi && zr
+
+ if v.infinite?
+ sign = v < 0 ? -1 : 1
+ int = :inf
+ hs = zr = nil
+ elsif v.nan?
+ sign = 1
+ int = :nan
+ hs = zr = nil
+ else
+ sign, int, exp = split_float10(v)
+ end
+
+ if sign < 0
+ sign = '-'
+ elsif sign == 0
+ sign = ''
+ elsif pl
+ sign = '+'
+ elsif sp
+ sign = ' '
+ else
+ sign = ''
+ end
+
+ if v.nan?
+ result = 'NaN'
+ elsif v.infinite?
+ result = 'Inf'
+ else
+ case type
+ when /[eE]/
+ result = emu_e(sp, hs, pl, mi, zr, width, precision, type, v, sign, int, exp)
+ when /f/
+ result = emu_f(sp, hs, pl, mi, zr, width, precision, type, sign, int, exp)
+ when /[gG]/
+ precision = 6 unless precision
+ precision = 1 if precision == 0
+ r = emu_e(sp, hs, pl, mi, zr, width, precision-1, type.tr('gG', 'eE'), v, sign, int, exp)
+ /[eE]([+-]\d+)/ =~ r
+ e = $1.to_i
+ if e < -4 || precision <= e
+ result = r
+ else
+ result = emu_f(sp, hs, pl, mi, zr, width, precision-1-e, type, sign, int, exp)
+ end
+ result.sub!(/\.[0-9]*/) { $&.sub(/\.?0*\z/, '') } if !hs
+ else
+ raise "unexpected type: #{type}"
+ end
+ end
+
+ pad = ''
+ if width && sign.length + result.length < width
+ if zr
+ pad = '0' * (width - sign.length - result.length)
+ else
+ pad = ' ' * (width - sign.length - result.length)
+ end
+ end
+ if mi
+ sign + result + pad
+ elsif zr
+ sign + pad + result
+ else
+ pad + sign + result
+ end
+
+ end
+
+ def test_format_float
+ combination(
+ %w[e E f g G],
+ [nil, 0, 5, 20],
+ ["", ".", ".0", ".8", ".20", ".200"],
+ ['', ' '],
+ ['', '#'],
+ ['', '+'],
+ ['', '-'],
+ ['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
+ format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+ FLOAT_VALUES.each {|v|
+ r = sprintf format, v
+ e = emu_float format, v
+ if true
+ assert_equal(e, r, "sprintf(#{format.dump}, #{'%.20g' % v})")
+ else
+ if e != r
+ puts "#{e.dump}\t#{r.dump}\tsprintf(#{format.dump}, #{'%.20g' % v})"
+ end
+ end
+ }
+ }
+ end
+end
diff --git a/trunk/test/ruby/test_string.rb b/trunk/test/ruby/test_string.rb
new file mode 100644
index 0000000000..cd32709658
--- /dev/null
+++ b/trunk/test/ruby/test_string.rb
@@ -0,0 +1,1717 @@
+require 'test/unit'
+require_relative 'envutil'
+
+# use of $= is deprecated after 1.7.1
+def pre_1_7_1
+end
+
+class TestString < Test::Unit::TestCase
+
+ def initialize(*args)
+ @cls = String
+ @aref_re_nth = true
+ @aref_re_silent = false
+ @aref_slicebang_silent = true
+ super
+ end
+
+ def S(str)
+ @cls.new(str)
+ end
+
+ def test_s_new
+ assert_equal("RUBY", S("RUBY"))
+ end
+
+ def test_AREF # '[]'
+ assert_equal("A", S("AooBar")[0])
+ assert_equal("B", S("FooBaB")[-1])
+ assert_equal(nil, S("FooBar")[6])
+ assert_equal(nil, S("FooBar")[-7])
+
+ assert_equal(S("Foo"), S("FooBar")[0,3])
+ assert_equal(S("Bar"), S("FooBar")[-3,3])
+ assert_equal(S(""), S("FooBar")[6,2])
+ assert_equal(nil, S("FooBar")[-7,10])
+
+ assert_equal(S("Foo"), S("FooBar")[0..2])
+ assert_equal(S("Foo"), S("FooBar")[0...3])
+ assert_equal(S("Bar"), S("FooBar")[-3..-1])
+ assert_equal(S(""), S("FooBar")[6..2])
+ assert_equal(nil, S("FooBar")[-10..-7])
+
+ assert_equal(S("Foo"), S("FooBar")[/^F../])
+ assert_equal(S("Bar"), S("FooBar")[/..r$/])
+ assert_equal(nil, S("FooBar")[/xyzzy/])
+ assert_equal(nil, S("FooBar")[/plugh/])
+
+ assert_equal(S("Foo"), S("FooBar")[S("Foo")])
+ assert_equal(S("Bar"), S("FooBar")[S("Bar")])
+ assert_equal(nil, S("FooBar")[S("xyzzy")])
+ assert_equal(nil, S("FooBar")[S("plugh")])
+
+ if @aref_re_nth
+ assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/, 1])
+ assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/, 2])
+ assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/, 3])
+ assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/, -1])
+ assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/, -2])
+ assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/, -3])
+ end
+
+ o = Object.new
+ def o.to_int; 2; end
+ assert_equal("o", "foo"[o])
+
+ assert_raise(ArgumentError) { "foo"[] }
+ end
+
+ def test_ASET # '[]='
+ s = S("FooBar")
+ s[0] = S('A')
+ assert_equal(S("AooBar"), s)
+
+ s[-1]= S('B')
+ assert_equal(S("AooBaB"), s)
+ assert_raise(IndexError) { s[-7] = S("xyz") }
+ assert_equal(S("AooBaB"), s)
+ s[0] = S("ABC")
+ assert_equal(S("ABCooBaB"), s)
+
+ s = S("FooBar")
+ s[0,3] = S("A")
+ assert_equal(S("ABar"),s)
+ s[0] = S("Foo")
+ assert_equal(S("FooBar"), s)
+ s[-3,3] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ assert_raise(IndexError) { s[7,3] = S("Bar") }
+ assert_raise(IndexError) { s[-7,3] = S("Bar") }
+
+ s = S("FooBar")
+ s[0..2] = S("A")
+ assert_equal(S("ABar"), s)
+ s[1..3] = S("Foo")
+ assert_equal(S("AFoo"), s)
+ s[-4..-4] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ assert_raise(RangeError) { s[7..10] = S("Bar") }
+ assert_raise(RangeError) { s[-7..-10] = S("Bar") }
+
+ s = S("FooBar")
+ s[/^F../]= S("Bar")
+ assert_equal(S("BarBar"), s)
+ s[/..r$/] = S("Foo")
+ assert_equal(S("BarFoo"), s)
+ if @aref_re_silent
+ s[/xyzzy/] = S("None")
+ assert_equal(S("BarFoo"), s)
+ else
+ assert_raise(IndexError) { s[/xyzzy/] = S("None") }
+ end
+ if @aref_re_nth
+ s[/([A-Z]..)([A-Z]..)/, 1] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ s[/([A-Z]..)([A-Z]..)/, 2] = S("Bar")
+ assert_equal(S("FooBar"), s)
+ assert_raise(IndexError) { s[/([A-Z]..)([A-Z]..)/, 3] = "None" }
+ s[/([A-Z]..)([A-Z]..)/, -1] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ s[/([A-Z]..)([A-Z]..)/, -2] = S("Bar")
+ assert_equal(S("BarFoo"), s)
+ assert_raise(IndexError) { s[/([A-Z]..)([A-Z]..)/, -3] = "None" }
+ end
+
+ s = S("FooBar")
+ s[S("Foo")] = S("Bar")
+ assert_equal(S("BarBar"), s)
+
+ pre_1_7_1 do
+ s = S("FooBar")
+ s[S("Foo")] = S("xyz")
+ assert_equal(S("xyzBar"), s)
+
+ $= = true
+ s = S("FooBar")
+ s[S("FOO")] = S("Bar")
+ assert_equal(S("BarBar"), s)
+ s[S("FOO")] = S("xyz")
+ assert_equal(S("BarBar"), s)
+ $= = false
+ end
+
+ s = S("a string")
+ s[0..s.size] = S("another string")
+ assert_equal(S("another string"), s)
+
+ o = Object.new
+ def o.to_int; 2; end
+ s = "foo"
+ s[o] = "bar"
+ assert_equal("fobar", s)
+
+ assert_raise(ArgumentError) { "foo"[1, 2, 3] = "" }
+ end
+
+ def test_CMP # '<=>'
+ assert_equal(1, S("abcdef") <=> S("abcde"))
+ assert_equal(0, S("abcdef") <=> S("abcdef"))
+ assert_equal(-1, S("abcde") <=> S("abcdef"))
+
+ assert_equal(-1, S("ABCDEF") <=> S("abcdef"))
+
+ pre_1_7_1 do
+ $= = true
+ assert_equal(0, S("ABCDEF") <=> S("abcdef"))
+ $= = false
+ end
+
+ assert_nil("foo" <=> Object.new)
+
+ o = Object.new
+ def o.to_str; "bar"; end
+ assert_nil("foo" <=> o)
+
+ def o.<=>(x); nil; end
+ assert_nil("foo" <=> o)
+
+ def o.<=>(x); 1; end
+ assert_equal(-1, "foo" <=> o)
+
+ def o.<=>(x); 2**100; end
+ assert_equal(-(2**100), "foo" <=> o)
+ end
+
+ def test_EQUAL # '=='
+ assert_equal(false, S("foo") == :foo)
+ assert(S("abcdef") == S("abcdef"))
+
+ pre_1_7_1 do
+ $= = true
+ assert(S("CAT") == S('cat'))
+ assert(S("CaT") == S('cAt'))
+ $= = false
+ end
+
+ assert(S("CAT") != S('cat'))
+ assert(S("CaT") != S('cAt'))
+
+ o = Object.new
+ def o.to_str; end
+ def o.==(x); false; end
+ assert_equal(false, "foo" == o)
+ def o.==(x); true; end
+ assert_equal(true, "foo" == o)
+ end
+
+ def test_LSHIFT # '<<'
+ assert_equal(S("world!"), S("world") << 33)
+ assert_equal(S("world!"), S("world") << S('!'))
+
+ s = "a"
+ 10.times {|i|
+ s << s
+ assert_equal("a" * (2 << i), s)
+ }
+
+ s = ["foo"].pack("p")
+ l = s.size
+ s << "bar"
+ assert_equal(l + 3, s.size)
+ end
+
+ def test_MATCH # '=~'
+ assert_equal(10, S("FeeFieFoo-Fum") =~ /Fum$/)
+ assert_equal(nil, S("FeeFieFoo-Fum") =~ /FUM$/)
+
+ pre_1_7_1 do
+ $= = true
+ assert_equal(10, S("FeeFieFoo-Fum") =~ /FUM$/)
+ $= = false
+ end
+
+ o = Object.new
+ def o.=~(x); x + "bar"; end
+ assert_equal("foobar", S("foo") =~ o)
+
+ assert_raise(TypeError) { S("foo") =~ "foo" }
+ end
+
+ def test_MOD # '%'
+ assert_equal(S("00123"), S("%05d") % 123)
+ assert_equal(S("123 |00000001"), S("%-5s|%08x") % [123, 1])
+ x = S("%3s %-4s%%foo %.0s%5d %#x%c%3.1f %b %x %X %#b %#x %#X") %
+ [S("hi"),
+ 123,
+ S("never seen"),
+ 456,
+ 0,
+ ?A,
+ 3.0999,
+ 11,
+ 171,
+ 171,
+ 11,
+ 171,
+ 171]
+
+ assert_equal(S(' hi 123 %foo 456 0A3.1 1011 ab AB 0b1011 0xab 0XAB'), x)
+ end
+
+ def test_MUL # '*'
+ assert_equal(S("XXX"), S("X") * 3)
+ assert_equal(S("HOHO"), S("HO") * 2)
+ end
+
+ def test_PLUS # '+'
+ assert_equal(S("Yodel"), S("Yo") + S("del"))
+ end
+
+ def casetest(a, b, rev=false)
+ case a
+ when b
+ assert(!rev)
+ else
+ assert(rev)
+ end
+ end
+
+ def test_VERY_EQUAL # '==='
+ # assert_equal(true, S("foo") === :foo)
+ casetest(S("abcdef"), S("abcdef"))
+
+ pre_1_7_1 do
+ $= = true
+ casetest(S("CAT"), S('cat'))
+ casetest(S("CaT"), S('cAt'))
+ $= = false
+ end
+
+ casetest(S("CAT"), S('cat'), true) # Reverse the test - we don't want to
+ casetest(S("CaT"), S('cAt'), true) # find these in the case.
+ end
+
+ def test_capitalize
+ assert_equal(S("Hello"), S("hello").capitalize)
+ assert_equal(S("Hello"), S("hELLO").capitalize)
+ assert_equal(S("123abc"), S("123ABC").capitalize)
+ end
+
+ def test_capitalize!
+ a = S("hello"); a.capitalize!
+ assert_equal(S("Hello"), a)
+
+ a = S("hELLO"); a.capitalize!
+ assert_equal(S("Hello"), a)
+
+ a = S("123ABC"); a.capitalize!
+ assert_equal(S("123abc"), a)
+
+ assert_equal(nil, S("123abc").capitalize!)
+ assert_equal(S("123abc"), S("123ABC").capitalize!)
+ assert_equal(S("Abc"), S("ABC").capitalize!)
+ assert_equal(S("Abc"), S("abc").capitalize!)
+ assert_equal(nil, S("Abc").capitalize!)
+
+ a = S("hello")
+ b = a.dup
+ assert_equal(S("Hello"), a.capitalize!)
+ assert_equal(S("hello"), b)
+
+ end
+
+ def test_center
+ assert_equal(S("hello"), S("hello").center(4))
+ assert_equal(S(" hello "), S("hello").center(11))
+ end
+
+ def test_chomp
+ assert_equal(S("hello"), S("hello").chomp("\n"))
+ assert_equal(S("hello"), S("hello\n").chomp("\n"))
+ save = $/
+
+ $/ = "\n"
+
+ assert_equal(S("hello"), S("hello").chomp)
+ assert_equal(S("hello"), S("hello\n").chomp)
+
+ $/ = "!"
+ assert_equal(S("hello"), S("hello").chomp)
+ assert_equal(S("hello"), S("hello!").chomp)
+ $/ = save
+ end
+
+ def test_chomp!
+ a = S("hello")
+ a.chomp!(S("\n"))
+
+ assert_equal(S("hello"), a)
+ assert_equal(nil, a.chomp!(S("\n")))
+
+ a = S("hello\n")
+ a.chomp!(S("\n"))
+ assert_equal(S("hello"), a)
+ save = $/
+
+ $/ = "\n"
+ a = S("hello")
+ a.chomp!
+ assert_equal(S("hello"), a)
+
+ a = S("hello\n")
+ a.chomp!
+ assert_equal(S("hello"), a)
+
+ $/ = "!"
+ a = S("hello")
+ a.chomp!
+ assert_equal(S("hello"), a)
+
+ a="hello!"
+ a.chomp!
+ assert_equal(S("hello"), a)
+
+ $/ = save
+
+ a = S("hello\n")
+ b = a.dup
+ assert_equal(S("hello"), a.chomp!)
+ assert_equal(S("hello\n"), b)
+
+ s = "foo\r\n"
+ s.chomp!
+ assert_equal("foo", s)
+
+ s = "foo\r"
+ s.chomp!
+ assert_equal("foo", s)
+
+ s = "foo\r\n"
+ s.chomp!("")
+ assert_equal("foo", s)
+
+ s = "foo\r"
+ s.chomp!("")
+ assert_equal("foo\r", s)
+ end
+
+ def test_chop
+ assert_equal(S("hell"), S("hello").chop)
+ assert_equal(S("hello"), S("hello\r\n").chop)
+ assert_equal(S("hello\n"), S("hello\n\r").chop)
+ assert_equal(S(""), S("\r\n").chop)
+ assert_equal(S(""), S("").chop)
+ end
+
+ def test_chop!
+ a = S("hello").chop!
+ assert_equal(S("hell"), a)
+
+ a = S("hello\r\n").chop!
+ assert_equal(S("hello"), a)
+
+ a = S("hello\n\r").chop!
+ assert_equal(S("hello\n"), a)
+
+ a = S("\r\n").chop!
+ assert_equal(S(""), a)
+
+ a = S("").chop!
+ assert_nil(a)
+
+ a = S("hello\n")
+ b = a.dup
+ assert_equal(S("hello"), a.chop!)
+ assert_equal(S("hello\n"), b)
+ end
+
+ def test_clone
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = S("Cool")
+ a.taint if taint
+ a.untrust if untrust
+ a.freeze if frozen
+ b = a.clone
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert_equal(a.frozen?, b.frozen?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ assert_equal(a.tainted?, b.tainted?)
+ end
+ end
+ end
+
+ null = File.exist?("/dev/null") ? "/dev/null" : "NUL" # maybe DOSISH
+ assert_equal("", File.read(null).clone, '[ruby-dev:32819] reported by Kazuhiro NISHIYAMA')
+ end
+
+ def test_concat
+ assert_equal(S("world!"), S("world").concat(33))
+ assert_equal(S("world!"), S("world").concat(S('!')))
+ end
+
+ def test_count
+ a = S("hello world")
+ assert_equal(5, a.count(S("lo")))
+ assert_equal(2, a.count(S("lo"), S("o")))
+ assert_equal(4, a.count(S("hello"), S("^l")))
+ assert_equal(4, a.count(S("ej-m")))
+ assert_equal(0, S("y").count(S("a\\-z")))
+
+ assert_raise(ArgumentError) { "foo".count }
+ end
+
+ def test_crypt
+ assert_equal(S('aaGUC/JkO9/Sc'), S("mypassword").crypt(S("aa")))
+ assert(S('aaGUC/JkO9/Sc') != S("mypassword").crypt(S("ab")))
+ end
+
+ def test_delete
+ assert_equal(S("heo"), S("hello").delete(S("l"), S("lo")))
+ assert_equal(S("he"), S("hello").delete(S("lo")))
+ assert_equal(S("hell"), S("hello").delete(S("aeiou"), S("^e")))
+ assert_equal(S("ho"), S("hello").delete(S("ej-m")))
+ end
+
+ def test_delete!
+ a = S("hello")
+ a.delete!(S("l"), S("lo"))
+ assert_equal(S("heo"), a)
+
+ a = S("hello")
+ a.delete!(S("lo"))
+ assert_equal(S("he"), a)
+
+ a = S("hello")
+ a.delete!(S("aeiou"), S("^e"))
+ assert_equal(S("hell"), a)
+
+ a = S("hello")
+ a.delete!(S("ej-m"))
+ assert_equal(S("ho"), a)
+
+ a = S("hello")
+ assert_nil(a.delete!(S("z")))
+
+ a = S("hello")
+ b = a.dup
+ a.delete!(S("lo"))
+ assert_equal(S("he"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("hello")
+ a.delete!(S("^el"))
+ assert_equal(S("ell"), a)
+
+ assert_raise(ArgumentError) { S("foo").delete! }
+ end
+
+
+ def test_downcase
+ assert_equal(S("hello"), S("helLO").downcase)
+ assert_equal(S("hello"), S("hello").downcase)
+ assert_equal(S("hello"), S("HELLO").downcase)
+ assert_equal(S("abc hello 123"), S("abc HELLO 123").downcase)
+ end
+
+ def test_downcase!
+ a = S("helLO")
+ b = a.dup
+ assert_equal(S("hello"), a.downcase!)
+ assert_equal(S("hello"), a)
+ assert_equal(S("helLO"), b)
+
+ a=S("hello")
+ assert_nil(a.downcase!)
+ assert_equal(S("hello"), a)
+ end
+
+ def test_dump
+ a= S("Test") << 1 << 2 << 3 << 9 << 13 << 10
+ assert_equal(S('"Test\\x01\\x02\\x03\\t\\r\\n"'), a.dump)
+ end
+
+ def test_dup
+ for taint in [ false, true ]
+ for untrust in [ false, true ]
+ for frozen in [ false, true ]
+ a = S("hello")
+ a.taint if taint
+ a.untrust if untrust
+ a.freeze if frozen
+ b = a.dup
+
+ assert_equal(a, b)
+ assert(a.__id__ != b.__id__)
+ assert(!b.frozen?)
+ assert_equal(a.tainted?, b.tainted?)
+ assert_equal(a.untrusted?, b.untrusted?)
+ end
+ end
+ end
+ end
+
+ def test_each
+ save = $/
+ $/ = "\n"
+ res=[]
+ S("hello\nworld").lines.each {|x| res << x}
+ assert_equal(S("hello\n"), res[0])
+ assert_equal(S("world"), res[1])
+
+ res=[]
+ S("hello\n\n\nworld").lines(S('')).each {|x| res << x}
+ assert_equal(S("hello\n\n\n"), res[0])
+ assert_equal(S("world"), res[1])
+
+ $/ = "!"
+ res=[]
+ S("hello!world").lines.each {|x| res << x}
+ assert_equal(S("hello!"), res[0])
+ assert_equal(S("world"), res[1])
+ $/ = save
+ end
+
+ def test_each_byte
+ res = []
+ S("ABC").each_byte {|x| res << x }
+ assert_equal(65, res[0])
+ assert_equal(66, res[1])
+ assert_equal(67, res[2])
+ end
+
+ def test_each_line
+ save = $/
+ $/ = "\n"
+ res=[]
+ S("hello\nworld").lines.each {|x| res << x}
+ assert_equal(S("hello\n"), res[0])
+ assert_equal(S("world"), res[1])
+
+ res=[]
+ S("hello\n\n\nworld").lines(S('')).each {|x| res << x}
+ assert_equal(S("hello\n\n\n"), res[0])
+ assert_equal(S("world"), res[1])
+
+ $/ = "!"
+
+ res=[]
+ S("hello!world").lines.each {|x| res << x}
+ assert_equal(S("hello!"), res[0])
+ assert_equal(S("world"), res[1])
+
+ $/ = save
+
+ s = nil
+ "foo\nbar".each_line(nil) {|s2| s = s2 }
+ assert_equal("foo\nbar", s)
+ end
+
+ def test_empty?
+ assert(S("").empty?)
+ assert(!S("not").empty?)
+ end
+
+ def test_eql?
+ a = S("hello")
+ assert(a.eql?(S("hello")))
+ assert(a.eql?(a))
+ end
+
+ def test_gsub
+ assert_equal(S("h*ll*"), S("hello").gsub(/[aeiou]/, S('*')))
+ assert_equal(S("h<e>ll<o>"), S("hello").gsub(/([aeiou])/, S('<\1>')))
+ assert_equal(S("h e l l o "),
+ S("hello").gsub(/./) { |s| s[0].to_s + S(' ')})
+ assert_equal(S("HELL-o"),
+ S("hello").gsub(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 })
+
+ a = S("hello")
+ a.taint
+ a.untrust
+ assert(a.gsub(/./, S('X')).tainted?)
+ assert(a.gsub(/./, S('X')).untrusted?)
+
+ assert_equal("z", "abc".gsub(/./, "a" => "z"), "moved from btest/knownbug")
+
+ assert_raise(ArgumentError) { "foo".gsub }
+ end
+
+ def test_gsub!
+ a = S("hello")
+ b = a.dup
+ a.gsub!(/[aeiou]/, S('*'))
+ assert_equal(S("h*ll*"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("hello")
+ a.gsub!(/([aeiou])/, S('<\1>'))
+ assert_equal(S("h<e>ll<o>"), a)
+
+ a = S("hello")
+ a.gsub!(/./) { |s| s[0].to_s + S(' ')}
+ assert_equal(S("h e l l o "), a)
+
+ a = S("hello")
+ a.gsub!(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 }
+ assert_equal(S("HELL-o"), a)
+
+ r = S('X')
+ r.taint
+ r.untrust
+ a.gsub!(/./, r)
+ assert(a.tainted?)
+ assert(a.untrusted?)
+
+ a = S("hello")
+ assert_nil(a.sub!(S('X'), S('Y')))
+ end
+
+ def test_sub_hash
+ assert_equal('azc', 'abc'.sub(/b/, "b" => "z"))
+ assert_equal('ac', 'abc'.sub(/b/, {}))
+ assert_equal('a1c', 'abc'.sub(/b/, "b" => 1))
+ assert_equal('aBc', 'abc'.sub(/b/, Hash.new {|h, k| k.upcase }))
+ assert_equal('a[\&]c', 'abc'.sub(/b/, "b" => '[\&]'))
+ assert_equal('aBcabc', 'abcabc'.sub(/b/, Hash.new {|h, k| h[k] = k.upcase }))
+ assert_equal('aBcdef', 'abcdef'.sub(/de|b/, "b" => "B", "de" => "DE"))
+ end
+
+ def test_gsub_hash
+ assert_equal('azc', 'abc'.gsub(/b/, "b" => "z"))
+ assert_equal('ac', 'abc'.gsub(/b/, {}))
+ assert_equal('a1c', 'abc'.gsub(/b/, "b" => 1))
+ assert_equal('aBc', 'abc'.gsub(/b/, Hash.new {|h, k| k.upcase }))
+ assert_equal('a[\&]c', 'abc'.gsub(/b/, "b" => '[\&]'))
+ assert_equal('aBcaBc', 'abcabc'.gsub(/b/, Hash.new {|h, k| h[k] = k.upcase }))
+ assert_equal('aBcDEf', 'abcdef'.gsub(/de|b/, "b" => "B", "de" => "DE"))
+ end
+
+ def test_hash
+ assert_equal(S("hello").hash, S("hello").hash)
+ assert(S("hello").hash != S("helLO").hash)
+ end
+
+ def test_hash_random
+ str = 'abc'
+ a = [str.hash.to_s]
+ 3.times {
+ assert_in_out_err(["-e", "print #{str.dump}.hash"], "") do |r, e|
+ a += r
+ assert_equal([], e)
+ end
+ }
+ assert_not_equal([str.hash.to_s], a.uniq)
+ end
+
+ def test_hex
+ assert_equal(255, S("0xff").hex)
+ assert_equal(-255, S("-0xff").hex)
+ assert_equal(255, S("ff").hex)
+ assert_equal(-255, S("-ff").hex)
+ assert_equal(0, S("-ralph").hex)
+ assert_equal(-15, S("-fred").hex)
+ assert_equal(15, S("fred").hex)
+ end
+
+ def test_include?
+ assert( S("foobar").include?(?f))
+ assert( S("foobar").include?(S("foo")))
+ assert(!S("foobar").include?(S("baz")))
+ assert(!S("foobar").include?(?z))
+ end
+
+ def test_index
+ assert_equal(0, S("hello").index(?h))
+ assert_equal(1, S("hello").index(S("ell")))
+ assert_equal(2, S("hello").index(/ll./))
+
+ assert_equal(3, S("hello").index(?l, 3))
+ assert_equal(3, S("hello").index(S("l"), 3))
+ assert_equal(3, S("hello").index(/l./, 3))
+
+ assert_nil(S("hello").index(?z, 3))
+ assert_nil(S("hello").index(S("z"), 3))
+ assert_nil(S("hello").index(/z./, 3))
+
+ assert_nil(S("hello").index(?z))
+ assert_nil(S("hello").index(S("z")))
+ assert_nil(S("hello").index(/z./))
+
+ o = Object.new
+ def o.to_str; "bar"; end
+ assert_equal(3, "foobarbarbaz".index(o))
+ assert_raise(TypeError) { "foo".index(Object.new) }
+
+ assert_nil("foo".index(//, -100))
+ assert_nil($~)
+ end
+
+ def test_intern
+ assert_equal(:koala, S("koala").intern)
+ assert(:koala != S("Koala").intern)
+ end
+
+ def test_length
+ assert_equal(0, S("").length)
+ assert_equal(4, S("1234").length)
+ assert_equal(6, S("1234\r\n").length)
+ assert_equal(7, S("\0011234\r\n").length)
+ end
+
+ def test_ljust
+ assert_equal(S("hello"), S("hello").ljust(4))
+ assert_equal(S("hello "), S("hello").ljust(11))
+ end
+
+ def test_next
+ assert_equal(S("abd"), S("abc").next)
+ assert_equal(S("z"), S("y").next)
+ assert_equal(S("aaa"), S("zz").next)
+
+ assert_equal(S("124"), S("123").next)
+ assert_equal(S("1000"), S("999").next)
+
+ assert_equal(S("2000aaa"), S("1999zzz").next)
+ assert_equal(S("AAAAA000"), S("ZZZZ999").next)
+
+ assert_equal(S("*+"), S("**").next)
+ end
+
+ def test_next!
+ a = S("abc")
+ b = a.dup
+ assert_equal(S("abd"), a.next!)
+ assert_equal(S("abd"), a)
+ assert_equal(S("abc"), b)
+
+ a = S("y")
+ assert_equal(S("z"), a.next!)
+ assert_equal(S("z"), a)
+
+ a = S("zz")
+ assert_equal(S("aaa"), a.next!)
+ assert_equal(S("aaa"), a)
+
+ a = S("123")
+ assert_equal(S("124"), a.next!)
+ assert_equal(S("124"), a)
+
+ a = S("999")
+ assert_equal(S("1000"), a.next!)
+ assert_equal(S("1000"), a)
+
+ a = S("1999zzz")
+ assert_equal(S("2000aaa"), a.next!)
+ assert_equal(S("2000aaa"), a)
+
+ a = S("ZZZZ999")
+ assert_equal(S("AAAAA000"), a.next!)
+ assert_equal(S("AAAAA000"), a)
+
+ a = S("**")
+ assert_equal(S("*+"), a.next!)
+ assert_equal(S("*+"), a)
+ end
+
+ def test_oct
+ assert_equal(255, S("0377").oct)
+ assert_equal(255, S("377").oct)
+ assert_equal(-255, S("-0377").oct)
+ assert_equal(-255, S("-377").oct)
+ assert_equal(0, S("OO").oct)
+ assert_equal(24, S("030OO").oct)
+ end
+
+ def test_replace
+ a = S("foo")
+ assert_equal(S("f"), a.replace(S("f")))
+
+ a = S("foo")
+ assert_equal(S("foobar"), a.replace(S("foobar")))
+
+ a = S("foo")
+ a.taint
+ a.untrust
+ b = a.replace(S("xyz"))
+ assert_equal(S("xyz"), b)
+ assert(b.tainted?)
+ assert(b.untrusted?)
+
+ s = "foo" * 100
+ s2 = ("bar" * 100).dup
+ s.replace(s2)
+ assert_equal(s2, s)
+
+ s2 = ["foo"].pack("p")
+ s.replace(s2)
+ assert_equal(s2, s)
+ end
+
+ def test_reverse
+ assert_equal(S("beta"), S("ateb").reverse)
+ assert_equal(S("madamImadam"), S("madamImadam").reverse)
+
+ a=S("beta")
+ assert_equal(S("ateb"), a.reverse)
+ assert_equal(S("beta"), a)
+ end
+
+ def test_reverse!
+ a = S("beta")
+ b = a.dup
+ assert_equal(S("ateb"), a.reverse!)
+ assert_equal(S("ateb"), a)
+ assert_equal(S("beta"), b)
+
+ assert_equal(S("madamImadam"), S("madamImadam").reverse!)
+
+ a = S("madamImadam")
+ assert_equal(S("madamImadam"), a.reverse!) # ??
+ assert_equal(S("madamImadam"), a)
+ end
+
+ def test_rindex
+ assert_equal(3, S("hello").rindex(?l))
+ assert_equal(6, S("ell, hello").rindex(S("ell")))
+ assert_equal(7, S("ell, hello").rindex(/ll./))
+
+ assert_equal(3, S("hello,lo").rindex(?l, 3))
+ assert_equal(3, S("hello,lo").rindex(S("l"), 3))
+ assert_equal(3, S("hello,lo").rindex(/l./, 3))
+
+ assert_nil(S("hello").rindex(?z, 3))
+ assert_nil(S("hello").rindex(S("z"), 3))
+ assert_nil(S("hello").rindex(/z./, 3))
+
+ assert_nil(S("hello").rindex(?z))
+ assert_nil(S("hello").rindex(S("z")))
+ assert_nil(S("hello").rindex(/z./))
+
+ o = Object.new
+ def o.to_str; "bar"; end
+ assert_equal(6, "foobarbarbaz".rindex(o))
+ assert_raise(TypeError) { "foo".rindex(Object.new) }
+
+ assert_nil("foo".rindex(//, -100))
+ assert_nil($~)
+ end
+
+ def test_rjust
+ assert_equal(S("hello"), S("hello").rjust(4))
+ assert_equal(S(" hello"), S("hello").rjust(11))
+ end
+
+ def test_scan
+ a = S("cruel world")
+ assert_equal([S("cruel"), S("world")],a.scan(/\w+/))
+ assert_equal([S("cru"), S("el "), S("wor")],a.scan(/.../))
+ assert_equal([[S("cru")], [S("el ")], [S("wor")]],a.scan(/(...)/))
+
+ res = []
+ a.scan(/\w+/) { |w| res << w }
+ assert_equal([S("cruel"), S("world") ],res)
+
+ res = []
+ a.scan(/.../) { |w| res << w }
+ assert_equal([S("cru"), S("el "), S("wor")],res)
+
+ res = []
+ a.scan(/(...)/) { |w| res << w }
+ assert_equal([[S("cru")], [S("el ")], [S("wor")]],res)
+ end
+
+ def test_size
+ assert_equal(0, S("").size)
+ assert_equal(4, S("1234").size)
+ assert_equal(6, S("1234\r\n").size)
+ assert_equal(7, S("\0011234\r\n").size)
+ end
+
+ def test_slice
+ assert_equal(?A, S("AooBar").slice(0))
+ assert_equal(?B, S("FooBaB").slice(-1))
+ assert_nil(S("FooBar").slice(6))
+ assert_nil(S("FooBar").slice(-7))
+
+ assert_equal(S("Foo"), S("FooBar").slice(0,3))
+ assert_equal(S(S("Bar")), S("FooBar").slice(-3,3))
+ assert_nil(S("FooBar").slice(7,2)) # Maybe should be six?
+ assert_nil(S("FooBar").slice(-7,10))
+
+ assert_equal(S("Foo"), S("FooBar").slice(0..2))
+ assert_equal(S("Bar"), S("FooBar").slice(-3..-1))
+ assert_equal(S(""), S("FooBar").slice(6..2))
+ assert_nil(S("FooBar").slice(-10..-7))
+
+ assert_equal(S("Foo"), S("FooBar").slice(/^F../))
+ assert_equal(S("Bar"), S("FooBar").slice(/..r$/))
+ assert_nil(S("FooBar").slice(/xyzzy/))
+ assert_nil(S("FooBar").slice(/plugh/))
+
+ assert_equal(S("Foo"), S("FooBar").slice(S("Foo")))
+ assert_equal(S("Bar"), S("FooBar").slice(S("Bar")))
+ assert_nil(S("FooBar").slice(S("xyzzy")))
+ assert_nil(S("FooBar").slice(S("plugh")))
+ end
+
+ def test_slice!
+ a = S("AooBar")
+ b = a.dup
+ assert_equal(?A, a.slice!(0))
+ assert_equal(S("ooBar"), a)
+ assert_equal(S("AooBar"), b)
+
+ a = S("FooBar")
+ assert_equal(?r,a.slice!(-1))
+ assert_equal(S("FooBa"), a)
+
+ a = S("FooBar")
+ if @aref_slicebang_silent
+ assert_nil( a.slice!(6) )
+ else
+ assert_raise(IndexError) { a.slice!(6) }
+ end
+ assert_equal(S("FooBar"), a)
+
+ if @aref_slicebang_silent
+ assert_nil( a.slice!(-7) )
+ else
+ assert_raise(IndexError) { a.slice!(-7) }
+ end
+ assert_equal(S("FooBar"), a)
+
+ a = S("FooBar")
+ assert_equal(S("Foo"), a.slice!(0,3))
+ assert_equal(S("Bar"), a)
+
+ a = S("FooBar")
+ assert_equal(S("Bar"), a.slice!(-3,3))
+ assert_equal(S("Foo"), a)
+
+ a=S("FooBar")
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(7,2)) # Maybe should be six?
+ else
+ assert_raise(IndexError) {a.slice!(7,2)} # Maybe should be six?
+ end
+ assert_equal(S("FooBar"), a)
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(-7,10))
+ else
+ assert_raise(IndexError) {a.slice!(-7,10)}
+ end
+ assert_equal(S("FooBar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Foo"), a.slice!(0..2))
+ assert_equal(S("Bar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Bar"), a.slice!(-3..-1))
+ assert_equal(S("Foo"), a)
+
+ a=S("FooBar")
+ if @aref_slicebang_silent
+ assert_equal(S(""), a.slice!(6..2))
+ else
+ assert_raise(RangeError) {a.slice!(6..2)}
+ end
+ assert_equal(S("FooBar"), a)
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(-10..-7))
+ else
+ assert_raise(RangeError) {a.slice!(-10..-7)}
+ end
+ assert_equal(S("FooBar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Foo"), a.slice!(/^F../))
+ assert_equal(S("Bar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Bar"), a.slice!(/..r$/))
+ assert_equal(S("Foo"), a)
+
+ a=S("FooBar")
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(/xyzzy/))
+ else
+ assert_raise(IndexError) {a.slice!(/xyzzy/)}
+ end
+ assert_equal(S("FooBar"), a)
+ if @aref_slicebang_silent
+ assert_nil(a.slice!(/plugh/))
+ else
+ assert_raise(IndexError) {a.slice!(/plugh/)}
+ end
+ assert_equal(S("FooBar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Foo"), a.slice!(S("Foo")))
+ assert_equal(S("Bar"), a)
+
+ a=S("FooBar")
+ assert_equal(S("Bar"), a.slice!(S("Bar")))
+ assert_equal(S("Foo"), a)
+
+ pre_1_7_1 do
+ a=S("FooBar")
+ assert_nil(a.slice!(S("xyzzy")))
+ assert_equal(S("FooBar"), a)
+ assert_nil(a.slice!(S("plugh")))
+ assert_equal(S("FooBar"), a)
+ end
+
+ assert_raise(ArgumentError) { "foo".slice! }
+ end
+
+ def test_split
+ assert_nil($;)
+ assert_equal([S("a"), S("b"), S("c")], S(" a b\t c ").split)
+ assert_equal([S("a"), S("b"), S("c")], S(" a b\t c ").split(S(" ")))
+
+ assert_equal([S(" a "), S(" b "), S(" c ")], S(" a | b | c ").split(S("|")))
+
+ assert_equal([S("a"), S("b"), S("c")], S("aXXbXXcXX").split(/X./))
+
+ assert_equal([S("a"), S("b"), S("c")], S("abc").split(//))
+
+ assert_equal([S("a|b|c")], S("a|b|c").split(S('|'), 1))
+
+ assert_equal([S("a"), S("b|c")], S("a|b|c").split(S('|'), 2))
+ assert_equal([S("a"), S("b"), S("c")], S("a|b|c").split(S('|'), 3))
+
+ assert_equal([S("a"), S("b"), S("c"), S("")], S("a|b|c|").split(S('|'), -1))
+ assert_equal([S("a"), S("b"), S("c"), S(""), S("")], S("a|b|c||").split(S('|'), -1))
+
+ assert_equal([S("a"), S(""), S("b"), S("c")], S("a||b|c|").split(S('|')))
+ assert_equal([S("a"), S(""), S("b"), S("c"), S("")], S("a||b|c|").split(S('|'), -1))
+
+ assert_equal([], "".split(//, 1))
+
+ assert_equal("[2, 3]", [1,2,3].slice!(1,10000).inspect, "moved from btest/knownbug")
+
+ end
+
+ def test_squeeze
+ assert_equal(S("abc"), S("aaabbbbccc").squeeze)
+ assert_equal(S("aa bb cc"), S("aa bb cc").squeeze(S(" ")))
+ assert_equal(S("BxTyWz"), S("BxxxTyyyWzzzzz").squeeze(S("a-z")))
+ end
+
+ def test_squeeze!
+ a = S("aaabbbbccc")
+ b = a.dup
+ assert_equal(S("abc"), a.squeeze!)
+ assert_equal(S("abc"), a)
+ assert_equal(S("aaabbbbccc"), b)
+
+ a = S("aa bb cc")
+ assert_equal(S("aa bb cc"), a.squeeze!(S(" ")))
+ assert_equal(S("aa bb cc"), a)
+
+ a = S("BxxxTyyyWzzzzz")
+ assert_equal(S("BxTyWz"), a.squeeze!(S("a-z")))
+ assert_equal(S("BxTyWz"), a)
+
+ a=S("The quick brown fox")
+ assert_nil(a.squeeze!)
+ end
+
+ def test_strip
+ assert_equal(S("x"), S(" x ").strip)
+ assert_equal(S("x"), S(" \n\r\t x \t\r\n\n ").strip)
+ end
+
+ def test_strip!
+ a = S(" x ")
+ b = a.dup
+ assert_equal(S("x") ,a.strip!)
+ assert_equal(S("x") ,a)
+ assert_equal(S(" x "), b)
+
+ a = S(" \n\r\t x \t\r\n\n ")
+ assert_equal(S("x"), a.strip!)
+ assert_equal(S("x"), a)
+
+ a = S("x")
+ assert_nil(a.strip!)
+ assert_equal(S("x") ,a)
+ end
+
+ def test_sub
+ assert_equal(S("h*llo"), S("hello").sub(/[aeiou]/, S('*')))
+ assert_equal(S("h<e>llo"), S("hello").sub(/([aeiou])/, S('<\1>')))
+ assert_equal(S("h ello"), S("hello").sub(/./) {
+ |s| s[0].to_s + S(' ')})
+ assert_equal(S("HELL-o"), S("hello").sub(/(hell)(.)/) {
+ |s| $1.upcase + S('-') + $2
+ })
+
+ assert_equal(S("a\\aba"), S("ababa").sub(/b/, '\\'))
+ assert_equal(S("ab\\aba"), S("ababa").sub(/(b)/, '\1\\'))
+ assert_equal(S("ababa"), S("ababa").sub(/(b)/, '\1'))
+ assert_equal(S("ababa"), S("ababa").sub(/(b)/, '\\1'))
+ assert_equal(S("a\\1aba"), S("ababa").sub(/(b)/, '\\\1'))
+ assert_equal(S("a\\1aba"), S("ababa").sub(/(b)/, '\\\\1'))
+ assert_equal(S("a\\baba"), S("ababa").sub(/(b)/, '\\\\\1'))
+
+ assert_equal(S("a--ababababababababab"),
+ S("abababababababababab").sub(/(b)/, '-\9-'))
+ assert_equal(S("1-b-0"),
+ S("1b2b3b4b5b6b7b8b9b0").
+ sub(/(b).(b).(b).(b).(b).(b).(b).(b).(b)/, '-\9-'))
+ assert_equal(S("1-b-0"),
+ S("1b2b3b4b5b6b7b8b9b0").
+ sub(/(b).(b).(b).(b).(b).(b).(b).(b).(b)/, '-\\9-'))
+ assert_equal(S("1-\\9-0"),
+ S("1b2b3b4b5b6b7b8b9b0").
+ sub(/(b).(b).(b).(b).(b).(b).(b).(b).(b)/, '-\\\9-'))
+ assert_equal(S("k"),
+ S("1a2b3c4d5e6f7g8h9iAjBk").
+ sub(/.(.).(.).(.).(.).(.).(.).(.).(.).(.).(.).(.)/, '\+'))
+
+ assert_equal(S("ab\\aba"), S("ababa").sub(/b/, '\&\\'))
+ assert_equal(S("ababa"), S("ababa").sub(/b/, '\&'))
+ assert_equal(S("ababa"), S("ababa").sub(/b/, '\\&'))
+ assert_equal(S("a\\&aba"), S("ababa").sub(/b/, '\\\&'))
+ assert_equal(S("a\\&aba"), S("ababa").sub(/b/, '\\\\&'))
+ assert_equal(S("a\\baba"), S("ababa").sub(/b/, '\\\\\&'))
+
+ a = S("hello")
+ a.taint
+ a.untrust
+ x = a.sub(/./, S('X'))
+ assert(x.tainted?)
+ assert(x.untrusted?)
+
+ o = Object.new
+ def o.to_str; "bar"; end
+ assert_equal("fooBARbaz", "foobarbaz".sub(o, "BAR"))
+
+ assert_raise(TypeError) { "foo".sub(Object.new, "") }
+
+ assert_raise(ArgumentError) { "foo".sub }
+
+ assert_raise(IndexError) { "foo"[/(?:(o$)|(x))/, 2] = 'bar' }
+
+ o = Object.new
+ def o.to_s; self; end
+ assert_match(/^foo#<Object:0x.*>baz$/, "foobarbaz".sub("bar") { o })
+ end
+
+ def test_sub!
+ a = S("hello")
+ b = a.dup
+ a.sub!(/[aeiou]/, S('*'))
+ assert_equal(S("h*llo"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("hello")
+ a.sub!(/([aeiou])/, S('<\1>'))
+ assert_equal(S("h<e>llo"), a)
+
+ a = S("hello")
+ a.sub!(/./) { |s| s[0].to_s + S(' ')}
+ assert_equal(S("h ello"), a)
+
+ a = S("hello")
+ a.sub!(/(hell)(.)/) { |s| $1.upcase + S('-') + $2 }
+ assert_equal(S("HELL-o"), a)
+
+ a=S("hello")
+ assert_nil(a.sub!(/X/, S('Y')))
+
+ r = S('X')
+ r.taint
+ r.untrust
+ a.sub!(/./, r)
+ assert(a.tainted?)
+ assert(a.untrusted?)
+ end
+
+ def test_succ
+ assert_equal(S("abd"), S("abc").succ)
+ assert_equal(S("z"), S("y").succ)
+ assert_equal(S("aaa"), S("zz").succ)
+
+ assert_equal(S("124"), S("123").succ)
+ assert_equal(S("1000"), S("999").succ)
+ assert_equal(S("2.000"), S("1.999").succ)
+
+ assert_equal(S("No.10"), S("No.9").succ)
+ assert_equal(S("2000aaa"), S("1999zzz").succ)
+ assert_equal(S("AAAAA000"), S("ZZZZ999").succ)
+ assert_equal(S("*+"), S("**").succ)
+
+ assert_equal("abce", "abcd".succ)
+ assert_equal("THX1139", "THX1138".succ)
+ assert_equal("<<koalb>>", "<<koala>>".succ)
+ assert_equal("2000aaa", "1999zzz".succ)
+ assert_equal("AAAA0000", "ZZZ9999".succ)
+ assert_equal("**+", "***".succ)
+ end
+
+ def test_succ!
+ a = S("abc")
+ b = a.dup
+ assert_equal(S("abd"), a.succ!)
+ assert_equal(S("abd"), a)
+ assert_equal(S("abc"), b)
+
+ a = S("y")
+ assert_equal(S("z"), a.succ!)
+ assert_equal(S("z"), a)
+
+ a = S("zz")
+ assert_equal(S("aaa"), a.succ!)
+ assert_equal(S("aaa"), a)
+
+ a = S("123")
+ assert_equal(S("124"), a.succ!)
+ assert_equal(S("124"), a)
+
+ a = S("999")
+ assert_equal(S("1000"), a.succ!)
+ assert_equal(S("1000"), a)
+
+ a = S("1999zzz")
+ assert_equal(S("2000aaa"), a.succ!)
+ assert_equal(S("2000aaa"), a)
+
+ a = S("ZZZZ999")
+ assert_equal(S("AAAAA000"), a.succ!)
+ assert_equal(S("AAAAA000"), a)
+
+ a = S("**")
+ assert_equal(S("*+"), a.succ!)
+ assert_equal(S("*+"), a)
+
+ a = S("No.9")
+ assert_equal(S("No.10"), a.succ!)
+ assert_equal(S("No.10"), a)
+
+ assert_equal("aaaaaaaaaaaa", "zzzzzzzzzzz".succ!)
+ assert_equal("aaaaaaaaaaaaaaaaaaaaaaaa", "zzzzzzzzzzzzzzzzzzzzzzz".succ!)
+ end
+
+ def test_sum
+ n = S("\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001")
+ assert_equal(15, n.sum)
+ n += S("\001")
+ assert_equal(16, n.sum(17))
+ n[0] = 2.chr
+ assert(15 != n.sum)
+ end
+
+ def check_sum(str, bits=16)
+ sum = 0
+ str.each_byte {|c| sum += c}
+ sum = sum & ((1 << bits) - 1) if bits != 0
+ assert_equal(sum, str.sum(bits))
+ end
+
+ def test_sum_2
+ assert_equal(0, "".sum)
+ assert_equal(294, "abc".sum)
+ check_sum("abc")
+ check_sum("\x80")
+ 0.upto(70) {|bits|
+ check_sum("xyz", bits)
+ }
+ end
+
+ def test_swapcase
+ assert_equal(S("hi&LOW"), S("HI&low").swapcase)
+ end
+
+ def test_swapcase!
+ a = S("hi&LOW")
+ b = a.dup
+ assert_equal(S("HI&low"), a.swapcase!)
+ assert_equal(S("HI&low"), a)
+ assert_equal(S("hi&LOW"), b)
+
+ a = S("$^#^%$#!!")
+ assert_nil(a.swapcase!)
+ assert_equal(S("$^#^%$#!!"), a)
+ end
+
+ def test_to_f
+ assert_equal(344.3, S("344.3").to_f)
+ assert_equal(5.9742e24, S("5.9742e24").to_f)
+ assert_equal(98.6, S("98.6 degrees").to_f)
+ assert_equal(0.0, S("degrees 100.0").to_f)
+ end
+
+ def test_to_i
+ assert_equal(1480, S("1480ft/sec").to_i)
+ assert_equal(0, S("speed of sound in water @20C = 1480ft/sec)").to_i)
+ assert_equal(0, " 0".to_i)
+ assert_equal(0, "+0".to_i)
+ assert_equal(0, "-0".to_i)
+ assert_equal(0, "--0".to_i)
+ assert_equal(16, "0x10".to_i(0))
+ assert_equal(16, "0X10".to_i(0))
+ assert_equal(2, "0b10".to_i(0))
+ assert_equal(2, "0B10".to_i(0))
+ assert_equal(8, "0o10".to_i(0))
+ assert_equal(8, "0O10".to_i(0))
+ assert_equal(10, "0d10".to_i(0))
+ assert_equal(10, "0D10".to_i(0))
+ assert_equal(8, "010".to_i(0))
+ assert_raise(ArgumentError) { "010".to_i(-10) }
+ 2.upto(36) {|radix|
+ assert_equal(radix, "10".to_i(radix))
+ assert_equal(radix**2, "100".to_i(radix))
+ }
+ assert_raise(ArgumentError) { "0".to_i(1) }
+ assert_raise(ArgumentError) { "0".to_i(37) }
+ assert_equal(0, "z".to_i(10))
+ assert_equal(12, "1_2".to_i(10))
+ assert_equal(0x40000000, "1073741824".to_i(10))
+ assert_equal(0x4000000000000000, "4611686018427387904".to_i(10))
+ assert_equal(1, "1__2".to_i(10))
+ assert_equal(1, "1_z".to_i(10))
+ end
+
+ def test_to_s
+ a = S("me")
+ assert_equal("me", a.to_s)
+ assert_equal(a.__id__, a.to_s.__id__) if @cls == String
+ end
+
+ def test_to_str
+ a = S("me")
+ assert_equal("me", a.to_s)
+ assert_equal(a.__id__, a.to_s.__id__) if @cls == String
+ end
+
+ def test_tr
+ assert_equal(S("hippo"), S("hello").tr(S("el"), S("ip")))
+ assert_equal(S("*e**o"), S("hello").tr(S("^aeiou"), S("*")))
+ assert_equal(S("hal"), S("ibm").tr(S("b-z"), S("a-z")))
+ end
+
+ def test_tr!
+ a = S("hello")
+ b = a.dup
+ assert_equal(S("hippo"), a.tr!(S("el"), S("ip")))
+ assert_equal(S("hippo"), a)
+ assert_equal(S("hello"),b)
+
+ a = S("hello")
+ assert_equal(S("*e**o"), a.tr!(S("^aeiou"), S("*")))
+ assert_equal(S("*e**o"), a)
+
+ a = S("IBM")
+ assert_equal(S("HAL"), a.tr!(S("B-Z"), S("A-Z")))
+ assert_equal(S("HAL"), a)
+
+ a = S("ibm")
+ assert_nil(a.tr!(S("B-Z"), S("A-Z")))
+ assert_equal(S("ibm"), a)
+ end
+
+ def test_tr_s
+ assert_equal(S("hypo"), S("hello").tr_s(S("el"), S("yp")))
+ assert_equal(S("h*o"), S("hello").tr_s(S("el"), S("*")))
+ end
+
+ def test_tr_s!
+ a = S("hello")
+ b = a.dup
+ assert_equal(S("hypo"), a.tr_s!(S("el"), S("yp")))
+ assert_equal(S("hypo"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("hello")
+ assert_equal(S("h*o"), a.tr_s!(S("el"), S("*")))
+ assert_equal(S("h*o"), a)
+ end
+
+ def test_unpack
+ a = [S("cat"), S("wom"), S("x"), S("yy")]
+ assert_equal(a, S("catwomx yy ").unpack(S("A3A3A3A3")))
+
+ assert_equal([S("cat")], S("cat \000\000").unpack(S("A*")))
+ assert_equal([S("cwx"), S("wx"), S("x"), S("yy")],
+ S("cwx yy ").unpack(S("A3@1A3@2A3A3")))
+ assert_equal([S("cat"), S("wom"), S("x\000\000"), S("yy\000")],
+ S("catwomx\000\000yy\000").unpack(S("a3a3a3a3")))
+ assert_equal([S("cat \000\000")], S("cat \000\000").unpack(S("a*")))
+ assert_equal([S("ca")], S("catdog").unpack(S("a2")))
+
+ assert_equal([S("cat\000\000")],
+ S("cat\000\000\000\000\000dog").unpack(S("a5")))
+
+ assert_equal([S("01100001")], S("\x61").unpack(S("B8")))
+ assert_equal([S("01100001")], S("\x61").unpack(S("B*")))
+ assert_equal([S("0110000100110111")], S("\x61\x37").unpack(S("B16")))
+ assert_equal([S("01100001"), S("00110111")], S("\x61\x37").unpack(S("B8B8")))
+ assert_equal([S("0110")], S("\x60").unpack(S("B4")))
+
+ assert_equal([S("01")], S("\x40").unpack(S("B2")))
+
+ assert_equal([S("01100001")], S("\x86").unpack(S("b8")))
+ assert_equal([S("01100001")], S("\x86").unpack(S("b*")))
+
+ assert_equal([S("0110000100110111")], S("\x86\xec").unpack(S("b16")))
+ assert_equal([S("01100001"), S("00110111")], S("\x86\xec").unpack(S("b8b8")))
+
+ assert_equal([S("0110")], S("\x06").unpack(S("b4")))
+ assert_equal([S("01")], S("\x02").unpack(S("b2")))
+
+ assert_equal([ 65, 66, 67 ], S("ABC").unpack(S("C3")))
+ assert_equal([ 255, 66, 67 ], S("\377BC").unpack("C*"))
+ assert_equal([ 65, 66, 67 ], S("ABC").unpack("c3"))
+ assert_equal([ -1, 66, 67 ], S("\377BC").unpack("c*"))
+
+
+ assert_equal([S("4142"), S("0a"), S("1")], S("AB\n\x10").unpack(S("H4H2H1")))
+ assert_equal([S("1424"), S("a0"), S("2")], S("AB\n\x02").unpack(S("h4h2h1")))
+
+ assert_equal([S("abc\002defcat\001"), S(""), S("")],
+ S("abc=02def=\ncat=\n=01=\n").unpack(S("M9M3M4")))
+
+ assert_equal([S("hello\n")], S("aGVsbG8K\n").unpack(S("m")))
+
+ assert_equal([S("hello\nhello\n")], S(",:&5L;&\\*:&5L;&\\*\n").unpack(S("u")))
+
+ assert_equal([0xa9, 0x42, 0x2260], S("\xc2\xa9B\xe2\x89\xa0").unpack(S("U*")))
+
+=begin
+ skipping "Not tested:
+ D,d & double-precision float, native format\\
+ E & double-precision float, little-endian byte order\\
+ e & single-precision float, little-endian byte order\\
+ F,f & single-precision float, native format\\
+ G & double-precision float, network (big-endian) byte order\\
+ g & single-precision float, network (big-endian) byte order\\
+ I & unsigned integer\\
+ i & integer\\
+ L & unsigned long\\
+ l & long\\
+
+ m & string encoded in base64 (uuencoded)\\
+ N & long, network (big-endian) byte order\\
+ n & short, network (big-endian) byte-order\\
+ P & pointer to a structure (fixed-length string)\\
+ p & pointer to a null-terminated string\\
+ S & unsigned short\\
+ s & short\\
+ V & long, little-endian byte order\\
+ v & short, little-endian byte order\\
+ X & back up a byte\\
+ x & null byte\\
+ Z & ASCII string (null padded, count is width)\\
+"
+=end
+ end
+
+ def test_upcase
+ assert_equal(S("HELLO"), S("hello").upcase)
+ assert_equal(S("HELLO"), S("hello").upcase)
+ assert_equal(S("HELLO"), S("HELLO").upcase)
+ assert_equal(S("ABC HELLO 123"), S("abc HELLO 123").upcase)
+ end
+
+ def test_upcase!
+ a = S("hello")
+ b = a.dup
+ assert_equal(S("HELLO"), a.upcase!)
+ assert_equal(S("HELLO"), a)
+ assert_equal(S("hello"), b)
+
+ a = S("HELLO")
+ assert_nil(a.upcase!)
+ assert_equal(S("HELLO"), a)
+ end
+
+ def test_upto
+ a = S("aa")
+ start = S("aa")
+ count = 0
+ assert_equal(S("aa"), a.upto(S("zz")) {|s|
+ assert_equal(start, s)
+ start.succ!
+ count += 1
+ })
+ assert_equal(676, count)
+ end
+
+ def test_mod_check
+ assert_raise(RuntimeError) {
+ s = ""
+ s.sub!(/\A/) { s.replace "z" * 2000; "zzz" }
+ }
+ end
+
+ def test_frozen_check
+ assert_raise(RuntimeError) {
+ s = ""
+ s.sub!(/\A/) { s.freeze; "zzz" }
+ }
+ end
+
+ def test_tainted_str_new
+ a = []
+ a << a
+ s = a.inspect
+ assert(s.tainted?)
+ assert_equal("[[...]]", s)
+ end
+
+ class S2 < String
+ end
+ def test_str_new4
+ s = (0..54).to_a.join # length = 100
+ s2 = S2.new(s[10,90])
+ s3 = s2[10,80]
+ assert_equal((10..54).to_a.to_a.join, s2)
+ assert_equal((15..54).to_a.to_a.join, s3)
+ end
+
+ def test_rb_str_new4
+ s = "a" * 100
+ s2 = s[10,90]
+ assert_equal("a" * 90, s2)
+ s3 = s2[10,80]
+ assert_equal("a" * 80, s3)
+ end
+
+ class StringLike
+ def initialize(str)
+ @str = str
+ end
+
+ def to_str
+ @str
+ end
+ end
+
+ def test_rb_str_to_str
+ assert_equal("ab", "a" + StringLike.new("b"))
+ end
+
+ def test_rb_str_shared_replace
+ s = "a" * 100
+ s.succ!
+ assert_equal("a" * 99 + "b", s)
+ s = ""
+ s.succ!
+ assert_equal("", s)
+ end
+
+ def test_times
+ assert_raise(ArgumentError) { "a" * (-1) }
+ end
+
+ def test_splice!
+ l = S("1234\n234\n34\n4\n")
+ assert_equal(S("1234\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ assert_equal(S("234\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ assert_equal(S("34\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ assert_equal(S("4\n"), l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ assert_nil(l.slice!(/\A.*\n/), "[ruby-dev:31665]")
+ end
+
+ def test_end_with?
+ assert("abc".end_with?("c"))
+ end
+
+ def test_times2
+ s1 = ''
+ 100.times {|n|
+ s2 = "a" * n
+ assert_equal(s1, s2)
+ s1 << 'a'
+ }
+
+ assert_raise(ArgumentError) { "foo" * (-1) }
+ end
+
+ def test_respond_to
+ o = Object.new
+ def o.respond_to?(arg) [:to_str].include?(arg) ? nil : super end
+ def o.to_str() "" end
+ def o.==(other) "" == other end
+ assert_equal(false, "" == o)
+ end
+
+ def test_match_method
+ assert_equal("bar", "foobarbaz".match(/bar/).to_s)
+
+ o = /foo/
+ def o.match(x, y, z); x + y + z; end
+ assert_equal("foobarbaz", "foo".match(o, "bar", "baz"))
+ x = nil
+ "foo".match(o, "bar", "baz") {|y| x = y }
+ assert_equal("foobarbaz", x)
+
+ assert_raise(ArgumentError) { "foo".match }
+ end
+
+ def test_clear
+ s = "foo" * 100
+ s.clear
+ assert_equal("", s)
+ end
+
+ def test_to_s_2
+ c = Class.new(String)
+ s = c.new
+ s.replace("foo")
+ assert_equal("foo", s.to_s)
+ assert_instance_of(String, s.to_s)
+ end
+
+ def test_partition
+ assert_equal(%w(he l lo), "hello".partition(/l/))
+ assert_equal(%w(he l lo), "hello".partition("l"))
+ assert_raise(TypeError) { "hello".partition(1) }
+ end
+
+ def test_rpartition
+ assert_equal(%w(hel l o), "hello".rpartition(/l/))
+ assert_equal(%w(hel l o), "hello".rpartition("l"))
+ assert_raise(TypeError) { "hello".rpartition(1) }
+ end
+
+ def test_setter
+ assert_raise(TypeError) { $/ = 1 }
+ end
+
+ def test_to_id
+ c = Class.new
+ c.class_eval do
+ def initialize
+ @foo = :foo
+ end
+ end
+
+ assert_raise(TypeError) do
+ c.class_eval { attr 1 }
+ end
+
+ o = Object.new
+ def o.to_str; :foo; end
+ assert_raise(TypeError) do
+ c.class_eval { attr 1 }
+ end
+
+ def o.to_str; "foo"; end
+ assert_nothing_raised do
+ c.class_eval { attr o }
+ end
+ assert_equal(:foo, c.new.foo)
+ end
+
+ def test_gsub_enumerator
+ assert_normal_exit %q{"abc".gsub(/./).next}, "[ruby-dev:34828]"
+ end
+end
diff --git a/trunk/test/ruby/test_stringchar.rb b/trunk/test/ruby/test_stringchar.rb
new file mode 100644
index 0000000000..184e221211
--- /dev/null
+++ b/trunk/test/ruby/test_stringchar.rb
@@ -0,0 +1,166 @@
+require 'test/unit'
+
+class TestStringchar < Test::Unit::TestCase
+ def test_string
+ assert_equal("abcd", "abcd")
+ assert_match(/abcd/, "abcd")
+ assert("abcd" === "abcd")
+ # compile time string concatenation
+ assert_equal("abcd", "ab" "cd")
+ assert_equal("22aacd44", "#{22}aa" "cd#{44}")
+ assert_equal("22aacd445566", "#{22}aa" "cd#{44}" "55" "#{66}")
+ assert("abc" !~ /^$/)
+ assert("abc\n" !~ /^$/)
+ assert("abc" !~ /^d*$/)
+ assert_equal(3, ("abc" =~ /d*$/))
+ assert("" =~ /^$/)
+ assert("\n" =~ /^$/)
+ assert("a\n\n" =~ /^$/)
+ assert("abcabc" =~ /.*a/); assert_equal("abca", $&)
+ assert("abcabc" =~ /.*c/); assert_equal("abcabc", $&)
+ assert("abcabc" =~ /.*?a/); assert_equal("a", $&)
+ assert("abcabc" =~ /.*?c/); assert_equal("abc", $&)
+ assert(/(.|\n)*?\n(b|\n)/ =~ "a\nb\n\n"); assert_equal("a\nb", $&)
+
+ assert(/^(ab+)+b/ =~ "ababb"); assert_equal("ababb", $&)
+ assert(/^(?:ab+)+b/ =~ "ababb"); assert_equal("ababb", $&)
+ assert(/^(ab+)+/ =~ "ababb"); assert_equal("ababb", $&)
+ assert(/^(?:ab+)+/ =~ "ababb"); assert_equal("ababb", $&)
+
+ assert(/(\s+\d+){2}/ =~ " 1 2"); assert_equal(" 1 2", $&)
+ assert(/(?:\s+\d+){2}/ =~ " 1 2"); assert_equal(" 1 2", $&)
+
+ $x = <<END;
+ABCD
+ABCD
+END
+ $x.gsub!(/((.|\n)*?)B((.|\n)*?)D/m ,'\1\3')
+ assert_equal("AC\nAC\n", $x)
+
+ assert("foobar" =~ /foo(?=(bar)|(baz))/)
+ assert("foobaz" =~ /foo(?=(bar)|(baz))/)
+
+ $foo = "abc"
+ assert_equal("abc = abc", "#$foo = abc")
+ assert_equal("abc = abc", "#{$foo} = abc")
+
+ foo = "abc"
+ assert_equal("abc = abc", "#{foo} = abc")
+
+ assert_equal('-----', '-' * 5)
+ assert_equal('-', '-' * 1)
+ assert_equal('', '-' * 0)
+
+ foo = '-'
+ assert_equal('-----', foo * 5)
+ assert_equal('-', foo * 1)
+ assert_equal('', foo * 0)
+
+ $x = "a.gif"
+ assert_equal("gif", $x.sub(/.*\.([^\.]+)$/, '\1'))
+ assert_equal("b.gif", $x.sub(/.*\.([^\.]+)$/, 'b.\1'))
+ assert_equal("", $x.sub(/.*\.([^\.]+)$/, '\2'))
+ assert_equal("ab", $x.sub(/.*\.([^\.]+)$/, 'a\2b'))
+ assert_equal("<a.gif>", $x.sub(/.*\.([^\.]+)$/, '<\&>'))
+ end
+
+ def test_char
+ # character constants(assumes ASCII)
+ assert_equal(?a, "a"[0])
+ assert_equal(?a, ?a)
+ assert_equal("\1", ?\C-a)
+ assert_equal("\341", ?\M-a)
+ assert_equal("\201", ?\M-\C-a)
+ assert_equal(?A, "a".upcase![0])
+ assert_equal(?a, "A".downcase![0])
+ assert_equal("ABC", "abc".tr!("a-z", "A-Z"))
+ assert_equal("ABC", "aabbcccc".tr_s!("a-z", "A-Z"))
+ assert_equal("abc", "abcc".squeeze!("a-z"))
+ assert_equal("ad", "abcd".delete!("bc"))
+
+ $x = "abcdef"
+ $y = [ ?a, ?b, ?c, ?d, ?e, ?f ]
+ $bad = false
+ $x.each_byte {|i|
+ if i.chr != $y.shift
+ $bad = true
+ break
+ end
+ }
+ assert(!$bad)
+
+ s = "a string"
+ s[0..s.size]="another string"
+ assert_equal("another string", s)
+
+ s = <<EOS
+#{
+[1,2,3].join(",")
+}
+EOS
+ assert_equal("1,2,3\n", s)
+ assert_equal(926381, "Just".to_i(36))
+ assert_equal(-23200231779, "-another".to_i(36))
+ assert_equal("ruby", 1299022.to_s(36))
+ assert_equal("-hacker", -1045307475.to_s(36))
+ assert_equal(265419172580680477752431643787347, "Just_another_Ruby_hacker".to_i(36))
+ assert_equal("-justanotherrubyhacker", -265419172580680477752431643787347.to_s(36))
+
+ a = []
+ (0..255).each {|n|
+ ch = [n].pack("C")
+ a.push ch if /a#{Regexp.quote ch}b/x =~ "ab"
+ }
+ assert_equal(0, a.size)
+ end
+
+ def test_bang
+ s = "aBc"
+ s.upcase
+ assert_equal("aBc", s)
+ s.upcase!
+ assert_equal("ABC", s)
+
+ s = "aBc"
+ s.downcase
+ assert_equal("aBc", s)
+ s.downcase!
+ assert_equal("abc", s)
+
+ s = "aBc"
+ s.swapcase
+ assert_equal("aBc", s)
+ s.swapcase!
+ assert_equal("AbC", s)
+
+ s = "aBc"
+ s.capitalize
+ assert_equal("aBc", s)
+ s.capitalize!
+ assert_equal("Abc", s)
+
+ s = "aBc"
+ s.tr("a-z", "A-Z")
+ assert_equal("aBc", s)
+ s.tr!("a-z", "A-Z")
+ assert_equal("ABC", s)
+
+ s = "aaBBcc"
+ s.tr_s("a-z", "A-Z")
+ assert_equal("aaBBcc", s)
+ s.tr_s!("a-z", "A-Z")
+ assert_equal("ABBC", s)
+
+ s = "aaBBcc"
+ s.squeeze("a-z")
+ assert_equal("aaBBcc", s)
+ s.squeeze!("a-z")
+ assert_equal("aBBc", s)
+
+ s = "aaBBcc"
+ s.delete("a-z")
+ assert_equal("aaBBcc", s)
+ s.delete!("a-z")
+ assert_equal("BB", s)
+ end
+end
diff --git a/trunk/test/ruby/test_struct.rb b/trunk/test/ruby/test_struct.rb
new file mode 100644
index 0000000000..6c0e1f4fb2
--- /dev/null
+++ b/trunk/test/ruby/test_struct.rb
@@ -0,0 +1,215 @@
+require 'test/unit'
+
+class TestStruct < Test::Unit::TestCase
+ def test_struct
+ struct_test = Struct.new("Test", :foo, :bar)
+ assert_equal(Struct::Test, struct_test)
+
+ test = struct_test.new(1, 2)
+ assert_equal(1, test.foo)
+ assert_equal(2, test.bar)
+ assert_equal(1, test[0])
+ assert_equal(2, test[1])
+
+ a, b = test.to_a
+ assert_equal(1, a)
+ assert_equal(2, b)
+
+ test[0] = 22
+ assert_equal(22, test.foo)
+
+ test.bar = 47
+ assert_equal(47, test.bar)
+ end
+
+ # [ruby-dev:26247] more than 10 struct members causes segmentation fault
+ def test_morethan10members
+ list = %w( a b c d e f g h i j k l m n o p )
+ until list.empty?
+ c = Struct.new(* list.map {|ch| ch.intern }).new
+ list.each do |ch|
+ c.__send__(ch)
+ end
+ list.pop
+ end
+ end
+
+ def test_small_structs
+ names = [:a, :b, :c, :d]
+ 1.upto(4) {|n|
+ fields = names[0, n]
+ klass = Struct.new(*fields)
+ o = klass.new(*(0...n).to_a)
+ fields.each_with_index {|name, i|
+ assert_equal(i, o[name])
+ }
+ o = klass.new(*(0...n).to_a.reverse)
+ fields.each_with_index {|name, i|
+ assert_equal(n-i-1, o[name])
+ }
+ }
+ end
+
+ def test_inherit
+ klass = Struct.new(:a)
+ klass2 = Class.new(klass)
+ o = klass2.new(1)
+ assert_equal(1, o.a)
+ end
+
+ def test_members
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal([:a], klass.members)
+ assert_equal([:a], o.members)
+ end
+
+ def test_ref
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal(1, o[:a])
+ assert_raise(NameError) { o[:b] }
+ end
+
+ def test_modify
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_raise(SecurityError) do
+ Thread.new do
+ $SAFE = 4
+ o.a = 2
+ end.value
+ end
+ end
+
+ def test_set
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ o[:a] = 2
+ assert_equal(2, o[:a])
+ assert_raise(NameError) { o[:b] = 3 }
+ end
+
+ def test_struct_new
+ assert_raise(NameError) { Struct.new("foo") }
+ assert_nothing_raised { Struct.new("Foo") }
+ Struct.instance_eval { remove_const(:Foo) }
+ assert_nothing_raised { Struct.new(:a) { } }
+ assert_raise(RuntimeError) { Struct.new(:a) { raise } }
+
+ assert_equal([:utime, :stime, :cutime, :cstime], Process.times.members)
+ end
+
+ def test_initialize
+ klass = Struct.new(:a)
+ assert_raise(ArgumentError) { klass.new(1, 2) }
+ end
+
+ def test_each
+ klass = Struct.new(:a, :b)
+ o = klass.new(1, 2)
+ assert_equal([1, 2], o.each.to_a)
+ end
+
+ def test_each_pair
+ klass = Struct.new(:a, :b)
+ o = klass.new(1, 2)
+ assert_equal([[:a, 1], [:b, 2]], o.each_pair.to_a)
+ end
+
+ def test_inspect
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal("#<struct a=1>", o.inspect)
+ o.a = o
+ assert(o.inspect =~ /^#<struct a=#<struct #<.*?>:...>>$/)
+
+ Struct.new("Foo", :a)
+ o = Struct::Foo.new(1)
+ assert_equal("#<struct Struct::Foo a=1>", o.inspect)
+ Struct.instance_eval { remove_const(:Foo) }
+
+ klass = Struct.new(:a, :b)
+ o = klass.new(1, 2)
+ assert_equal("#<struct a=1, b=2>", o.inspect)
+
+ klass = Struct.new(:@a)
+ o = klass.new(1)
+ assert_equal("#<struct :@a=1>", o.inspect)
+ end
+
+ def test_init_copy
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal(o, o.dup)
+ end
+
+ def test_aref
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal(1, o[0])
+ assert_raise(IndexError) { o[-2] }
+ assert_raise(IndexError) { o[1] }
+ end
+
+ def test_aset
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ o[0] = 2
+ assert_equal(2, o[:a])
+ assert_raise(IndexError) { o[-2] = 3 }
+ assert_raise(IndexError) { o[1] = 3 }
+ end
+
+ def test_values_at
+ klass = Struct.new(:a, :b, :c, :d, :e, :f)
+ o = klass.new(1, 2, 3, 4, 5, 6)
+ assert_equal([2, 4, 6], o.values_at(1, 3, 5))
+ assert_equal([2, 3, 4, 3, 4, 5], o.values_at(1..3, 2...5))
+ end
+
+ def test_select
+ klass = Struct.new(:a, :b, :c, :d, :e, :f)
+ o = klass.new(1, 2, 3, 4, 5, 6)
+ assert_equal([1, 3, 5], o.select {|v| v % 2 != 0 })
+ assert_raise(ArgumentError) { o.select(1) }
+ end
+
+ def test_equal
+ klass1 = Struct.new(:a)
+ klass2 = Struct.new(:a, :b)
+ o1 = klass1.new(1)
+ o2 = klass1.new(1)
+ o3 = klass2.new(1)
+ assert(o1.==(o2))
+ assert(o1 != o3)
+ end
+
+ def test_hash
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert(o.hash.is_a?(Fixnum))
+ end
+
+ def test_eql
+ klass1 = Struct.new(:a)
+ klass2 = Struct.new(:a, :b)
+ o1 = klass1.new(1)
+ o2 = klass1.new(1)
+ o3 = klass2.new(1)
+ assert(o1.eql?(o2))
+ assert(!(o1.eql?(o3)))
+ end
+
+ def test_size
+ klass = Struct.new(:a)
+ o = klass.new(1)
+ assert_equal(1, o.size)
+ end
+
+ def test_error
+ assert_raise(TypeError){
+ Struct.new(0)
+ }
+ end
+end
diff --git a/trunk/test/ruby/test_super.rb b/trunk/test/ruby/test_super.rb
new file mode 100644
index 0000000000..5e93074e2d
--- /dev/null
+++ b/trunk/test/ruby/test_super.rb
@@ -0,0 +1,134 @@
+require 'test/unit'
+
+class TestSuper < Test::Unit::TestCase
+ class Base
+ def single(a) a end
+ def double(a, b) [a,b] end
+ def array(*a) a end
+ def optional(a = 0) a end
+ end
+ class Single1 < Base
+ def single(*) super end
+ end
+ class Single2 < Base
+ def single(a,*) super end
+ end
+ class Double1 < Base
+ def double(*) super end
+ end
+ class Double2 < Base
+ def double(a,*) super end
+ end
+ class Double3 < Base
+ def double(a,b,*) super end
+ end
+ class Array1 < Base
+ def array(*) super end
+ end
+ class Array2 < Base
+ def array(a,*) super end
+ end
+ class Array3 < Base
+ def array(a,b,*) super end
+ end
+ class Array4 < Base
+ def array(a,b,c,*) super end
+ end
+ class Optional1 < Base
+ def optional(a = 1) super end
+ end
+ class Optional2 < Base
+ def optional(a, b = 1) super end
+ end
+ class Optional3 < Base
+ def single(a = 1) super end
+ end
+ class Optional4 < Base
+ def array(a = 1, *) super end
+ end
+ class Optional5 < Base
+ def array(a = 1, b = 2, *) super end
+ end
+
+ def test_single1
+ assert_equal(1, Single1.new.single(1))
+ end
+ def test_single2
+ assert_equal(1, Single2.new.single(1))
+ end
+ def test_double1
+ assert_equal([1, 2], Double1.new.double(1, 2))
+ end
+ def test_double2
+ assert_equal([1, 2], Double2.new.double(1, 2))
+ end
+ def test_double3
+ assert_equal([1, 2], Double3.new.double(1, 2))
+ end
+ def test_array1
+ assert_equal([], Array1.new.array())
+ assert_equal([1], Array1.new.array(1))
+ end
+ def test_array2
+ assert_equal([1], Array2.new.array(1))
+ assert_equal([1,2], Array2.new.array(1, 2))
+ end
+ def test_array3
+ assert_equal([1,2], Array3.new.array(1, 2))
+ assert_equal([1,2,3], Array3.new.array(1, 2, 3))
+ end
+ def test_array4
+ assert_equal([1,2,3], Array4.new.array(1, 2, 3))
+ assert_equal([1,2,3,4], Array4.new.array(1, 2, 3, 4))
+ end
+ def test_optional1
+ assert_equal(9, Optional1.new.optional(9))
+ assert_equal(1, Optional1.new.optional)
+ end
+ def test_optional2
+ assert_raise(ArgumentError) do
+ # call Base#optional with 2 arguments; the 2nd arg is supplied
+ assert_equal(9, Optional2.new.optional(9))
+ end
+ assert_raise(ArgumentError) do
+ # call Base#optional with 2 arguments
+ assert_equal(9, Optional2.new.optional(9, 2))
+ end
+ end
+ def test_optional3
+ assert_equal(9, Optional3.new.single(9))
+ # call Base#single with 1 argument; the arg is supplied
+ assert_equal(1, Optional3.new.single)
+ end
+ def test_optional4
+ assert_equal([1], Optional4.new.array)
+ assert_equal([9], Optional4.new.array(9))
+ assert_equal([9, 8], Optional4.new.array(9, 8))
+ end
+ def test_optional5
+ assert_equal([1, 2], Optional5.new.array)
+ assert_equal([9, 2], Optional5.new.array(9))
+ assert_equal([9, 8], Optional5.new.array(9, 8))
+ assert_equal([9, 8, 7], Optional5.new.array(9, 8, 7))
+ end
+
+ class A
+ def tt(aa)
+ "A#tt"
+ end
+
+ def uu(a)
+ class << self
+ define_method(:tt) do |sym|
+ super(sym)
+ end
+ end
+ end
+ end
+
+ def test_define_method
+ a = A.new
+ a.uu(12)
+ assert_equal("A#tt", a.tt(12), "[ruby-core:3856]")
+ end
+end
diff --git a/trunk/test/ruby/test_symbol.rb b/trunk/test/ruby/test_symbol.rb
new file mode 100644
index 0000000000..a19a78e605
--- /dev/null
+++ b/trunk/test/ruby/test_symbol.rb
@@ -0,0 +1,135 @@
+require 'test/unit'
+
+class TestSymbol < Test::Unit::TestCase
+ # [ruby-core:3573]
+
+ def assert_eval_inspected(sym)
+ n = sym.inspect
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(n))}
+ end
+
+ def test_inspect_invalid
+ # 2) Symbol#inspect sometimes returns invalid symbol representations:
+ assert_eval_inspected(:"!")
+ assert_eval_inspected(:"=")
+ assert_eval_inspected(:"0")
+ assert_eval_inspected(:"$1")
+ assert_eval_inspected(:"@1")
+ assert_eval_inspected(:"@@1")
+ assert_eval_inspected(:"@")
+ assert_eval_inspected(:"@@")
+ end
+
+ def assert_inspect_evaled(n)
+ assert_nothing_raised(SyntaxError) {assert_equal(n, eval(n).inspect)}
+ end
+
+ def test_inspect_suboptimal
+ # 3) Symbol#inspect sometimes returns suboptimal symbol representations:
+ assert_inspect_evaled(':foo')
+ assert_inspect_evaled(':foo!')
+ assert_inspect_evaled(':bar?')
+ assert_inspect_evaled(':<<')
+ assert_inspect_evaled(':>>')
+ assert_inspect_evaled(':<=')
+ assert_inspect_evaled(':>=')
+ assert_inspect_evaled(':=~')
+ assert_inspect_evaled(':==')
+ assert_inspect_evaled(':===')
+ assert_raise(SyntaxError) {eval ':='}
+ assert_inspect_evaled(':*')
+ assert_inspect_evaled(':**')
+ assert_raise(SyntaxError) {eval ':***'}
+ assert_inspect_evaled(':+')
+ assert_inspect_evaled(':-')
+ assert_inspect_evaled(':+@')
+ assert_inspect_evaled(':-@')
+ assert_inspect_evaled(':|')
+ assert_inspect_evaled(':^')
+ assert_inspect_evaled(':&')
+ assert_inspect_evaled(':/')
+ assert_inspect_evaled(':%')
+ assert_inspect_evaled(':~')
+ assert_inspect_evaled(':`')
+ assert_inspect_evaled(':[]')
+ assert_inspect_evaled(':[]=')
+ assert_raise(SyntaxError) {eval ':||'}
+ assert_raise(SyntaxError) {eval ':&&'}
+ assert_raise(SyntaxError) {eval ':['}
+ end
+
+ def test_inspect_dollar
+ # 4) :$- always treats next character literally:
+ sym = "$-".intern
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(':$-'))}
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(":$-\n"))}
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(":$- "))}
+ assert_nothing_raised(SyntaxError) {assert_equal(sym, eval(":$-#"))}
+ assert_raise(SyntaxError) {eval ':$-('}
+ end
+
+ def test_inspect_number
+ # 5) Inconsistency between :$0 and :$1? The first one is valid, but the
+ # latter isn't.
+ assert_inspect_evaled(':$0')
+ assert_inspect_evaled(':$1')
+ end
+
+ def test_to_proc
+ assert_equal %w(1 2 3), (1..3).map(&:to_s)
+ [
+ [],
+ [1],
+ [1, 2],
+ [1, [2, 3]],
+ ].each do |ary|
+ ary_id = ary.object_id
+ assert_equal ary_id, :object_id.to_proc.call(ary)
+ ary_ids = ary.collect{|x| x.object_id }
+ assert_equal ary_ids, ary.collect(&:object_id)
+ end
+ end
+
+ def test_call
+ o = Object.new
+ def o.foo(x, y); x + y; end
+
+ assert_equal(3, :foo.to_proc.call(o, 1, 2))
+ assert_raise(ArgumentError) { :foo.to_proc.call }
+ end
+
+ def test_succ
+ assert_equal(:fop, :foo.succ)
+ end
+
+ def test_cmp
+ assert_equal(0, :FoO <=> :FoO)
+ assert_equal(-1, :FoO <=> :fOO)
+ assert_equal(1, :fOO <=> :FoO)
+ assert_nil(:foo <=> "foo")
+ end
+
+ def test_casecmp
+ assert_equal(0, :FoO.casecmp(:fOO))
+ assert_equal(1, :FoO.casecmp(:BaR))
+ assert_equal(-1, :baR.casecmp(:FoO))
+ assert_nil(:foo.casecmp("foo"))
+ end
+
+ def test_length
+ assert_equal(3, :FoO.length)
+ assert_equal(3, :FoO.size)
+ end
+
+ def test_empty
+ assert_equal(false, :FoO.empty?)
+ assert_equal(true, :"".empty?)
+ end
+
+ def test_case
+ assert_equal(:FOO, :FoO.upcase)
+ assert_equal(:foo, :FoO.downcase)
+ assert_equal(:Foo, :foo.capitalize)
+ assert_equal(:fOo, :FoO.swapcase)
+ end
+end
diff --git a/trunk/test/ruby/test_system.rb b/trunk/test/ruby/test_system.rb
new file mode 100644
index 0000000000..ec8aca74cb
--- /dev/null
+++ b/trunk/test/ruby/test_system.rb
@@ -0,0 +1,76 @@
+require 'test/unit'
+require 'tmpdir'
+require_relative 'envutil'
+
+class TestSystem < Test::Unit::TestCase
+ def valid_syntax?(code, fname)
+ code.force_encoding("ascii-8bit")
+ code = code.sub(/\A(?:\s*\#.*$)*(\n)?/n) {
+ "#$&#{"\n" if $1 && !$2}BEGIN{return true}\n"
+ }
+ eval(code, nil, fname, 0)
+ end
+
+ def test_system
+ ruby = EnvUtil.rubybin
+ assert_equal("foobar\n", `echo foobar`)
+ assert_equal('foobar', `#{ruby} -e 'print "foobar"'`)
+
+ Dir.mktmpdir("ruby_script_tmp") {|tmpdir|
+ tmpfilename = "#{tmpdir}/ruby_script_tmp.#{$$}"
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "print $zzz\n";
+ tmp.close
+
+ assert_equal('true', `#{ruby} -s #{tmpfilename} -zzz`)
+ assert_equal('555', `#{ruby} -s #{tmpfilename} -zzz=555`)
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "#! /usr/local/bin/ruby -s\n";
+ tmp.print "print $zzz\n";
+ tmp.close
+
+ assert_equal('678', `#{ruby} #{tmpfilename} -zzz=678`)
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "this is a leading junk\n";
+ tmp.print "#! /usr/local/bin/ruby -s\n";
+ tmp.print "print $zzz\n";
+ tmp.print "__END__\n";
+ tmp.print "this is a trailing junk\n";
+ tmp.close
+
+ assert_equal('', `#{ruby} -x #{tmpfilename}`)
+ assert_equal('555', `#{ruby} -x #{tmpfilename} -zzz=555`)
+
+ tmp = open(tmpfilename, "w")
+ for i in 1..5
+ tmp.print i, "\n"
+ end
+ tmp.close
+
+ `#{ruby} -i.bak -pe '$_.sub!(/^[0-9]+$/){$&.to_i * 5}' #{tmpfilename}`
+ tmp = open(tmpfilename, "r")
+ while tmp.gets
+ assert_equal(0, $_.to_i % 5)
+ end
+ tmp.close
+
+ File.unlink tmpfilename or `/bin/rm -f "#{tmpfilename}"`
+ File.unlink "#{tmpfilename}.bak" or `/bin/rm -f "#{tmpfilename}.bak"`
+ }
+ end
+
+ def test_syntax
+ assert_nothing_raised(Exception) do
+ for script in Dir[File.expand_path("../../../{lib,sample,ext}/**/*.rb", __FILE__)]
+ valid_syntax? IO::read(script), script
+ end
+ end
+ end
+
+ def test_empty_evstr
+ assert_equal("", eval('"#{}"', nil, __FILE__, __LINE__), "[ruby-dev:25113]")
+ end
+end
diff --git a/trunk/test/ruby/test_thread.rb b/trunk/test/ruby/test_thread.rb
new file mode 100644
index 0000000000..cd99cdc401
--- /dev/null
+++ b/trunk/test/ruby/test_thread.rb
@@ -0,0 +1,507 @@
+require 'test/unit'
+require 'thread'
+require_relative 'envutil'
+
+class TestThread < Test::Unit::TestCase
+ class Thread < ::Thread
+ Threads = []
+ def self.new(*)
+ th = super
+ th.abort_on_exception = true
+ Threads << th
+ th
+ end
+ end
+
+ def setup
+ Thread::Threads.clear
+ end
+
+ def teardown
+ Thread::Threads.each do |t|
+ t.kill if t.alive?
+ begin
+ t.join
+ rescue Exception
+ end
+ end
+ end
+
+ def test_mutex_synchronize
+ m = Mutex.new
+ r = 0
+ max = 100
+ (1..max).map{
+ Thread.new{
+ i=0
+ while i<max*max
+ i+=1
+ m.synchronize{
+ r += 1
+ }
+ end
+ }
+ }.each{|e|
+ e.join
+ }
+ assert_equal(max * max * max, r)
+ end
+
+ def test_condvar
+ mutex = Mutex.new
+ condvar = ConditionVariable.new
+ result = []
+ mutex.synchronize do
+ t = Thread.new do
+ mutex.synchronize do
+ result << 1
+ condvar.signal
+ end
+ end
+
+ result << 0
+ condvar.wait(mutex)
+ result << 2
+ t.join
+ end
+ assert_equal([0, 1, 2], result)
+ end
+
+ def test_condvar_wait_not_owner
+ mutex = Mutex.new
+ condvar = ConditionVariable.new
+
+ assert_raises(ThreadError) { condvar.wait(mutex) }
+ end
+
+ def test_condvar_wait_exception_handling
+ # Calling wait in the only thread running should raise a ThreadError of
+ # 'stopping only thread'
+ mutex = Mutex.new
+ condvar = ConditionVariable.new
+
+ locked = false
+ thread = Thread.new do
+ Thread.current.abort_on_exception = false
+ mutex.synchronize do
+ begin
+ condvar.wait(mutex)
+ rescue Exception
+ locked = mutex.locked?
+ raise
+ end
+ end
+ end
+
+ until thread.stop?
+ sleep(0.1)
+ end
+
+ thread.raise Interrupt, "interrupt a dead condition variable"
+ assert_raises(Interrupt) { thread.value }
+ assert(locked)
+ end
+
+ def test_local_barrier
+ dir = File.dirname(__FILE__)
+ lbtest = File.join(dir, "lbtest.rb")
+ $:.unshift File.join(File.dirname(dir), 'ruby')
+ require 'envutil'
+ $:.shift
+ 10.times {
+ result = `#{EnvUtil.rubybin} #{lbtest}`
+ assert(!$?.coredump?, '[ruby-dev:30653]')
+ assert_equal("exit.", result[/.*\Z/], '[ruby-dev:30653]')
+ }
+ end
+
+ def test_priority
+ c1 = c2 = 0
+ t1 = Thread.new { loop { c1 += 1 } }
+ t1.priority = -1
+ t2 = Thread.new { loop { c2 += 1 } }
+ t2.priority = -3
+ assert_equal(-1, t1.priority)
+ assert_equal(-3, t2.priority)
+ sleep 0.5
+ t1.kill
+ t2.kill
+ assert(c1 > c2 * 1.5, "[ruby-dev:33124]")
+ end
+
+ def test_new
+ assert_raise(ThreadError) do
+ Thread.new
+ end
+
+ t1 = Thread.new { sleep }
+ assert_raise(ThreadError) do
+ t1.instance_eval { initialize { } }
+ end
+
+ t2 = Thread.new(&method(:sleep).to_proc)
+ assert_raise(ThreadError) do
+ t2.instance_eval { initialize { } }
+ end
+
+ ensure
+ t1.kill if t1
+ t2.kill if t2
+ end
+
+ def test_join
+ t = Thread.new { sleep }
+ assert_nil(t.join(0.5))
+
+ ensure
+ t.kill if t
+ end
+
+ def test_join2
+ t1 = Thread.new { sleep(1.5) }
+ t2 = Thread.new do
+ t1.join(1)
+ end
+ t3 = Thread.new do
+ sleep 0.5
+ t1.join
+ end
+ assert_nil(t2.value)
+ assert_equal(t1, t3.value)
+
+ ensure
+ t1.kill if t1
+ t2.kill if t2
+ t3.kill if t3
+ end
+
+ def test_kill_main_thread
+ assert_in_out_err([], <<-INPUT, %w(1), [])
+ p 1
+ Thread.kill Thread.current
+ p 2
+ INPUT
+ end
+
+ def test_exit
+ s = 0
+ Thread.new do
+ s += 1
+ Thread.exit
+ s += 2
+ end.join
+ assert_equal(1, s)
+ end
+
+ def test_wakeup
+ s = 0
+ t = Thread.new do
+ s += 1
+ Thread.stop
+ s += 1
+ end
+ sleep 0.5
+ assert_equal(1, s)
+ t.wakeup
+ sleep 0.5
+ assert_equal(2, s)
+ assert_raise(ThreadError) { t.wakeup }
+
+ ensure
+ t.kill if t
+ end
+
+ def test_stop
+ assert_in_out_err([], <<-INPUT, %w(2), [])
+ begin
+ Thread.stop
+ p 1
+ rescue ThreadError
+ p 2
+ end
+ INPUT
+ end
+
+ def test_list
+ assert_in_out_err([], <<-INPUT) do |r, e|
+ t1 = Thread.new { sleep }
+ Thread.pass
+ t2 = Thread.new { loop { } }
+ t3 = Thread.new { }.join
+ p [Thread.current, t1, t2].sort_by {|t| t.object_id }
+ p Thread.list.sort_by {|t| t.object_id }
+ INPUT
+ assert_equal(r.first, r.last)
+ assert_equal([], e)
+ end
+ end
+
+ def test_main
+ assert_in_out_err([], <<-INPUT, %w(true false), [])
+ p Thread.main == Thread.current
+ Thread.new { p Thread.main == Thread.current }.join
+ INPUT
+ end
+
+ def test_abort_on_exception
+ assert_in_out_err([], <<-INPUT, %w(false 1), [])
+ p Thread.abort_on_exception
+ begin
+ Thread.new { raise }
+ sleep 0.5
+ p 1
+ rescue
+ p 2
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(true 2), [])
+ Thread.abort_on_exception = true
+ p Thread.abort_on_exception
+ begin
+ Thread.new { raise }
+ sleep 0.5
+ p 1
+ rescue
+ p 2
+ end
+ INPUT
+
+ assert_in_out_err(%w(-d), <<-INPUT, %w(false 2), /.+/)
+ p Thread.abort_on_exception
+ begin
+ Thread.new { raise }
+ sleep 0.5
+ p 1
+ rescue
+ p 2
+ end
+ INPUT
+
+ assert_in_out_err([], <<-INPUT, %w(false true 2), [])
+ p Thread.abort_on_exception
+ begin
+ t = Thread.new { sleep 0.5; raise }
+ t.abort_on_exception = true
+ p t.abort_on_exception
+ sleep 1
+ p 1
+ rescue
+ p 2
+ end
+ INPUT
+ end
+
+ def test_status_and_stop_p
+ a = ::Thread.new { raise("die now") }
+ b = Thread.new { Thread.stop }
+ c = Thread.new { Thread.exit }
+ d = Thread.new { sleep }
+ e = Thread.current
+ sleep 0.5
+
+ assert_equal(nil, a.status)
+ assert(a.stop?)
+
+ assert_equal("sleep", b.status)
+ assert(b.stop?)
+
+ assert_equal(false, c.status)
+ assert_match(/^#<TestThread::Thread:.* dead>$/, c.inspect)
+ assert(c.stop?)
+
+ d.kill
+ assert_equal("aborting", d.status)
+ assert(!d.stop?)
+
+ assert_equal("run", e.status)
+ assert(!e.stop?)
+
+ ensure
+ a.kill if a
+ b.kill if b
+ c.kill if c
+ d.kill if d
+ end
+
+ def test_safe_level
+ t = Thread.new { $SAFE = 3; sleep }
+ sleep 0.5
+ assert_equal(0, Thread.current.safe_level)
+ assert_equal(3, t.safe_level)
+
+ ensure
+ t.kill if t
+ end
+
+ def test_thread_local
+ t = Thread.new { sleep }
+
+ assert_equal(false, t.key?(:foo))
+
+ t["foo"] = "foo"
+ t["bar"] = "bar"
+ t["baz"] = "baz"
+
+ assert_equal(true, t.key?(:foo))
+ assert_equal(true, t.key?("foo"))
+ assert_equal(false, t.key?(:qux))
+ assert_equal(false, t.key?("qux"))
+
+ assert_equal([:foo, :bar, :baz], t.keys)
+
+ ensure
+ t.kill if t
+ end
+
+ def test_thread_local_security
+ t = Thread.new { sleep }
+
+ assert_raise(SecurityError) do
+ Thread.new { $SAFE = 4; t[:foo] }.join
+ end
+
+ assert_raise(SecurityError) do
+ Thread.new { $SAFE = 4; t[:foo] = :baz }.join
+ end
+
+ assert_raise(RuntimeError) do
+ Thread.new do
+ Thread.current[:foo] = :bar
+ Thread.current.freeze
+ Thread.current[:foo] = :baz
+ end.join
+ end
+ end
+
+ def test_select_wait
+ assert_nil(IO.select(nil, nil, nil, 1))
+ t = Thread.new do
+ IO.select(nil, nil, nil, nil)
+ end
+ sleep 0.5
+ t.kill
+ end
+
+ def test_mutex_deadlock
+ m = Mutex.new
+ m.synchronize do
+ assert_raise(ThreadError) do
+ m.synchronize do
+ assert(false)
+ end
+ end
+ end
+ end
+
+ def test_mutex_interrupt
+ m = Mutex.new
+ m.lock
+ t = Thread.new do
+ m.lock
+ :foo
+ end
+ sleep 0.5
+ t.kill
+ assert_nil(t.value)
+ end
+
+ def test_mutex_illegal_unlock
+ m = Mutex.new
+ m.lock
+ assert_raise(ThreadError) do
+ Thread.new do
+ m.unlock
+ end.join
+ end
+ end
+
+ def test_mutex_fifo_like_lock
+ m1 = Mutex.new
+ m2 = Mutex.new
+ m1.lock
+ m2.lock
+ m1.unlock
+ m2.unlock
+ assert_equal(false, m1.locked?)
+ assert_equal(false, m2.locked?)
+
+ m3 = Mutex.new
+ m1.lock
+ m2.lock
+ m3.lock
+ m1.unlock
+ m2.unlock
+ m3.unlock
+ assert_equal(false, m1.locked?)
+ assert_equal(false, m2.locked?)
+ assert_equal(false, m3.locked?)
+ end
+
+ def test_recursive_error
+ o = Object.new
+ def o.inspect
+ Thread.current[:__recursive_key__][:inspect] = nil
+ super
+ end
+ assert_raise(TypeError) { [o].inspect }
+ end
+end
+
+class TestThreadGroup < Test::Unit::TestCase
+ def test_thread_init
+ thgrp = ThreadGroup.new
+ Thread.new{
+ thgrp.add(Thread.current)
+ assert_equal(thgrp, Thread.new{sleep 1}.group)
+ }.join
+ end
+
+ def test_frozen_thgroup
+ thgrp = ThreadGroup.new
+
+ t = Thread.new{1}
+ Thread.new{
+ thgrp.add(Thread.current)
+ thgrp.freeze
+ assert_raise(ThreadError) do
+ Thread.new{1}.join
+ end
+ assert_raise(ThreadError) do
+ thgrp.add(t)
+ end
+ assert_raise(ThreadError) do
+ ThreadGroup.new.add Thread.current
+ end
+ }.join
+ t.join
+ end
+
+ def test_enclosed_thgroup
+ thgrp = ThreadGroup.new
+ assert_equal(false, thgrp.enclosed?)
+
+ t = Thread.new{1}
+ Thread.new{
+ thgrp.add(Thread.current)
+ thgrp.enclose
+ assert_equal(true, thgrp.enclosed?)
+ assert_nothing_raised do
+ Thread.new{1}.join
+ end
+ assert_raise(ThreadError) do
+ thgrp.add t
+ end
+ assert_raise(ThreadError) do
+ ThreadGroup.new.add Thread.current
+ end
+ }.join
+ t.join
+ end
+
+ def test_uninitialized
+ c = Class.new(Thread)
+ c.class_eval { def initialize; end }
+ assert_raise(ThreadError) { c.new.start }
+ end
+end
diff --git a/trunk/test/ruby/test_time.rb b/trunk/test/ruby/test_time.rb
new file mode 100644
index 0000000000..87516e10c4
--- /dev/null
+++ b/trunk/test/ruby/test_time.rb
@@ -0,0 +1,394 @@
+require 'test/unit'
+require 'rational'
+require 'timeout'
+
+class TestTime < Test::Unit::TestCase
+ def test_time_add()
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) + 3 * 3600,
+ Time.utc(2000, 3, 21, 6, 30))
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) + (-3 * 3600),
+ Time.utc(2000, 3, 21, 0, 30))
+ assert_equal(0, (Time.at(1.1) + 0.9).usec)
+ end
+
+ def test_time_subt()
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) - 3 * 3600,
+ Time.utc(2000, 3, 21, 0, 30))
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) - (-3 * 3600),
+ Time.utc(2000, 3, 21, 6, 30))
+ assert_equal(900000, (Time.at(1.1) - 0.2).usec)
+ end
+
+ def test_time_time()
+ assert_equal(Time.utc(2000, 3, 21, 3, 30) \
+ -Time.utc(2000, 3, 21, 0, 30), 3*3600)
+ assert_equal(Time.utc(2000, 3, 21, 0, 30) \
+ -Time.utc(2000, 3, 21, 3, 30), -3*3600)
+ end
+
+ def negative_time_t?
+ begin
+ Time.at(-1)
+ true
+ rescue ArgumentError
+ false
+ end
+ end
+
+ def test_timegm
+ if negative_time_t?
+ assert_equal(-0x80000000, Time.utc(1901, 12, 13, 20, 45, 52).tv_sec)
+ assert_equal(-2, Time.utc(1969, 12, 31, 23, 59, 58).tv_sec)
+ assert_equal(-1, Time.utc(1969, 12, 31, 23, 59, 59).tv_sec)
+ end
+
+ assert_equal(0, Time.utc(1970, 1, 1, 0, 0, 0).tv_sec) # the Epoch
+ assert_equal(1, Time.utc(1970, 1, 1, 0, 0, 1).tv_sec)
+ assert_equal(31535999, Time.utc(1970, 12, 31, 23, 59, 59).tv_sec)
+ assert_equal(31536000, Time.utc(1971, 1, 1, 0, 0, 0).tv_sec)
+ assert_equal(78796799, Time.utc(1972, 6, 30, 23, 59, 59).tv_sec)
+
+ # 1972-06-30T23:59:60Z is the first leap second.
+ if Time.utc(1972, 7, 1, 0, 0, 0) - Time.utc(1972, 6, 30, 23, 59, 59) == 1
+ # no leap second.
+ assert_equal(78796800, Time.utc(1972, 7, 1, 0, 0, 0).tv_sec)
+ assert_equal(78796801, Time.utc(1972, 7, 1, 0, 0, 1).tv_sec)
+ assert_equal(946684800, Time.utc(2000, 1, 1, 0, 0, 0).tv_sec)
+ assert_equal(0x7fffffff, Time.utc(2038, 1, 19, 3, 14, 7).tv_sec)
+ else
+ # leap seconds supported.
+ assert_equal(2, Time.utc(1972, 7, 1, 0, 0, 0) - Time.utc(1972, 6, 30, 23, 59, 59))
+ assert_equal(78796800, Time.utc(1972, 6, 30, 23, 59, 60).tv_sec)
+ assert_equal(78796801, Time.utc(1972, 7, 1, 0, 0, 0).tv_sec)
+ assert_equal(78796802, Time.utc(1972, 7, 1, 0, 0, 1).tv_sec)
+ assert_equal(946684822, Time.utc(2000, 1, 1, 0, 0, 0).tv_sec)
+ end
+ end
+
+ def test_strtime
+ t = nil
+ assert_nothing_raised { t = Time.utc("2000", "1", "2" , "3", "4", "5") }
+ assert_equal(Time.utc(2000,1,2,3,4,5), t)
+ end
+
+ def test_huge_difference
+ if negative_time_t?
+ assert_equal(Time.at(-0x80000000), Time.at(0x7fffffff) - 0xffffffff, "[ruby-dev:22619]")
+ assert_equal(Time.at(-0x80000000), Time.at(0x7fffffff) + (-0xffffffff))
+ assert_equal(Time.at(0x7fffffff), Time.at(-0x80000000) + 0xffffffff, "[ruby-dev:22619]")
+ assert_equal(Time.at(0x7fffffff), Time.at(-0x80000000) - (-0xffffffff))
+ end
+ end
+
+ def test_big_minus
+ begin
+ bigtime0 = Time.at(2**60)
+ bigtime1 = Time.at(2**60+1)
+ rescue RangeError
+ return
+ end
+ assert_equal(1.0, bigtime1 - bigtime0)
+ end
+
+ def test_at
+ assert_equal(100000, Time.at(0.1).usec)
+ assert_equal(10000, Time.at(0.01).usec)
+ assert_equal(1000, Time.at(0.001).usec)
+ assert_equal(100, Time.at(0.0001).usec)
+ assert_equal(10, Time.at(0.00001).usec)
+ assert_equal(1, Time.at(0.000001).usec)
+ assert_equal(100000000, Time.at(0.1).nsec)
+ assert_equal(10000000, Time.at(0.01).nsec)
+ assert_equal(1000000, Time.at(0.001).nsec)
+ assert_equal(100000, Time.at(0.0001).nsec)
+ assert_equal(10000, Time.at(0.00001).nsec)
+ assert_equal(1000, Time.at(0.000001).nsec)
+ assert_equal(100, Time.at(0.0000001).nsec)
+ assert_equal(10, Time.at(0.00000001).nsec)
+ assert_equal(1, Time.at(0.000000001).nsec)
+ assert_equal(0, Time.at(1e-10).nsec)
+ assert_equal(0, Time.at(4e-10).nsec)
+ assert_equal(1, Time.at(6e-10).nsec)
+ assert_equal(1, Time.at(14e-10).nsec)
+ assert_equal(2, Time.at(16e-10).nsec)
+ if negative_time_t?
+ assert_equal(0, Time.at(-1e-10).nsec)
+ assert_equal(0, Time.at(-4e-10).nsec)
+ assert_equal(999999999, Time.at(-6e-10).nsec)
+ assert_equal(999999999, Time.at(-14e-10).nsec)
+ assert_equal(999999998, Time.at(-16e-10).nsec)
+ end
+ end
+
+ def test_at2
+ assert_equal(100, Time.at(0, 0.1).nsec)
+ assert_equal(10, Time.at(0, 0.01).nsec)
+ assert_equal(1, Time.at(0, 0.001).nsec)
+ end
+
+ def test_at_rational
+ assert_equal(1, Time.at(Rational(1,1) / 1000000000).nsec)
+ assert_equal(1, Time.at(1167609600 + Rational(1,1) / 1000000000).nsec)
+ end
+
+ def test_utc_subsecond
+ assert_equal(100000, Time.utc(2007,1,1,0,0,1.1).usec)
+ assert_equal(100000, Time.utc(2007,1,1,0,0,Rational(11,10)).usec)
+ end
+
+ def test_eq_nsec
+ assert_equal(Time.at(0, 0.123), Time.at(0, 0.123))
+ assert_not_equal(Time.at(0, 0.123), Time.at(0, 0.124))
+ end
+
+ def assert_marshal_roundtrip(t)
+ iv_names = t.instance_variables
+ iv_vals1 = iv_names.map {|n| t.instance_variable_get n }
+ m = Marshal.dump(t)
+ t2 = Marshal.load(m)
+ iv_vals2 = iv_names.map {|n| t2.instance_variable_get n }
+ assert_equal(t, t2)
+ assert_equal(iv_vals1, iv_vals2)
+ t2
+ end
+
+ def test_marshal_nsec
+ assert_marshal_roundtrip(Time.at(0, 0.123))
+ assert_marshal_roundtrip(Time.at(0, 0.120))
+ end
+
+ def test_marshal_ivar
+ t = Time.at(123456789, 987654.321)
+ t.instance_eval { @var = 135 }
+ assert_marshal_roundtrip(t)
+ assert_marshal_roundtrip(Marshal.load(Marshal.dump(t)))
+ end
+
+ # Sat Jan 01 00:00:00 UTC 2000
+ T2000 = Time.at(946684800).gmtime
+
+ def test_security_error
+ assert_raise(SecurityError) do
+ Thread.new do
+ t = Time.gm(2000)
+ $SAFE = 4
+ t.localtime
+ end.join
+ end
+ end
+
+ def test_at3
+ assert_equal(T2000, Time.at(T2000))
+ assert_raise(RangeError) do
+ Time.at(2**31-1, 1_000_000)
+ Time.at(2**63-1, 1_000_000)
+ end
+ assert_raise(RangeError) do
+ Time.at(-2**31, -1_000_000)
+ Time.at(-2**63, -1_000_000)
+ end
+ end
+
+ def test_utc_or_local
+ assert_equal(T2000, Time.gm(2000))
+ assert_equal(T2000, Time.gm(0, 0, 0, 1, 1, 2000, :foo, :bar, false, :baz))
+ assert_equal(T2000, Time.gm(0))
+ assert_equal(T2000, Time.gm(100))
+ assert_equal(T2000, Time.gm(2000, "jan"))
+ assert_equal(T2000, Time.gm(2000, "1"))
+ assert_equal(T2000, Time.gm(2000, 1, 1, 0, 0, 0, 0))
+ assert_equal(T2000, Time.gm(2000, 1, 1, 0, 0, 0, "0"))
+ assert_equal(T2000, Time.gm(2000, 1, 1, 0, 0, "0", :foo, :foo))
+ assert_raise(ArgumentError) { Time.gm(2000, 1, 1, 0, 0, -1, :foo, :foo) }
+ assert_raise(ArgumentError) { Time.gm(2000, 1, 1, 0, 0, -1.0, :foo, :foo) }
+ assert_raise(RangeError) do
+ Time.gm(2000, 1, 1, 0, 0, 10_000_000_000_000_000_001.0, :foo, :foo)
+ end
+ assert_raise(ArgumentError) { Time.gm(2000, 1, 1, 0, 0, -(2**31), :foo, :foo) }
+ o = Object.new
+ def o.divmod(x); nil; end
+ assert_raise(TypeError) { Time.gm(2000, 1, 1, 0, 0, o, :foo, :foo) }
+ def o.divmod(x); [-1, 0]; end
+ assert_raise(ArgumentError) { Time.gm(2000, 1, 1, 0, 0, o, :foo, :foo) }
+ assert_raise(ArgumentError) { Time.gm(2000, 13) }
+
+ t = Time.local(2000)
+ assert_equal(t.gmt_offset, T2000 - t)
+ end
+
+ def test_time_interval
+ m = Mutex.new.lock
+ assert_nothing_raised {
+ Timeout.timeout(10) {
+ m.sleep(0)
+ }
+ }
+ assert_raise(ArgumentError) { m.sleep(-1) }
+ end
+
+ def test_to_f
+ assert_equal(946684800.0, T2000.to_f)
+ end
+
+ def test_cmp
+ assert_equal(-1, T2000 <=> Time.gm(2001))
+ assert_equal(1, T2000 <=> Time.gm(1999))
+ assert_nil(T2000 <=> 0)
+ end
+
+ def test_eql
+ assert(T2000.eql?(T2000))
+ assert(!T2000.eql?(Time.gm(2001)))
+ end
+
+ def test_utc_p
+ assert(Time.gm(2000).gmt?)
+ assert(!Time.local(2000).gmt?)
+ assert(!Time.at(0).gmt?)
+ end
+
+ def test_hash
+ assert_kind_of(Integer, T2000.hash)
+ end
+
+ def test_init_copy
+ assert_equal(T2000, T2000.dup)
+ assert_raise(TypeError) do
+ T2000.instance_eval { initialize_copy(nil) }
+ end
+ end
+
+ def test_localtime_gmtime
+ assert_nothing_raised do
+ t = Time.gm(2000)
+ assert(t.gmt?)
+ t.localtime
+ assert(!t.gmt?)
+ t.localtime
+ assert(!t.gmt?)
+ t.gmtime
+ assert(t.gmt?)
+ t.gmtime
+ assert(t.gmt?)
+ end
+
+ t1 = Time.gm(2000)
+ t2 = t1.getlocal
+ assert_equal(t1, t2)
+ t1.localtime
+ assert_equal(t1, t2)
+ assert_equal(t1.gmt?, t2.gmt?)
+
+ t1 = Time.local(2000)
+ t2 = t1.getgm
+ assert_equal(t1, t2)
+ t1.gmtime
+ assert_equal(t1, t2)
+ assert_equal(t1.gmt?, t2.gmt?)
+ end
+
+ def test_asctime
+ assert_equal("Sat Jan 1 00:00:00 2000", T2000.asctime)
+ assert_kind_of(String, Time.at(0).asctime)
+ end
+
+ def test_to_s
+ assert_equal("2000-01-01 00:00:00 UTC", T2000.to_s)
+ assert_kind_of(String, Time.at(946684800).getlocal.to_s)
+ assert_equal(Time.at(946684800).getlocal.to_s, Time.at(946684800).to_s)
+ end
+
+ def test_plus_minus_succ
+ # assert_raise(RangeError) { T2000 + 10000000000 }
+ # assert_raise(RangeError) T2000 - 3094168449 }
+ # assert_raise(RangeError) { T2000 + 1200798848 }
+ assert_raise(TypeError) { T2000 + Time.now }
+ assert_equal(T2000 + 1, T2000.succ)
+ end
+
+ def test_readers
+ assert_equal(0, T2000.sec)
+ assert_equal(0, T2000.min)
+ assert_equal(0, T2000.hour)
+ assert_equal(1, T2000.mday)
+ assert_equal(1, T2000.mon)
+ assert_equal(2000, T2000.year)
+ assert_equal(6, T2000.wday)
+ assert_equal(1, T2000.yday)
+ assert_equal(false, T2000.isdst)
+ assert_equal("UTC", T2000.zone)
+ assert_equal(0, T2000.gmt_offset)
+ assert(!T2000.sunday?)
+ assert(!T2000.monday?)
+ assert(!T2000.tuesday?)
+ assert(!T2000.wednesday?)
+ assert(!T2000.thursday?)
+ assert(!T2000.friday?)
+ assert(T2000.saturday?)
+ assert_equal([0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], T2000.to_a)
+
+ t = Time.at(946684800).getlocal
+ assert_equal(t.sec, Time.at(946684800).sec)
+ assert_equal(t.min, Time.at(946684800).min)
+ assert_equal(t.hour, Time.at(946684800).hour)
+ assert_equal(t.mday, Time.at(946684800).mday)
+ assert_equal(t.mon, Time.at(946684800).mon)
+ assert_equal(t.year, Time.at(946684800).year)
+ assert_equal(t.wday, Time.at(946684800).wday)
+ assert_equal(t.yday, Time.at(946684800).yday)
+ assert_equal(t.isdst, Time.at(946684800).isdst)
+ assert_equal(t.zone, Time.at(946684800).zone)
+ assert_equal(t.gmt_offset, Time.at(946684800).gmt_offset)
+ assert_equal(t.sunday?, Time.at(946684800).sunday?)
+ assert_equal(t.monday?, Time.at(946684800).monday?)
+ assert_equal(t.tuesday?, Time.at(946684800).tuesday?)
+ assert_equal(t.wednesday?, Time.at(946684800).wednesday?)
+ assert_equal(t.thursday?, Time.at(946684800).thursday?)
+ assert_equal(t.friday?, Time.at(946684800).friday?)
+ assert_equal(t.saturday?, Time.at(946684800).saturday?)
+ assert_equal(t.to_a, Time.at(946684800).to_a)
+ end
+
+ def test_strftime
+ t = Time.at(946684800).getlocal
+ assert_equal("Sat", T2000.strftime("%a"))
+ assert_equal("Saturday", T2000.strftime("%A"))
+ assert_equal("Jan", T2000.strftime("%b"))
+ assert_equal("January", T2000.strftime("%B"))
+ assert_kind_of(String, T2000.strftime("%c"))
+ assert_equal("01", T2000.strftime("%d"))
+ assert_equal("00", T2000.strftime("%H"))
+ assert_equal("12", T2000.strftime("%I"))
+ assert_equal("001", T2000.strftime("%j"))
+ assert_equal("01", T2000.strftime("%m"))
+ assert_equal("00", T2000.strftime("%M"))
+ assert_equal("AM", T2000.strftime("%p"))
+ assert_equal("00", T2000.strftime("%S"))
+ assert_equal("00", T2000.strftime("%U"))
+ assert_equal("00", T2000.strftime("%W"))
+ assert_equal("6", T2000.strftime("%w"))
+ assert_equal("01/01/00", T2000.strftime("%x"))
+ assert_equal("00:00:00", T2000.strftime("%X"))
+ assert_equal("00", T2000.strftime("%y"))
+ assert_equal("2000", T2000.strftime("%Y"))
+ assert_equal("UTC", T2000.strftime("%Z"))
+ assert_equal("%", T2000.strftime("%%"))
+
+ assert_equal("", T2000.strftime(""))
+ assert_equal("foo\0bar\x0000\x0000\x0000", T2000.strftime("foo\0bar\0%H\0%M\0%S"))
+ assert_equal("foo" * 1000, T2000.strftime("foo" * 1000))
+
+ assert_equal("Sat", Time.at(946684800).strftime("%a"))
+
+ t = Time.at(946684800, 123456.789)
+ assert_equal("123", t.strftime("%3N"))
+ assert_equal("123456", t.strftime("%6N"))
+ assert_equal("123456789", t.strftime("%9N"))
+ assert_equal("1234567890", t.strftime("%10N"))
+ assert_equal("", t.strftime("%0N"))
+ assert_equal("000", t.strftime("%3S"))
+
+ t = Time.mktime(2001, 10, 1)
+ assert_equal("2001-10-01", t.strftime("%F"))
+ end
+end
diff --git a/trunk/test/ruby/test_trace.rb b/trunk/test/ruby/test_trace.rb
new file mode 100644
index 0000000000..48294c9694
--- /dev/null
+++ b/trunk/test/ruby/test_trace.rb
@@ -0,0 +1,49 @@
+require 'test/unit'
+
+class TestTrace < Test::Unit::TestCase
+ def test_trace
+ $x = 1234
+ $y = 0
+ trace_var :$x, proc{$y = $x}
+ $x = 40414
+ assert_equal($x, $y)
+
+ untrace_var :$x
+ $x = 19660208
+ assert_not_equal($x, $y)
+
+ trace_var :$x, proc{$x *= 2}
+ $x = 5
+ assert_equal(10, $x)
+
+ untrace_var :$x
+ end
+
+ def test_trace_tainted_proc
+ $x = 1234
+ s = proc { $y = :foo }
+ trace_var :$x, s
+ s.taint
+ $x = 42
+ assert_equal(:foo, $y)
+ ensure
+ untrace_var :$x
+ end
+
+ def test_trace_proc_that_raises_exception
+ $x = 1234
+ trace_var :$x, proc { raise }
+ assert_raise(RuntimeError) { $x = 42 }
+ ensure
+ untrace_var :$x
+ end
+
+ def test_trace_string
+ $x = 1234
+ trace_var :$x, "$y = :bar"
+ $x = 42
+ assert_equal(:bar, $y)
+ ensure
+ untrace_var :$x
+ end
+end
diff --git a/trunk/test/ruby/test_transcode.rb b/trunk/test/ruby/test_transcode.rb
new file mode 100644
index 0000000000..fd673a96c0
--- /dev/null
+++ b/trunk/test/ruby/test_transcode.rb
@@ -0,0 +1,398 @@
+# -*- encoding: ASCII-8BIT -*- # make sure this runs in binary mode
+# some of the comments are in UTF-8
+
+require 'test/unit'
+class TestTranscode < Test::Unit::TestCase
+ def setup_really_needed? # trick to create all the necessary encodings
+ all_encodings = [ 'ISO-8859-1', 'ISO-8859-2',
+ 'ISO-8859-3', 'ISO-8859-4',
+ 'ISO-8859-5', 'ISO-8859-6',
+ 'ISO-8859-7', 'ISO-8859-8',
+ 'ISO-8859-9', 'ISO-8859-10',
+ 'ISO-8859-11', 'ISO-8859-13',
+ 'ISO-8859-14', 'ISO-8859-15',
+ 'UTF-16BE'
+ ]
+ all_encodings.each do |enc|
+ 'abc'.encode(enc, 'UTF-8')
+ end
+ end
+
+ def test_errors
+ assert_raise(ArgumentError) { 'abc'.encode }
+ assert_raise(ArgumentError) { 'abc'.encode! }
+ assert_raise(Encoding::NoConverter) { 'abc'.encode('foo', 'bar') }
+ assert_raise(Encoding::NoConverter) { 'abc'.encode!('foo', 'bar') }
+ assert_raise(Encoding::NoConverter) { 'abc'.force_encoding('utf-8').encode('foo') }
+ assert_raise(Encoding::NoConverter) { 'abc'.force_encoding('utf-8').encode!('foo') }
+ assert_raise(Encoding::ConversionUndefined) { "\x80".encode('utf-8','ASCII-8BIT') }
+ assert_raise(Encoding::InvalidByteSequence) { "\x80".encode('utf-8','US-ASCII') }
+ assert_raise(Encoding::ConversionUndefined) { "\xA5".encode('utf-8','iso-8859-3') }
+ end
+
+ def test_arguments
+ assert_equal('abc', 'abc'.force_encoding('utf-8').encode('iso-8859-1'))
+ # check that encoding is kept when no conversion is done
+ assert_equal('abc'.force_encoding('Shift_JIS'), 'abc'.force_encoding('Shift_JIS').encode('Shift_JIS'))
+ assert_equal('abc'.force_encoding('Shift_JIS'), 'abc'.force_encoding('Shift_JIS').encode!('Shift_JIS'))
+ # assert that encoding is correctly set
+ assert_equal("D\u00FCrst".encoding, "D\xFCrst".force_encoding('iso-8859-1').encode('utf-8').encoding)
+ # check that Encoding can be used as parameter
+ assert_equal("D\u00FCrst", "D\xFCrst".encode('utf-8', Encoding.find('ISO-8859-1')))
+ assert_equal("D\u00FCrst", "D\xFCrst".encode(Encoding.find('utf-8'), 'ISO-8859-1'))
+ assert_equal("D\u00FCrst", "D\xFCrst".encode(Encoding.find('utf-8'), Encoding.find('ISO-8859-1')))
+ end
+
+ def test_length
+ assert_equal("\u20AC"*20, ("\xA4"*20).encode('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*20, ("\xA4"*20).encode!('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*2000, ("\xA4"*2000).encode('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*2000, ("\xA4"*2000).encode!('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*200000, ("\xA4"*200000).encode('utf-8', 'iso-8859-15'))
+ assert_equal("\u20AC"*200000, ("\xA4"*200000).encode!('utf-8', 'iso-8859-15'))
+ end
+
+ def check_both_ways(utf8, raw, encoding)
+ assert_equal(utf8.force_encoding('utf-8'), raw.encode('utf-8', encoding))
+ assert_equal(raw.force_encoding(encoding), utf8.encode(encoding, 'utf-8'))
+ end
+
+ def test_encodings
+ check_both_ways("\u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D",
+ "\x82\xdc\x82\xc2\x82\xe0\x82\xc6 \x82\xe4\x82\xab\x82\xd0\x82\xeb", 'shift_jis') # まつもと ゆきひろ
+ check_both_ways("\u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D",
+ "\xa4\xde\xa4\xc4\xa4\xe2\xa4\xc8 \xa4\xe6\xa4\xad\xa4\xd2\xa4\xed", 'euc-jp')
+ check_both_ways("\u677E\u672C\u884C\u5F18", "\x8f\xbc\x96\x7b\x8d\x73\x8d\x4f", 'shift_jis') # 松本行弘
+ check_both_ways("\u677E\u672C\u884C\u5F18", "\xbe\xbe\xcb\xdc\xb9\xd4\xb9\xb0", 'euc-jp')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-1') # Dürst
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-2')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-3')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-4')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-9')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-10')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-13')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-14')
+ check_both_ways("D\u00FCrst", "D\xFCrst", 'iso-8859-15')
+ check_both_ways("r\u00E9sum\u00E9", "r\xE9sum\xE9", 'iso-8859-1') # résumé
+ check_both_ways("\u0065\u006C\u0151\u00ED\u0072\u00E1\u0073", "el\xF5\xEDr\xE1s", 'iso-8859-2') # előírás
+ check_both_ways("\u043F\u0435\u0440\u0435\u0432\u043E\u0434",
+ "\xDF\xD5\xE0\xD5\xD2\xDE\xD4", 'iso-8859-5') # перевод
+ check_both_ways("\u0643\u062A\u0628", "\xE3\xCA\xC8", 'iso-8859-6') # كتب
+ check_both_ways("\u65E5\u8A18", "\x93\xFA\x8BL", 'shift_jis') # 日記
+ check_both_ways("\u65E5\u8A18", "\xC6\xFC\xB5\xAD", 'euc-jp')
+ check_both_ways("\uC560\uC778\uAD6C\uD568\u0020\u6734\uC9C0\uC778",
+ "\xBE\xD6\xC0\xCE\xB1\xB8\xC7\xD4\x20\xDA\xD3\xC1\xF6\xC0\xCE", 'euc-kr') # 애인구함 朴지인
+ check_both_ways("\uC544\uD58F\uD58F\u0020\uB620\uBC29\uD6BD\uB2D8\u0020\uC0AC\uB791\uD716",
+ "\xBE\xC6\xC1\x64\xC1\x64\x20\x8C\x63\xB9\xE6\xC4\x4F\xB4\xD4\x20\xBB\xE7\xB6\xFB\xC5\x42", 'cp949') # 아햏햏 똠방횽님 사랑휖
+ end
+
+ def test_twostep
+ assert_equal("D\xFCrst".force_encoding('iso-8859-2'), "D\xFCrst".encode('iso-8859-2', 'iso-8859-1'))
+ end
+
+ def test_ascii_range
+ encodings = [
+ 'US-ASCII', 'ASCII-8BIT',
+ 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3',
+ 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6',
+ 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9',
+ 'ISO-8859-10', 'ISO-8859-11', 'ISO-8859-13',
+ 'ISO-8859-14', 'ISO-8859-15',
+ 'EUC-JP', 'SHIFT_JIS', 'EUC-KR'
+ ]
+ all_ascii = (0..127).to_a.pack 'C*'
+ encodings.each do |enc|
+ test_start = all_ascii
+ assert_equal(test_start, test_start.encode('UTF-8',enc).encode(enc).force_encoding('ASCII-8BIT'))
+ end
+ end
+
+ def test_all_bytes
+ encodings_8859 = [
+ 'ISO-8859-1', 'ISO-8859-2',
+ #'ISO-8859-3', # not all bytes used
+ 'ISO-8859-4', 'ISO-8859-5',
+ #'ISO-8859-6', # not all bytes used
+ #'ISO-8859-7', # not all bytes used
+ #'ISO-8859-8', # not all bytes used
+ 'ISO-8859-9', 'ISO-8859-10',
+ #'ISO-8859-11', # not all bytes used
+ #'ISO-8859-12', # not available
+ 'ISO-8859-13','ISO-8859-14','ISO-8859-15',
+ #'ISO-8859-16', # not available
+ ]
+ all_bytes = (0..255).to_a.pack 'C*'
+ encodings_8859.each do |enc|
+ test_start = all_bytes
+ assert_equal(test_start, test_start.encode('UTF-8',enc).encode(enc).force_encoding('ASCII-8BIT'))
+ end
+ end
+
+ def check_utf_16_both_ways(utf8, raw)
+ copy = raw.dup
+ 0.step(copy.length-1, 2) { |i| copy[i+1], copy[i] = copy[i], copy[i+1] }
+ check_both_ways(utf8, raw, 'utf-16be')
+ check_both_ways(utf8, copy, 'utf-16le')
+ end
+
+ def test_utf_16
+ check_utf_16_both_ways("abc", "\x00a\x00b\x00c")
+ check_utf_16_both_ways("\u00E9", "\x00\xE9");
+ check_utf_16_both_ways("\u00E9\u0070\u00E9\u0065", "\x00\xE9\x00\x70\x00\xE9\x00\x65") # épée
+ check_utf_16_both_ways("\u677E\u672C\u884C\u5F18", "\x67\x7E\x67\x2C\x88\x4C\x5F\x18") # 松本行弘
+ check_utf_16_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\x97\x52\x5C\x71\x5B\x66\x96\x62\x59\x27\x5B\x66") # 青山学院大学
+ check_utf_16_both_ways("Martin D\u00FCrst", "\x00M\x00a\x00r\x00t\x00i\x00n\x00 \x00D\x00\xFC\x00r\x00s\x00t") # Martin Dürst
+ # BMP
+ check_utf_16_both_ways("\u0000", "\x00\x00")
+ check_utf_16_both_ways("\u007F", "\x00\x7F")
+ check_utf_16_both_ways("\u0080", "\x00\x80")
+ check_utf_16_both_ways("\u0555", "\x05\x55")
+ check_utf_16_both_ways("\u04AA", "\x04\xAA")
+ check_utf_16_both_ways("\u0333", "\x03\x33")
+ check_utf_16_both_ways("\u04CC", "\x04\xCC")
+ check_utf_16_both_ways("\u00F0", "\x00\xF0")
+ check_utf_16_both_ways("\u070F", "\x07\x0F")
+ check_utf_16_both_ways("\u07FF", "\x07\xFF")
+ check_utf_16_both_ways("\u0800", "\x08\x00")
+ check_utf_16_both_ways("\uD7FF", "\xD7\xFF")
+ check_utf_16_both_ways("\uE000", "\xE0\x00")
+ check_utf_16_both_ways("\uFFFF", "\xFF\xFF")
+ check_utf_16_both_ways("\u5555", "\x55\x55")
+ check_utf_16_both_ways("\uAAAA", "\xAA\xAA")
+ check_utf_16_both_ways("\u3333", "\x33\x33")
+ check_utf_16_both_ways("\uCCCC", "\xCC\xCC")
+ check_utf_16_both_ways("\uF0F0", "\xF0\xF0")
+ check_utf_16_both_ways("\u0F0F", "\x0F\x0F")
+ check_utf_16_both_ways("\uFF00", "\xFF\x00")
+ check_utf_16_both_ways("\u00FF", "\x00\xFF")
+ # outer planes
+ check_utf_16_both_ways("\u{10000}", "\xD8\x00\xDC\x00")
+ check_utf_16_both_ways("\u{FFFFF}", "\xDB\xBF\xDF\xFF")
+ check_utf_16_both_ways("\u{100000}", "\xDB\xC0\xDC\x00")
+ check_utf_16_both_ways("\u{10FFFF}", "\xDB\xFF\xDF\xFF")
+ check_utf_16_both_ways("\u{105555}", "\xDB\xD5\xDD\x55")
+ check_utf_16_both_ways("\u{55555}", "\xD9\x15\xDD\x55")
+ check_utf_16_both_ways("\u{AAAAA}", "\xDA\x6A\xDE\xAA")
+ check_utf_16_both_ways("\u{33333}", "\xD8\x8C\xDF\x33")
+ check_utf_16_both_ways("\u{CCCCC}", "\xDA\xF3\xDC\xCC")
+ check_utf_16_both_ways("\u{8F0F0}", "\xD9\xFC\xDC\xF0")
+ check_utf_16_both_ways("\u{F0F0F}", "\xDB\x83\xDF\x0F")
+ check_utf_16_both_ways("\u{8FF00}", "\xD9\xFF\xDF\x00")
+ check_utf_16_both_ways("\u{F00FF}", "\xDB\x80\xDC\xFF")
+ end
+
+ def check_utf_32_both_ways(utf8, raw)
+ copy = raw.dup
+ 0.step(copy.length-1, 4) do |i|
+ copy[i+3], copy[i+2], copy[i+1], copy[i] = copy[i], copy[i+1], copy[i+2], copy[i+3]
+ end
+ check_both_ways(utf8, raw, 'utf-32be')
+ #check_both_ways(utf8, copy, 'utf-32le')
+ end
+
+ def test_utf_32
+ check_utf_32_both_ways("abc", "\x00\x00\x00a\x00\x00\x00b\x00\x00\x00c")
+ check_utf_32_both_ways("\u00E9", "\x00\x00\x00\xE9");
+ check_utf_32_both_ways("\u00E9\u0070\u00E9\u0065",
+ "\x00\x00\x00\xE9\x00\x00\x00\x70\x00\x00\x00\xE9\x00\x00\x00\x65") # épée
+ check_utf_32_both_ways("\u677E\u672C\u884C\u5F18",
+ "\x00\x00\x67\x7E\x00\x00\x67\x2C\x00\x00\x88\x4C\x00\x00\x5F\x18") # 松本行弘
+ check_utf_32_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66",
+ "\x00\x00\x97\x52\x00\x00\x5C\x71\x00\x00\x5B\x66\x00\x00\x96\x62\x00\x00\x59\x27\x00\x00\x5B\x66") # 青山学院大学
+ check_utf_32_both_ways("Martin D\u00FCrst",
+ "\x00\x00\x00M\x00\x00\x00a\x00\x00\x00r\x00\x00\x00t\x00\x00\x00i\x00\x00\x00n\x00\x00\x00 \x00\x00\x00D\x00\x00\x00\xFC\x00\x00\x00r\x00\x00\x00s\x00\x00\x00t") # Martin Dürst
+ # BMP
+ check_utf_32_both_ways("\u0000", "\x00\x00\x00\x00")
+ check_utf_32_both_ways("\u007F", "\x00\x00\x00\x7F")
+ check_utf_32_both_ways("\u0080", "\x00\x00\x00\x80")
+ check_utf_32_both_ways("\u0555", "\x00\x00\x05\x55")
+ check_utf_32_both_ways("\u04AA", "\x00\x00\x04\xAA")
+ check_utf_32_both_ways("\u0333", "\x00\x00\x03\x33")
+ check_utf_32_both_ways("\u04CC", "\x00\x00\x04\xCC")
+ check_utf_32_both_ways("\u00F0", "\x00\x00\x00\xF0")
+ check_utf_32_both_ways("\u070F", "\x00\x00\x07\x0F")
+ check_utf_32_both_ways("\u07FF", "\x00\x00\x07\xFF")
+ check_utf_32_both_ways("\u0800", "\x00\x00\x08\x00")
+ check_utf_32_both_ways("\uD7FF", "\x00\x00\xD7\xFF")
+ check_utf_32_both_ways("\uE000", "\x00\x00\xE0\x00")
+ check_utf_32_both_ways("\uFFFF", "\x00\x00\xFF\xFF")
+ check_utf_32_both_ways("\u5555", "\x00\x00\x55\x55")
+ check_utf_32_both_ways("\uAAAA", "\x00\x00\xAA\xAA")
+ check_utf_32_both_ways("\u3333", "\x00\x00\x33\x33")
+ check_utf_32_both_ways("\uCCCC", "\x00\x00\xCC\xCC")
+ check_utf_32_both_ways("\uF0F0", "\x00\x00\xF0\xF0")
+ check_utf_32_both_ways("\u0F0F", "\x00\x00\x0F\x0F")
+ check_utf_32_both_ways("\uFF00", "\x00\x00\xFF\x00")
+ check_utf_32_both_ways("\u00FF", "\x00\x00\x00\xFF")
+ # outer planes
+ check_utf_32_both_ways("\u{10000}", "\x00\x01\x00\x00")
+ check_utf_32_both_ways("\u{FFFFF}", "\x00\x0F\xFF\xFF")
+ check_utf_32_both_ways("\u{100000}","\x00\x10\x00\x00")
+ check_utf_32_both_ways("\u{10FFFF}","\x00\x10\xFF\xFF")
+ check_utf_32_both_ways("\u{105555}","\x00\x10\x55\x55")
+ check_utf_32_both_ways("\u{55555}", "\x00\x05\x55\x55")
+ check_utf_32_both_ways("\u{AAAAA}", "\x00\x0A\xAA\xAA")
+ check_utf_32_both_ways("\u{33333}", "\x00\x03\x33\x33")
+ check_utf_32_both_ways("\u{CCCCC}", "\x00\x0C\xCC\xCC")
+ check_utf_32_both_ways("\u{8F0F0}", "\x00\x08\xF0\xF0")
+ check_utf_32_both_ways("\u{F0F0F}", "\x00\x0F\x0F\x0F")
+ check_utf_32_both_ways("\u{8FF00}", "\x00\x08\xFF\x00")
+ check_utf_32_both_ways("\u{F00FF}", "\x00\x0F\x00\xFF")
+ end
+
+ def test_invalid_ignore
+ # arguments only
+ assert_nothing_raised { 'abc'.encode('utf-8', invalid: :ignore) }
+ # check handling of UTF-8 ill-formed subsequences
+ assert_equal("\x00\x41\x00\x3E\x00\x42".force_encoding('UTF-16BE'),
+ "\x41\xC2\x3E\x42".encode('UTF-16BE', 'UTF-8', invalid: :ignore))
+ assert_equal("\x00\x41\x00\xF1\x00\x42".force_encoding('UTF-16BE'),
+ "\x41\xC2\xC3\xB1\x42".encode('UTF-16BE', 'UTF-8', invalid: :ignore))
+ assert_equal("\x00\x42".force_encoding('UTF-16BE'),
+ "\xF0\x80\x80\x42".encode('UTF-16BE', 'UTF-8', invalid: :ignore))
+ assert_equal(''.force_encoding('UTF-16BE'),
+ "\x82\xAB".encode('UTF-16BE', 'UTF-8', invalid: :ignore))
+
+ assert_equal("\e$B!!\e(B".force_encoding("ISO-2022-JP"),
+ "\xA1\xA1\xFF".encode("ISO-2022-JP", "EUC-JP", invalid: :ignore))
+ assert_equal("\e$B\x24\x22\x24\x24\e(B".force_encoding("ISO-2022-JP"),
+ "\xA4\xA2\xFF\xA4\xA4".encode("ISO-2022-JP", "EUC-JP", invalid: :ignore))
+ assert_equal("\e$B\x24\x22\x24\x24\e(B".force_encoding("ISO-2022-JP"),
+ "\xA4\xA2\xFF\xFF\xA4\xA4".encode("ISO-2022-JP", "EUC-JP", invalid: :ignore))
+ end
+
+ def test_invalid_replace
+ # arguments only
+ assert_nothing_raised { 'abc'.encode('UTF-8', invalid: :replace) }
+ assert_equal("\xEF\xBF\xBD".force_encoding("UTF-8"),
+ "\x80".encode("UTF-8", "UTF-16BE", invalid: :replace))
+ assert_equal("\xFF\xFD".force_encoding("UTF-16BE"),
+ "\x80".encode("UTF-16BE", "UTF-8", invalid: :replace))
+ assert_equal("\xFD\xFF".force_encoding("UTF-16LE"),
+ "\x80".encode("UTF-16LE", "UTF-8", invalid: :replace))
+ assert_equal("\x00\x00\xFF\xFD".force_encoding("UTF-32BE"),
+ "\x80".encode("UTF-32BE", "UTF-8", invalid: :replace))
+ assert_equal("\xFD\xFF\x00\x00".force_encoding("UTF-32LE"),
+ "\x80".encode("UTF-32LE", "UTF-8", invalid: :replace))
+
+ assert_equal("\uFFFD!",
+ "\xdc\x00\x00!".encode("utf-8", "utf-16be", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\xd8\x00\x00!".encode("utf-8", "utf-16be", :invalid=>:replace))
+
+ assert_equal("\uFFFD!",
+ "\x00\xdc!\x00".encode("utf-8", "utf-16le", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x00\xd8!\x00".encode("utf-8", "utf-16le", :invalid=>:replace))
+
+ assert_equal("\uFFFD!",
+ "\x01\x00\x00\x00\x00\x00\x00!".encode("utf-8", "utf-32be", :invalid=>:replace), "[ruby-dev:35726]")
+ assert_equal("\uFFFD!",
+ "\x00\xff\x00\x00\x00\x00\x00!".encode("utf-8", "utf-32be", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x00\x00\xd8\x00\x00\x00\x00!".encode("utf-8", "utf-32be", :invalid=>:replace))
+
+ assert_equal("\uFFFD!",
+ "\x00\x00\x00\xff!\x00\x00\x00".encode("utf-8", "utf-32le", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x00\x00\xff\x00!\x00\x00\x00".encode("utf-8", "utf-32le", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x00\xd8\x00\x00!\x00\x00\x00".encode("utf-8", "utf-32le", :invalid=>:replace))
+
+ assert_equal("\uFFFD!",
+ "\xff!".encode("utf-8", "euc-jp", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\xa1!".encode("utf-8", "euc-jp", :invalid=>:replace))
+ assert_equal("\uFFFD!",
+ "\x8f\xa1!".encode("utf-8", "euc-jp", :invalid=>:replace))
+
+ assert_equal("?",
+ "\xdc\x00".encode("EUC-JP", "UTF-16BE", :invalid=>:replace), "[ruby-dev:35776]")
+ assert_equal("ab?cd?ef",
+ "\0a\0b\xdc\x00\0c\0d\xdf\x00\0e\0f".encode("EUC-JP", "UTF-16BE", :invalid=>:replace))
+
+ assert_equal("\e$B!!\e(B?".force_encoding("ISO-2022-JP"),
+ "\xA1\xA1\xFF".encode("ISO-2022-JP", "EUC-JP", invalid: :replace))
+ assert_equal("\e$B\x24\x22\e(B?\e$B\x24\x24\e(B".force_encoding("ISO-2022-JP"),
+ "\xA4\xA2\xFF\xA4\xA4".encode("ISO-2022-JP", "EUC-JP", invalid: :replace))
+ assert_equal("\e$B\x24\x22\e(B??\e$B\x24\x24\e(B".force_encoding("ISO-2022-JP"),
+ "\xA4\xA2\xFF\xFF\xA4\xA4".encode("ISO-2022-JP", "EUC-JP", invalid: :replace))
+ end
+
+ def test_undef_replace
+ assert_equal("?", "\u20AC".encode("EUC-JP", :undef=>:replace), "[ruby-dev:35709]")
+ end
+
+ def test_shift_jis
+ check_both_ways("\u3000", "\x81\x40", 'shift_jis') # full-width space
+ check_both_ways("\u00D7", "\x81\x7E", 'shift_jis') # ×
+ check_both_ways("\u00F7", "\x81\x80", 'shift_jis') # ÷
+ check_both_ways("\u25C7", "\x81\x9E", 'shift_jis') # ◇
+ check_both_ways("\u25C6", "\x81\x9F", 'shift_jis') # ◆
+ check_both_ways("\u25EF", "\x81\xFC", 'shift_jis') # ◯
+ check_both_ways("\u6A97", "\x9F\x40", 'shift_jis') # 檗
+ check_both_ways("\u6BEF", "\x9F\x7E", 'shift_jis') # 毯
+ check_both_ways("\u9EBE", "\x9F\x80", 'shift_jis') # 麾
+ check_both_ways("\u6CBE", "\x9F\x9E", 'shift_jis') # 沾
+ check_both_ways("\u6CBA", "\x9F\x9F", 'shift_jis') # 沺
+ check_both_ways("\u6ECC", "\x9F\xFC", 'shift_jis') # 滌
+ check_both_ways("\u6F3E", "\xE0\x40", 'shift_jis') # 漾
+ check_both_ways("\u70DD", "\xE0\x7E", 'shift_jis') # 烝
+ check_both_ways("\u70D9", "\xE0\x80", 'shift_jis') # 烙
+ check_both_ways("\u71FC", "\xE0\x9E", 'shift_jis') # 燼
+ check_both_ways("\u71F9", "\xE0\x9F", 'shift_jis') # 燹
+ check_both_ways("\u73F1", "\xE0\xFC", 'shift_jis') # 珱
+ assert_raise(Encoding::ConversionUndefined) { "\xEF\x40".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xEF\x7E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xEF\x80".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xEF\x9E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xEF\x9F".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xEF\xFC".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xF0\x40".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xF0\x7E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xF0\x80".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xF0\x9E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xF0\x9F".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xF0\xFC".encode("utf-8", 'shift_jis') }
+ check_both_ways("\u9ADC", "\xFC\x40", 'shift_jis') # 髜
+ assert_raise(Encoding::ConversionUndefined) { "\xFC\x7E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xFC\x80".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xFC\x9E".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xFC\x9F".encode("utf-8", 'shift_jis') }
+ assert_raise(Encoding::ConversionUndefined) { "\xFC\xFC".encode("utf-8", 'shift_jis') }
+ check_both_ways("\u677E\u672C\u884C\u5F18", "\x8f\xbc\x96\x7b\x8d\x73\x8d\x4f", 'shift_jis') # 松本行弘
+ check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\x90\xC2\x8E\x52\x8A\x77\x89\x40\x91\xE5\x8A\x77", 'shift_jis') # 青山学院大学
+ check_both_ways("\u795E\u6797\u7FA9\u535A", "\x90\x5F\x97\xD1\x8B\x60\x94\x8E", 'shift_jis') # 神林義博
+ end
+
+ def test_iso_2022_jp
+ assert_raise(Encoding::InvalidByteSequence) { "\x1b(A".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequence) { "\x1b$(A".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequence) { "\x1b$C".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequence) { "\x0e".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequence) { "\x80".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequence) { "\x1b$(Dd!\x1b(B".encode("utf-8", "iso-2022-jp") }
+ assert_raise(Encoding::ConversionUndefined) { "\u9299".encode("iso-2022-jp") }
+ assert_raise(Encoding::ConversionUndefined) { "\uff71\uff72\uff73\uff74\uff75".encode("iso-2022-jp") }
+ assert_raise(Encoding::InvalidByteSequence) { "\x1b(I12345\x1b(B".encode("utf-8", "iso-2022-jp") }
+ assert_equal("\xA1\xA1".force_encoding("euc-jp"),
+ "\e$B!!\e(B".encode("EUC-JP", "ISO-2022-JP"))
+ assert_equal("\e$B!!\e(B".force_encoding("ISO-2022-JP"),
+ "\xA1\xA1".encode("ISO-2022-JP", "EUC-JP"))
+ end
+
+ def test_iso_2022_jp_1
+ # check_both_ways("\u9299", "\x1b$(Dd!\x1b(B", "iso-2022-jp-1") # JIS X 0212 区68 点01 銙
+ end
+
+ def test_unicode_public_review_issue_121 # see http://www.unicode.org/review/pr-121.html
+ # assert_equal("\x00\x61\xFF\xFD\x00\x62".force_encoding('UTF-16BE'),
+ # "\x61\xF1\x80\x80\xE1\x80\xC2\x62".encode('UTF-16BE', 'UTF-8', invalid: :replace)) # option 1
+ assert_equal("\x00\x61\xFF\xFD\xFF\xFD\xFF\xFD\x00\x62".force_encoding('UTF-16BE'),
+ "\x61\xF1\x80\x80\xE1\x80\xC2\x62".encode('UTF-16BE', 'UTF-8', invalid: :replace)) # option 2
+ assert_equal("\x61\x00\xFD\xFF\xFD\xFF\xFD\xFF\x62\x00".force_encoding('UTF-16LE'),
+ "\x61\xF1\x80\x80\xE1\x80\xC2\x62".encode('UTF-16LE', 'UTF-8', invalid: :replace)) # option 2
+ # assert_equal("\x00\x61\xFF\xFD\xFF\xFD\xFF\xFD\xFF\xFD\xFF\xFD\xFF\xFD\x00\x62".force_encoding('UTF-16BE'),
+ # "\x61\xF1\x80\x80\xE1\x80\xC2\x62".encode('UTF-16BE', 'UTF-8', invalid: :replace)) # option 3
+ end
+end
diff --git a/trunk/test/ruby/test_unicode_escape.rb b/trunk/test/ruby/test_unicode_escape.rb
new file mode 100644
index 0000000000..e86489ec5c
--- /dev/null
+++ b/trunk/test/ruby/test_unicode_escape.rb
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+
+require 'test/unit'
+
+class TestUnicodeEscape < Test::Unit::TestCase
+ def test_basic
+ assert_equal('Matz - 松本行弘',
+ "Matz - \u677E\u672C\u884C\u5F18")
+ assert_equal('Matz - まつもと ゆきひろ',
+ "Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D")
+ assert_equal('Matz - まつもと ゆきひろ',
+ "Matz - \u{307E}\u{3064}\u{3082}\u{3068} \u{3086}\u{304D}\u{3072}\u{308D}")
+ assert_equal('Matz - まつもと ゆきひろ',
+ "Matz - \u{307E 3064 3082 3068 20 3086 304D 3072 308D}")
+ assert_equal("Aoyama Gakuin University - \xE9\x9D\x92\xE5\xB1\xB1\xE5\xAD\xA6\xE9\x99\xA2\xE5\xA4\xA7\xE5\xAD\xA6",
+ "Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66")
+ assert_equal('Aoyama Gakuin University - 青山学院大学',
+ "Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66")
+ assert_equal('青山学院大学', "\u9752\u5C71\u5B66\u9662\u5927\u5B66")
+ assert_equal("Martin D\xC3\xBCrst", "Martin D\u00FCrst")
+ assert_equal('Martin Dürst', "Martin D\u00FCrst")
+ assert_equal('ü', "\u00FC")
+ assert_equal("Martin D\xC3\xBCrst", "Martin D\u{FC}rst")
+ assert_equal('Martin Dürst', "Martin D\u{FC}rst")
+ assert_equal('ü', "\u{FC}")
+ assert_equal('ü', %Q|\u{FC}|)
+ assert_equal('ü', %W{\u{FC}}[0])
+
+ # \u escapes in here documents
+ assert_equal('Matz - まつもと ゆきひろ', <<EOS.chop)
+Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D
+EOS
+
+ assert_equal('Matz - まつもと ゆきひろ', <<"EOS".chop)
+Matz - \u{307E 3064 3082 3068} \u{3086 304D 3072 308D}
+EOS
+ assert_not_equal('Matz - まつもと ゆきひろ', <<'EOS'.chop)
+Matz - \u{307E 3064 3082 3068} \u{3086 304D 3072 308D}
+EOS
+
+ # single-quoted things don't expand \u
+ assert_not_equal('ü', '\u{FC}')
+ assert_not_equal('ü', %q|\u{FC}|)
+ assert_not_equal('ü', %w{\u{FC}}[0])
+ assert_equal('\u00fc', "\\" + "u00fc")
+
+ # \u in %x strings
+ assert_match(/^("?)A\1$/, `echo "\u0041"`) #"
+ assert_match(/^("?)A\1$/, %x{echo "\u0041"}) #"
+ assert_match(/^("?)ü\1$/, `echo "\u{FC}"`.force_encoding("utf-8")) #"
+
+ # \u in quoted symbols
+ assert_equal(:A, :"\u0041")
+ assert_equal(:a, :"\u0061")
+ assert_equal(:ま, :ま)
+ assert_equal(:ü, :ü)
+ assert_equal(:"\u{41}", :"\u0041")
+ assert_equal(:ü, :"\u{fc}")
+
+ # the NUL character is not allowed in symbols
+ assert_raise(SyntaxError) { eval %q(:"\u{0}")}
+ assert_raise(SyntaxError) { eval %q(:"\u0000")}
+ assert_raise(SyntaxError) { eval %q(:"\u{fc 0 0041}")}
+ assert_raise(SyntaxError) { eval %q(:"\x00")}
+ assert_raise(SyntaxError) { eval %q(:"\0")}
+ end
+
+ def test_regexp
+
+ # Compare regexps to regexps
+ assert_not_equal(/Yukihiro Matsumoto - 松本行弘/,
+ /Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18/)
+ assert_not_equal(/Yukihiro Matsumoto - 松本行弘/,
+ /Yukihiro Matsumoto - \u{677E 672C 884C 5F18}/)
+ assert_not_equal(/Matz - まつもと ゆきひろ/,
+ /Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D/)
+ assert_not_equal(/Aoyama Gakuin University - 青山学院大学/,
+ /Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66/)
+ assert_not_equal(/青山学院大学/, /\u9752\u5C71\u5B66\u9662\u5927\u5B66/)
+ assert_not_equal(/Martin Dürst/, /Martin D\u00FCrst/)
+ assert_not_equal(/ü/, /\u00FC/)
+ assert_not_equal(/Martin Dürst/, /Martin D\u{FC}rst/)
+ assert_not_equal(/ü/, /\u{FC}/)
+ assert_not_equal(/ü/, %r{\u{FC}})
+ assert_not_equal(/ü/i, %r{\u00FC}i)
+
+ assert_equal('Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18',
+ /Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18/.source)
+ assert_equal('Yukihiro Matsumoto - \u{677E 672C 884C 5F18}',
+ /Yukihiro Matsumoto - \u{677E 672C 884C 5F18}/.source)
+ assert_equal('Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D',
+ /Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D/.source)
+ assert_equal('Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66',
+ /Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66/.source)
+ assert_equal('\u9752\u5C71\u5B66\u9662\u5927\u5B66',
+ /\u9752\u5C71\u5B66\u9662\u5927\u5B66/.source)
+ assert_equal('Martin D\u00FCrst', /Martin D\u00FCrst/.source)
+ assert_equal('\u00FC', /\u00FC/.source)
+ assert_equal('Martin D\u{FC}rst', /Martin D\u{FC}rst/.source)
+ assert_equal('\u{FC}', /\u{FC}/.source)
+ assert_equal('\u{FC}', %r{\u{FC}}.source)
+ assert_equal('\u00FC', %r{\u00FC}i.source)
+
+ # match strings to regexps
+ assert_equal(0, "Yukihiro Matsumoto - 松本行弘" =~ /Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18/)
+ assert_equal(0, "Yukihiro Matsumoto - \u677E\u672C\u884C\u5F18" =~ /Yukihiro Matsumoto - \u677E\u672C\u884C/)
+ assert_equal(0, "Yukihiro Matsumoto - 松本行弘" =~ /Yukihiro Matsumoto - \u{677E 672C 884C 5F18}/)
+ assert_equal(0, %Q{Yukihiro Matsumoto - \u{677E 672C 884C 5F18}} =~ /Yukihiro Matsumoto - \u{677E 672C 884C 5F18}/)
+ assert_equal(0, "Matz - まつもと ゆきひろ" =~ /Matz - \u307E\u3064\u3082\u3068 \u3086\u304D\u3072\u308D/)
+ assert_equal(0, "Aoyama Gakuin University - 青山学院大学" =~ /Aoyama Gakuin University - \u9752\u5C71\u5B66\u9662\u5927\u5B66/)
+ assert_equal(0, "青山学院大学" =~ /\u9752\u5C71\u5B66\u9662\u5927\u5B66/)
+ assert_equal(0, "Martin Dürst" =~ /Martin D\u00FCrst/)
+ assert_equal(0, "ü" =~ /\u00FC/)
+ assert_equal(0, "Martin Dürst" =~ /Martin D\u{FC}rst/)
+ assert_equal(0, "ü" =~ %r{\u{FC}})
+ assert_equal(0, "ü" =~ %r{\u00FC}i)
+
+ # Flip order of the two operands
+ assert_equal(0, /Martin D\u00FCrst/ =~ "Martin Dürst")
+ assert_equal(4, /\u00FC/ =~ "testü")
+ assert_equal(3, /Martin D\u{FC}rst/ =~ "fooMartin Dürstbar")
+ assert_equal(3, %r{\u{FC}} =~ "fooübar")
+
+ # Put \u in strings, literal character in regexp
+ assert_equal(0, "Martin D\u00FCrst" =~ /Martin Dürst/)
+ assert_equal(4, "test\u00FC" =~ /ü/)
+ assert_equal(3, "fooMartin D\u{FC}rstbar" =~ /Martin Dürst/)
+ assert_equal(3, %Q{foo\u{FC}bar} =~ %r<ü>)
+
+ assert_match(eval('/\u{2a}/'), "*")
+ assert_raise(SyntaxError) { eval('/\u{6666}/n') }
+ assert_raise(SyntaxError) { eval('/\u{6666}/e') }
+ assert_raise(SyntaxError) { eval('/\u{6666}/s') }
+ assert_nothing_raised { eval('/\u{6666}/u') }
+ end
+
+ def test_dynamic_regexp
+ assert_match(Regexp.new("Martin D\\u{FC}rst"), "Martin Dürst")
+ end
+
+ def test_syntax_variants
+ # all hex digits
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89AB\uCDEF")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89AB\uCDEF")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89ab\ucdef")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89ab\ucdef")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89aB\uCdEf")
+ assert_equal("\xC4\xA3\xE4\x95\xA7\xE8\xA6\xAB\xEC\xB7\xAF", "\u0123\u4567\u89aB\ucDEF")
+ end
+
+ def test_fulton
+ # examples from Hal Fulton's book (second edition), chapter 4
+ # precomposed e'pe'e
+ assert_equal('épée', "\u00E9\u0070\u00E9\u0065")
+ assert_equal('épée', "\u00E9p\u00E9e")
+ assert_equal("\xC3\xA9\x70\xC3\xA9\x65", "\u00E9\u0070\u00E9\u0065")
+ assert_equal("\xC3\xA9\x70\xC3\xA9\x65", "\u00E9p\u00E9e")
+ # decomposed e'pe'e
+ assert_equal('épée', "\u0065\u0301\u0070\u0065\u0301\u0065")
+ assert_equal('épée', "e\u0301pe\u0301e")
+ assert_equal("\x65\xCC\x81\x70\x65\xCC\x81\x65", "\u0065\u0301\u0070\u0065\u0301\u0065")
+ assert_equal("\x65\xCC\x81\x70\x65\xCC\x81\x65", "e\u0301pe\u0301e")
+ # combinations of NFC/D, NFKC/D
+ assert_equal('öffnen', "\u00F6\u0066\u0066\u006E\u0065\u006E")
+ assert_equal("\xC3\xB6ffnen", "\u00F6\u0066\u0066\u006E\u0065\u006E")
+ assert_equal('öffnen', "\u00F6ffnen")
+ assert_equal("\xC3\xB6ffnen", "\u00F6ffnen")
+ assert_equal('öffnen', "\u006F\u0308\u0066\u0066\u006E\u0065\u006E")
+ assert_equal("\x6F\xCC\x88ffnen", "\u006F\u0308\u0066\u0066\u006E\u0065\u006E")
+ assert_equal('öffnen', "o\u0308ffnen")
+ assert_equal("\x6F\xCC\x88ffnen", "o\u0308ffnen")
+ assert_equal('öffnen', "\u00F6\uFB00\u006E\u0065\u006E")
+ assert_equal("\xC3\xB6\xEF\xAC\x80nen", "\u00F6\uFB00\u006E\u0065\u006E")
+ assert_equal('öffnen', "\u00F6\uFB00nen")
+ assert_equal("\xC3\xB6\xEF\xAC\x80nen", "\u00F6\uFB00nen")
+ assert_equal('öffnen', "\u006F\u0308\uFB00\u006E\u0065\u006E")
+ assert_equal("\x6F\xCC\x88\xEF\xAC\x80nen", "\u006F\u0308\uFB00\u006E\u0065\u006E")
+ assert_equal('öffnen', "o\u0308\uFB00nen")
+ assert_equal("\x6F\xCC\x88\xEF\xAC\x80nen", "o\u0308\uFB00nen")
+ # German sharp s (sz)
+ assert_equal('Straße', "\u0053\u0074\u0072\u0061\u00DF\u0065")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "\u0053\u0074\u0072\u0061\u00DF\u0065")
+ assert_equal('Straße', "Stra\u00DFe")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "Stra\u00DFe")
+ assert_equal('Straße', "\u{53}\u{74}\u{72}\u{61}\u{DF}\u{65}")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "\u{53}\u{74}\u{72}\u{61}\u{DF}\u{65}")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "\u{53 74 72 61 DF 65}")
+ assert_equal('Straße', "Stra\u{DF}e")
+ assert_equal("\x53\x74\x72\x61\xC3\x9F\x65", "Stra\u{DF}e")
+ end
+
+ def test_edge_cases
+ # start and end of each outer plane
+ assert_equal("\xF4\x8F\xBF\xBF", "\u{10FFFF}")
+ assert_equal("\xF4\x80\x80\x80", "\u{100000}")
+ assert_equal("\xF3\xBF\xBF\xBF", "\u{FFFFF}")
+ assert_equal("\xF3\xB0\x80\x80", "\u{F0000}")
+ assert_equal("\xF3\xAF\xBF\xBF", "\u{EFFFF}")
+ assert_equal("\xF3\xA0\x80\x80", "\u{E0000}")
+ assert_equal("\xF3\x9F\xBF\xBF", "\u{DFFFF}")
+ assert_equal("\xF3\x90\x80\x80", "\u{D0000}")
+ assert_equal("\xF3\x8F\xBF\xBF", "\u{CFFFF}")
+ assert_equal("\xF3\x80\x80\x80", "\u{C0000}")
+ assert_equal("\xF2\xBF\xBF\xBF", "\u{BFFFF}")
+ assert_equal("\xF2\xB0\x80\x80", "\u{B0000}")
+ assert_equal("\xF2\xAF\xBF\xBF", "\u{AFFFF}")
+ assert_equal("\xF2\xA0\x80\x80", "\u{A0000}")
+ assert_equal("\xF2\x9F\xBF\xBF", "\u{9FFFF}")
+ assert_equal("\xF2\x90\x80\x80", "\u{90000}")
+ assert_equal("\xF2\x8F\xBF\xBF", "\u{8FFFF}")
+ assert_equal("\xF2\x80\x80\x80", "\u{80000}")
+ assert_equal("\xF1\xBF\xBF\xBF", "\u{7FFFF}")
+ assert_equal("\xF1\xB0\x80\x80", "\u{70000}")
+ assert_equal("\xF1\xAF\xBF\xBF", "\u{6FFFF}")
+ assert_equal("\xF1\xA0\x80\x80", "\u{60000}")
+ assert_equal("\xF1\x9F\xBF\xBF", "\u{5FFFF}")
+ assert_equal("\xF1\x90\x80\x80", "\u{50000}")
+ assert_equal("\xF1\x8F\xBF\xBF", "\u{4FFFF}")
+ assert_equal("\xF1\x80\x80\x80", "\u{40000}")
+ assert_equal("\xF0\xBF\xBF\xBF", "\u{3FFFF}")
+ assert_equal("\xF0\xB0\x80\x80", "\u{30000}")
+ assert_equal("\xF0\xAF\xBF\xBF", "\u{2FFFF}")
+ assert_equal("\xF0\xA0\x80\x80", "\u{20000}")
+ assert_equal("\xF0\x9F\xBF\xBF", "\u{1FFFF}")
+ assert_equal("\xF0\x90\x80\x80", "\u{10000}")
+ # BMP
+ assert_equal("\xEF\xBF\xBF", "\uFFFF")
+ assert_equal("\xEE\x80\x80", "\uE000")
+ assert_equal("\xED\x9F\xBF", "\uD7FF")
+ assert_equal("\xE0\xA0\x80", "\u0800")
+ assert_equal("\xDF\xBF", "\u07FF")
+ assert_equal("\xC2\x80", "\u0080")
+ assert_equal("\x7F", "\u007F")
+ assert_equal("\x00", "\u0000")
+ end
+
+ def test_chars
+ assert_equal(?\u0041, ?A)
+ assert_equal(?\u{79}, ?\x79)
+ assert_equal(?\u{0}, ?\000)
+ assert_equal(?\u0000, ?\000)
+ end
+
+ # Tests to make sure that disallowed cases fail
+ def test_fail
+ assert_raise(SyntaxError) { eval %q("\uabc") } # too short
+ assert_raise(SyntaxError) { eval %q("\uab") } # too short
+ assert_raise(SyntaxError) { eval %q("\ua") } # too short
+ assert_raise(SyntaxError) { eval %q("\u") } # too short
+ assert_raise(SyntaxError) { eval %q("\u{110000}") } # too high
+ assert_raise(SyntaxError) { eval %q("\u{abcdeff}") } # too long
+ assert_raise(SyntaxError) { eval %q("\ughij") } # bad hex digits
+ assert_raise(SyntaxError) { eval %q("\u{ghij}") } # bad hex digits
+
+ assert_raise(SyntaxError) { eval %q("\u{123 456 }")} # extra space
+ assert_raise(SyntaxError) { eval %q("\u{ 123 456}")} # extra space
+ assert_raise(SyntaxError) { eval %q("\u{123 456}")} # extra space
+
+# The utf-8 encoding object currently does not object to codepoints
+# in the surrogate blocks, so these do not raise an error.
+# assert_raise(SyntaxError) { "\uD800" } # surrogate block
+# assert_raise(SyntaxError) { "\uDCBA" } # surrogate block
+# assert_raise(SyntaxError) { "\uDFFF" } # surrogate block
+# assert_raise(SyntaxError) { "\uD847\uDD9A" } # surrogate pair
+
+ end
+end
diff --git a/trunk/test/ruby/test_variable.rb b/trunk/test/ruby/test_variable.rb
new file mode 100644
index 0000000000..53cd151585
--- /dev/null
+++ b/trunk/test/ruby/test_variable.rb
@@ -0,0 +1,83 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestVariable < Test::Unit::TestCase
+ class Gods
+ @@rule = "Uranus"
+ def ruler0
+ @@rule
+ end
+
+ def self.ruler1 # <= per method definition style
+ @@rule
+ end
+ class << self # <= multiple method definition style
+ def ruler2
+ @@rule
+ end
+ end
+ end
+
+ module Olympians
+ @@rule ="Zeus"
+ def ruler3
+ @@rule
+ end
+ end
+
+ class Titans < Gods
+ @@rule = "Cronus" # modifies @@rule in Gods
+ include Olympians
+ def ruler4
+ @@rule
+ end
+ end
+
+ def test_variable
+ assert_instance_of(Fixnum, $$)
+
+ # read-only variable
+ assert_raises(NameError) do
+ $$ = 5
+ end
+
+ foobar = "foobar"
+ $_ = foobar
+ assert_equal(foobar, $_)
+
+ assert_equal("Cronus", Gods.new.ruler0)
+ assert_equal("Cronus", Gods.ruler1)
+ assert_equal("Cronus", Gods.ruler2)
+ assert_equal("Cronus", Titans.ruler1)
+ assert_equal("Cronus", Titans.ruler2)
+ atlas = Titans.new
+ assert_equal("Cronus", atlas.ruler0)
+ assert_equal("Zeus", atlas.ruler3)
+ assert_equal("Cronus", atlas.ruler4)
+ end
+
+ def test_local_variables
+ lvar = 1
+ assert_instance_of(Symbol, local_variables[0], "[ruby-dev:34008]")
+ end
+
+ def test_local_variables2
+ x = 1
+ proc do |y|
+ assert_equal([:x, :y], local_variables.sort)
+ end.call
+ end
+
+ def test_local_variables3
+ x = 1
+ proc do |y|
+ 1.times do |z|
+ assert_equal([:x, :y, :z], local_variables.sort)
+ end
+ end.call
+ end
+
+ def test_global_variable_0
+ assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, [])
+ end
+end
diff --git a/trunk/test/ruby/test_whileuntil.rb b/trunk/test/ruby/test_whileuntil.rb
new file mode 100644
index 0000000000..df5bda450d
--- /dev/null
+++ b/trunk/test/ruby/test_whileuntil.rb
@@ -0,0 +1,82 @@
+require 'test/unit'
+require 'tmpdir'
+
+class TestWhileuntil < Test::Unit::TestCase
+ def test_while
+ Dir.mktmpdir("ruby_while_tmp") {|tmpdir|
+ tmpfilename = "#{tmpdir}/ruby_while_tmp.#{$$}"
+
+ tmp = open(tmpfilename, "w")
+ tmp.print "tvi925\n";
+ tmp.print "tvi920\n";
+ tmp.print "vt100\n";
+ tmp.print "Amiga\n";
+ tmp.print "paper\n";
+ tmp.close
+
+ tmp = open(tmpfilename, "r")
+ assert_instance_of(File, tmp)
+
+ while line = tmp.gets()
+ break if /vt100/ =~ line
+ end
+
+ assert(!tmp.eof?)
+ assert_match(/vt100/, line)
+ tmp.close
+
+ tmp = open(tmpfilename, "r")
+ while line = tmp.gets()
+ next if /vt100/ =~ line
+ assert_no_match(/vt100/, line)
+ end
+ assert(tmp.eof?)
+ assert_no_match(/vt100/, line)
+ tmp.close
+
+ tmp = open(tmpfilename, "r")
+ while line = tmp.gets()
+ lastline = line
+ line = line.gsub(/vt100/, 'VT100')
+ if lastline != line
+ line.gsub!('VT100', 'Vt100')
+ redo
+ end
+ assert_no_match(/vt100/, line)
+ assert_no_match(/VT100/, line)
+ end
+ assert(tmp.eof?)
+ tmp.close
+
+ sum=0
+ for i in 1..10
+ sum += i
+ i -= 1
+ if i > 0
+ redo
+ end
+ end
+ assert_equal(220, sum)
+
+ tmp = open(tmpfilename, "r")
+ while line = tmp.gets()
+ break if 3
+ assert_no_match(/vt100/, line)
+ assert_no_match(/Amiga/, line)
+ assert_no_match(/paper/, line)
+ end
+ tmp.close
+
+ File.unlink tmpfilename or `/bin/rm -f "#{tmpfilename}"`
+ assert(!File.exist?(tmpfilename))
+ }
+ end
+
+ def test_until
+ i = 0
+ until i>4
+ i+=1
+ end
+ assert(i>4)
+ end
+end
diff --git a/trunk/test/ruby/test_yield.rb b/trunk/test/ruby/test_yield.rb
new file mode 100644
index 0000000000..452c17b141
--- /dev/null
+++ b/trunk/test/ruby/test_yield.rb
@@ -0,0 +1,355 @@
+require 'test/unit'
+
+class TestRubyYield < Test::Unit::TestCase
+
+ def test_ary_each
+ ary = [1]
+ ary.each {|a, b, c, d| assert_equal [1,nil,nil,nil], [a,b,c,d] }
+ ary.each {|a, b, c| assert_equal [1,nil,nil], [a,b,c] }
+ ary.each {|a, b| assert_equal [1,nil], [a,b] }
+ ary.each {|a| assert_equal 1, a }
+ end
+
+ def test_hash_each
+ h = {:a => 1}
+ h.each do |k, v|
+ assert_equal :a, k
+ assert_equal 1, v
+ end
+ h.each do |kv|
+ assert_equal [:a, 1], kv
+ end
+ end
+
+ def test_yield_0
+ assert_equal 1, iter0 { 1 }
+ assert_equal 2, iter0 { 2 }
+ end
+
+ def iter0
+ yield
+ end
+
+ def test_yield_1
+ iter1([]) {|a, b| assert_equal [nil,nil], [a, b] }
+ iter1([1]) {|a, b| assert_equal [1,nil], [a, b] }
+ iter1([1, 2]) {|a, b| assert_equal [1,2], [a,b] }
+ iter1([1, 2, 3]) {|a, b| assert_equal [1,2], [a,b] }
+
+ iter1([]) {|a| assert_equal [], a }
+ iter1([1]) {|a| assert_equal [1], a }
+ iter1([1, 2]) {|a| assert_equal [1,2], a }
+ iter1([1, 2, 3]) {|a| assert_equal [1,2,3], a }
+ end
+
+ def iter1(args)
+ yield args
+ end
+
+ def test_yield2
+ def iter2_1() yield 1, *[2, 3] end
+ iter2_1 {|a, b, c| assert_equal [1,2,3], [a,b,c] }
+ def iter2_2() yield 1, *[] end
+ iter2_2 {|a, b, c| assert_equal [1,nil,nil], [a,b,c] }
+ def iter2_3() yield 1, *[2] end
+ iter2_3 {|a, b, c| assert_equal [1,2,nil], [a,b,c] }
+ end
+
+ def test_yield_nested
+ [[1, [2, 3]]].each {|a, (b, c)|
+ assert_equal [1,2,3], [a,b,c]
+ }
+ [[1, [2, 3]]].map {|a, (b, c)|
+ assert_equal [1,2,3], [a,b,c]
+ }
+ end
+
+ def test_with_enum
+ obj = Object
+ def obj.each
+ yield(*[])
+ end
+ obj.each{|*v| assert_equal([], [], '[ruby-dev:32392]')}
+ obj.to_enum.each{|*v| assert_equal([], [], '[ruby-dev:32392]')}
+ end
+end
+
+require_relative 'sentence'
+class TestRubyYieldGen < Test::Unit::TestCase
+ Syntax = {
+ :exp => [["0"],
+ ["nil"],
+ ["false"],
+ ["[]"],
+ ["[",:exps,"]"]],
+ :exps => [[:exp],
+ [:exp,",",:exps]],
+ :opt_block_param => [[],
+ [:block_param_def]],
+ :block_param_def => [['|', '|'],
+ ['|', :block_param, '|']],
+ :block_param => [[:f_arg, ",", :f_rest_arg, :opt_f_block_arg],
+ [:f_arg, ","],
+ [:f_arg, ',', :f_rest_arg, ",", :f_arg, :opt_f_block_arg],
+ [:f_arg, :opt_f_block_arg],
+ [:f_rest_arg, :opt_f_block_arg],
+ [:f_rest_arg, ',', :f_arg, :opt_f_block_arg],
+ [:f_block_arg]],
+ :f_arg => [[:f_arg_item],
+ [:f_arg, ',', :f_arg_item]],
+ :f_rest_arg => [['*', "var"],
+ ['*']],
+ :opt_f_block_arg => [[',', :f_block_arg],
+ []],
+ :f_block_arg => [['&', 'var']],
+ :f_arg_item => [[:f_norm_arg],
+ ['(', :f_margs, ')']],
+ :f_margs => [[:f_marg_list],
+ [:f_marg_list, ',', '*', :f_norm_arg],
+ [:f_marg_list, ',', '*', :f_norm_arg, ',', :f_marg_list],
+ [:f_marg_list, ',', '*'],
+ [:f_marg_list, ',', '*', ',', :f_marg_list],
+ [ '*', :f_norm_arg],
+ [ '*', :f_norm_arg, ',', :f_marg_list],
+ [ '*'],
+ [ '*', ',', :f_marg_list]],
+ :f_marg_list => [[:f_marg],
+ [:f_marg_list, ',', :f_marg]],
+ :f_marg => [[:f_norm_arg],
+ ['(', :f_margs, ')']],
+ :f_norm_arg => [['var']],
+
+ :command_args => [[:open_args]],
+ :open_args => [[' ',:call_args],
+ ['(', ')'],
+ ['(', :call_args2, ')']],
+ :call_args => [[:command],
+ [ :args, :opt_block_arg],
+ [ :assocs, :opt_block_arg],
+ [ :args, ',', :assocs, :opt_block_arg],
+ [ :block_arg]],
+ :call_args2 => [[:arg, ',', :args, :opt_block_arg],
+ [:arg, ',', :block_arg],
+ [ :assocs, :opt_block_arg],
+ [:arg, ',', :assocs, :opt_block_arg],
+ [:arg, ',', :args, ',', :assocs, :opt_block_arg],
+ [ :block_arg]],
+
+ :command_args_noblock => [[:open_args_noblock]],
+ :open_args_noblock => [[' ',:call_args_noblock],
+ ['(', ')'],
+ ['(', :call_args2_noblock, ')']],
+ :call_args_noblock => [[:command],
+ [ :args],
+ [ :assocs],
+ [ :args, ',', :assocs]],
+ :call_args2_noblock => [[:arg, ',', :args],
+ [ :assocs],
+ [:arg, ',', :assocs],
+ [:arg, ',', :args, ',', :assocs]],
+
+ :command => [],
+ :args => [[:arg],
+ ["*",:arg],
+ [:args,",",:arg],
+ [:args,",","*",:arg]],
+ :arg => [[:exp]],
+ :assocs => [[:assoc],
+ [:assocs, ',', :assoc]],
+ :assoc => [[:arg, '=>', :arg],
+ ['label', ':', :arg]],
+ :opt_block_arg => [[',', :block_arg],
+ []],
+ :block_arg => [['&', :arg]],
+ #:test => [['def m() yield', :command_args_noblock, ' end; r = m {', :block_param_def, 'vars', '}; undef m; r']]
+ :test_proc => [['def m() yield', :command_args_noblock, ' end; r = m {', :block_param_def, 'vars', '}; undef m; r']],
+ :test_lambda => [['def m() yield', :command_args_noblock, ' end; r = m(&lambda {', :block_param_def, 'vars', '}); undef m; r']],
+ :test_enum => [['o = Object.new; def o.each() yield', :command_args_noblock, ' end; r1 = r2 = nil; o.each {|*x| r1 = x }; o.to_enum.each {|*x| r2 = x }; [r1, r2]']]
+ }
+
+ def rename_var(obj)
+ vars = []
+ r = obj.subst('var') {
+ var = "v#{vars.length}"
+ vars << var
+ var
+ }
+ return r, vars
+ end
+
+ def split_by_comma(ary)
+ return [] if ary.empty?
+ result = [[]]
+ ary.each {|e|
+ if e == ','
+ result << []
+ else
+ result.last << e
+ end
+ }
+ result
+ end
+
+ def emu_return_args(*vs)
+ vs
+ end
+
+ def emu_eval_args(args)
+ if args.last == []
+ args = args[0...-1]
+ end
+ code = "emu_return_args #{args.map {|a| a.join('') }.join(",")}"
+ eval code
+ end
+
+ def emu_bind_single(arg, param, result_binding)
+ #p [:emu_bind_single, arg, param]
+ if param.length == 1 && String === param[0] && /\A[a-z0-9]+\z/ =~ param[0]
+ result_binding[param[0]] = arg
+ elsif param.length == 1 && Array === param[0] && param[0][0] == '(' && param[0][-1] == ')'
+ arg = [arg] unless Array === arg
+ emu_bind_params(arg, split_by_comma(param[0][1...-1]), false, result_binding)
+ else
+ raise "unexpected param: #{param.inspect}"
+ end
+ result_binding
+ end
+
+ def emu_bind_params(args, params, islambda, result_binding={})
+ #p [:emu_bind_params, args, params]
+ if params.last == [] # extra comma
+ params.pop
+ end
+
+ star_index = nil
+ params.each_with_index {|par, i|
+ star_index = i if par[0] == '*'
+ }
+
+ if islambda
+ if star_index
+ if args.length < params.length - 1
+ throw :emuerror, ArgumentError
+ end
+ else
+ if args.length != params.length
+ throw :emuerror, ArgumentError
+ end
+ end
+ end
+
+ # TRICK #2 : adjust mismatch on number of arguments
+ if star_index
+ pre_params = params[0...star_index]
+ rest_param = params[star_index]
+ post_params = params[(star_index+1)..-1]
+ pre_params.each {|par| emu_bind_single(args.shift, par, result_binding) }
+ if post_params.length <= args.length
+ post_params.reverse_each {|par| emu_bind_single(args.pop, par, result_binding) }
+ else
+ post_params.each {|par| emu_bind_single(args.shift, par, result_binding) }
+ end
+ if rest_param != ['*']
+ emu_bind_single(args, rest_param[1..-1], result_binding)
+ end
+ else
+ params.each_with_index {|par, i|
+ emu_bind_single(args[i], par, result_binding)
+ }
+ end
+
+ #p [args, params, result_binding]
+
+ result_binding
+ end
+
+ def emu_bind(t, islambda)
+ #puts
+ #p t
+ command_args_noblock = t[1]
+ block_param_def = t[3]
+ command_args_noblock = command_args_noblock.expand {|a| !(a[0] == '[' && a[-1] == ']') }
+ block_param_def = block_param_def.expand {|a| !(a[0] == '(' && a[-1] == ')') }
+
+ if command_args_noblock.to_a[0] == ' '
+ args = command_args_noblock.to_a[1..-1]
+ elsif command_args_noblock.to_a[0] == '(' && command_args_noblock.to_a[-1] == ')'
+ args = command_args_noblock.to_a[1...-1]
+ else
+ raise "unexpected command_args_noblock: #{command_args_noblock.inspect}"
+ end
+ args = emu_eval_args(split_by_comma(args))
+
+ params = block_param_def.to_a[1...-1]
+ params = split_by_comma(params)
+
+ #p [:emu0, args, params]
+
+ result_binding = {}
+
+ if params.last && params.last[0] == '&'
+ result_binding[params.last[1]] = nil
+ params.pop
+ end
+
+ if !islambda
+ # TRICK #1 : single array argument is expanded if there are two or more params.
+ # * block parameter is not counted.
+ # * extra comma after single param forces the expansion.
+ if args.length == 1 && Array === args[0] && 1 < params.length
+ args = args[0]
+ end
+ end
+
+ emu_bind_params(args, params, islambda, result_binding)
+ #p result_binding
+ result_binding
+ end
+
+ def emu(t, vars, islambda)
+ catch(:emuerror) {
+ emu_binding = emu_bind(t, islambda)
+ vars.map {|var| emu_binding.fetch(var, "NOVAL") }
+ }
+ end
+
+ def check_nofork(t, islambda=false)
+ t, vars = rename_var(t)
+ t = t.subst('vars') { " [#{vars.join(",")}]" }
+ emu_values = emu(t, vars, islambda)
+ s = t.to_s
+ #print "#{s}\t\t"
+ #STDOUT.flush
+ begin
+ eval_values = eval(s)
+ rescue ArgumentError
+ eval_values = ArgumentError
+ end
+ #success = emu_values == eval_values ? 'succ' : 'fail'
+ #puts "eval:#{vs_ev.inspect[1...-1].delete(' ')}\temu:#{vs_emu.inspect[1...-1].delete(' ')}\t#{success}"
+ assert_equal(emu_values, eval_values, s)
+ end
+
+ def test_yield
+ syntax = Sentence.expand_syntax(Syntax)
+ Sentence.each(syntax, :test_proc, 4) {|t|
+ check_nofork(t)
+ }
+ end
+
+ def test_yield_lambda
+ syntax = Sentence.expand_syntax(Syntax)
+ Sentence.each(syntax, :test_lambda, 4) {|t|
+ check_nofork(t, true)
+ }
+ end
+
+ def test_yield_enum
+ syntax = Sentence.expand_syntax(Syntax)
+ Sentence.each(syntax, :test_enum, 4) {|t|
+ r1, r2 = eval(t.to_s)
+ assert_equal(r1, r2, "#{t}")
+ }
+ end
+
+end
diff --git a/trunk/test/ruby/ut_eof.rb b/trunk/test/ruby/ut_eof.rb
new file mode 100644
index 0000000000..b7219ddb51
--- /dev/null
+++ b/trunk/test/ruby/ut_eof.rb
@@ -0,0 +1,128 @@
+require 'test/unit'
+
+module TestEOF
+ def test_eof_0
+ open_file("") {|f|
+ assert_equal("", f.read(0))
+ assert_equal("", f.read(0))
+ assert_equal("", f.read)
+ assert_equal("", f.read(0))
+ assert_equal("", f.read(0))
+ }
+ open_file("") {|f|
+ assert_nil(f.read(1))
+ assert_equal("", f.read)
+ assert_nil(f.read(1))
+ }
+ open_file("") {|f|
+ s = "x"
+ assert_equal("", f.read(nil, s))
+ assert_equal("", s)
+ }
+ open_file("") {|f|
+ s = "x"
+ assert_nil(f.read(10, s))
+ assert_equal("", s)
+ }
+ end
+
+ def test_eof_0_rw
+ return unless respond_to? :open_file_rw
+ open_file_rw("") {|f|
+ assert_equal("", f.read)
+ assert_equal("", f.read)
+ assert_equal(0, f.syswrite(""))
+ assert_equal("", f.read)
+ }
+ end
+
+ def test_eof_1
+ open_file("a") {|f|
+ assert_equal("", f.read(0))
+ assert_equal("a", f.read(1))
+ assert_equal("" , f.read(0))
+ assert_equal("" , f.read(0))
+ assert_equal("", f.read)
+ assert_equal("", f.read(0))
+ assert_equal("", f.read(0))
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read(1))
+ assert_nil(f.read(1))
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read(2))
+ assert_nil(f.read(1))
+ assert_equal("", f.read)
+ assert_nil(f.read(1))
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read)
+ assert_nil(f.read(1))
+ assert_equal("", f.read)
+ assert_nil(f.read(1))
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read(2))
+ assert_equal("", f.read)
+ assert_equal("", f.read)
+ }
+ open_file("a") {|f|
+ assert_equal("a", f.read)
+ assert_equal("", f.read(0))
+ }
+ open_file("a") {|f|
+ s = "x"
+ assert_equal("a", f.read(nil, s))
+ assert_equal("a", s)
+ }
+ open_file("a") {|f|
+ s = "x"
+ assert_equal("a", f.read(10, s))
+ assert_equal("a", s)
+ }
+ end
+
+ def test_eof_2
+ open_file("") {|f|
+ assert_equal("", f.read)
+ assert(f.eof?)
+ }
+ end
+
+ def test_eof_3
+ open_file("") {|f|
+ assert(f.eof?)
+ }
+ end
+
+ module Seek
+ def open_file_seek(content, pos)
+ open_file(content) do |f|
+ f.seek(pos)
+ yield f
+ end
+ end
+
+ def test_eof_0_seek
+ open_file_seek("", 10) {|f|
+ assert_equal(10, f.pos)
+ assert_equal("", f.read(0))
+ assert_equal("", f.read)
+ assert_equal("", f.read(0))
+ assert_equal("", f.read)
+ }
+ end
+
+ def test_eof_1_seek
+ open_file_seek("a", 10) {|f|
+ assert_equal("", f.read)
+ assert_equal("", f.read)
+ }
+ open_file_seek("a", 1) {|f|
+ assert_equal("", f.read)
+ assert_equal("", f.read)
+ }
+ end
+ end
+end