diff options
Diffstat (limited to 'test/t')
| -rw-r--r-- | test/t/array.rb | 35 | ||||
| -rw-r--r-- | test/t/class.rb | 21 | ||||
| -rw-r--r-- | test/t/codegen.rb | 93 | ||||
| -rw-r--r-- | test/t/hash.rb | 18 | ||||
| -rw-r--r-- | test/t/kernel.rb | 38 | ||||
| -rw-r--r-- | test/t/literals.rb | 2 | ||||
| -rw-r--r-- | test/t/module.rb | 12 | ||||
| -rw-r--r-- | test/t/nomethoderror.rb | 49 | ||||
| -rw-r--r-- | test/t/proc.rb | 12 | ||||
| -rw-r--r-- | test/t/range.rb | 9 | ||||
| -rw-r--r-- | test/t/string.rb | 20 | ||||
| -rw-r--r-- | test/t/syntax.rb | 20 | ||||
| -rw-r--r-- | test/t/unicode.rb | 32 |
13 files changed, 334 insertions, 27 deletions
diff --git a/test/t/array.rb b/test/t/array.rb index 538ea0c3f..cf7ed4704 100644 --- a/test/t/array.rb +++ b/test/t/array.rb @@ -82,6 +82,14 @@ assert('Array#[]=', '15.2.12.5.5') do a = [1,2,3,4,5] a[2...4] = 6 assert_equal([1,2,6,5], a) + + # passing self (#3274) + a = [1,2,3] + a[1,0] = a + assert_equal([1,1,2,3,2,3], a) + a = [1,2,3] + a[-1,0] = a + assert_equal([1,2,1,2,3,3], a) end assert('Array#clear', '15.2.12.5.6') do @@ -98,6 +106,11 @@ end assert('Array#concat', '15.2.12.5.8') do assert_equal([1,2,3,4], [1, 2].concat([3, 4])) + + # passing self (#3302) + a = [1,2,3] + a.concat(a) + assert_equal([1,2,3,1,2,3], a) end assert('Array#delete_at', '15.2.12.5.9') do @@ -318,7 +331,8 @@ end assert('Array#hash', '15.2.12.5.35') do a = [ 1, 2, 3 ] - assert_true(a.hash.is_a? Integer) + #assert_true(a.hash.is_a? Integer) + assert_true(a.hash.is_a? Integral) # mruby special assert_equal([1,2].hash, [1,2].hash) end @@ -347,3 +361,22 @@ assert("Array (Longish inline array)") do ary.each {|p| h[p.class] += 1} assert_equal({Array=>200}, h) end + +assert("Array#rindex") do + class Sneaky + def ==(*) + $a.clear + $a.replace([1]) + false + end + end + $a = [2, 3, 4, 5, 6, 7, 8, 9, 10, Sneaky.new] + assert_equal 0, $a.rindex(1) +end + +assert('Array#freeze') do + a = [].freeze + assert_raise(RuntimeError) do + a[0] = 1 + end +end diff --git a/test/t/class.rb b/test/t/class.rb index 7bcaaf90d..605b7ec40 100644 --- a/test/t/class.rb +++ b/test/t/class.rb @@ -397,7 +397,28 @@ assert('class variable in module and class << self style class method') do assert_equal("value", ClassVariableInModuleTest.class_variable) end +assert('overriding class variable with a module (#3235)') do + module ModuleWithCVar + @@class_variable = 1 + end + class CVarOverrideTest + @@class_variable = 2 + include ModuleWithCVar + + assert_equal(1, @@class_variable) + end +end + assert('class with non-class/module outer raises TypeError') do assert_raise(TypeError) { class 0::C1; end } assert_raise(TypeError) { class []::C2; end } end + +assert("remove_method doesn't segfault if the passed in argument isn't a symbol") do + klass = Class.new + assert_raise(TypeError) { klass.remove_method nil } + assert_raise(TypeError) { klass.remove_method 123 } + assert_raise(TypeError) { klass.remove_method 1.23 } + assert_raise(NameError) { klass.remove_method "hello" } + assert_raise(TypeError) { klass.remove_method Class.new } +end diff --git a/test/t/codegen.rb b/test/t/codegen.rb new file mode 100644 index 000000000..709902741 --- /dev/null +++ b/test/t/codegen.rb @@ -0,0 +1,93 @@ +## +# Codegen tests + +assert('peephole optimization does not eliminate move whose result is reused') do + assert_raise LocalJumpError do + def method + yield + end + method(&a &&= 0) + end +end + +assert('empty condition in ternary expression parses correctly') do + assert_equal(() ? 1 : 2, 2) +end + +assert('codegen absorbs arguments to redo and retry if they are the argument of a call') do + assert_nothing_raised do + a=*"1", case nil + when 1 + redo | + 1 + end + end + + assert_nothing_raised do + a=*"1", case nil + when 1 + retry | + 1 + end + end +end + +assert('method call with exactly 127 arguments') do + def args_to_ary(*args) + args + end + + assert_equal [0]*127, args_to_ary( + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ) +end + +assert('nested empty heredoc') do + _, a = nil, <<B +#{<<A} +A +B + assert_equal "\n", a +end + +assert('splat in case splat') do + a = *case + when 0 + * = 1 + end + + assert_equal [1], a +end + +assert('undef with 127 or more arguments') do + assert_raise NameError do + undef + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, + a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a + end +end + +assert('next in normal loop with 127 arguments') do + assert_raise NameError do + while true + next A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A + end + end +end + +assert('negate literal register alignment') do + a = *case + when 0 + -0.0 + 2 + end + + assert_equal [2], a +end diff --git a/test/t/hash.rb b/test/t/hash.rb index c8d7a70ef..c63b8c009 100644 --- a/test/t/hash.rb +++ b/test/t/hash.rb @@ -16,6 +16,13 @@ assert('Hash#[]', '15.2.13.4.2') do a = { 'abc' => 'abc' } assert_equal 'abc', a['abc'] + + # Hash#[] should call #default (#3272) + hash = {} + def hash.default(k); self[k] = 1; end + hash[:foo] += 1 + + assert_equal 2, hash[:foo] end assert('Hash#[]=', '15.2.13.4.3') do @@ -37,6 +44,10 @@ assert('Hash#dup') do b = a.dup a['a'] = 2 assert_equal({'a' => 1}, b) + + c = Hash.new { |h, k| h[k] = k.upcase } + d = c.dup + assert_equal("FOO", d["foo"]) end assert('Hash#default', '15.2.13.4.5') do @@ -355,3 +366,10 @@ assert('Hash#rehash') do h.rehash assert_equal("b", h[[:b]]) end + +assert('Hash#freeze') do + h = {}.freeze + assert_raise(RuntimeError) do + h[:a] = 'b' + end +end diff --git a/test/t/kernel.rb b/test/t/kernel.rb index 927166283..aff2dd461 100644 --- a/test/t/kernel.rb +++ b/test/t/kernel.rb @@ -221,6 +221,14 @@ assert('Kernel#dup', '15.3.1.3.9') do assert_false c.respond_to?(:test) end +assert('Kernel#dup class') do + assert_nothing_raised do + Array.dup.new(200) + Range.dup.new(2, 3) + String.dup.new("a"*50) + end +end + # Kernel#eval is provided by mruby-eval mrbgem '15.3.1.3.12' assert('Kernel#extend', '15.3.1.3.13') do @@ -249,6 +257,13 @@ assert('Kernel#extend works on toplevel', '15.3.1.3.13') do assert_true respond_to?(:test_method) end +assert('Kernel#freeze') do + obj = Object.new + assert_equal obj, obj.freeze + assert_equal 0, 0.freeze + assert_equal :a, :a.freeze +end + assert('Kernel#global_variables', '15.3.1.3.14') do assert_equal Array, global_variables.class end @@ -512,6 +527,21 @@ assert('Kernel#to_s', '15.3.1.3.46') do assert_equal to_s.class, String end +assert('Kernel#to_s on primitives') do + begin + Fixnum.alias_method :to_s_, :to_s + Fixnum.remove_method :to_s + + assert_nothing_raised do + # segfaults if mrb_cptr is used + 1.to_s + end + ensure + Fixnum.alias_method :to_s, :to_s_ + Fixnum.remove_method :to_s_ + end +end + assert('Kernel.local_variables', '15.3.1.2.7') do a, b = 0, 1 a += b @@ -519,11 +549,10 @@ assert('Kernel.local_variables', '15.3.1.2.7') do vars = Kernel.local_variables.sort assert_equal [:a, :b, :vars], vars - Proc.new { + assert_equal [:a, :b, :c, :vars], Proc.new { |a, b| c = 2 - vars = Kernel.local_variables.sort - assert_equal [:a, :b, :c, :vars], vars - }.call + Kernel.local_variables.sort + }.call(-1, -2) end assert('Kernel#!=') do @@ -592,4 +621,3 @@ assert('stack extend') do assert_equal 6, recurse(0, 5) end - diff --git a/test/t/literals.rb b/test/t/literals.rb index 5bf6d6e06..51a37c32d 100644 --- a/test/t/literals.rb +++ b/test/t/literals.rb @@ -26,7 +26,7 @@ assert('Literals Numerical', '8.7.6.2') do assert_equal 10000000, 10_000_000 assert_equal 10, 1_0 # integer with exponent - assert_equal 10.0, 1e1, + assert_equal 10.0, 1e1 assert_equal(0.1, 1e-1) assert_equal 10.0, 1e+1 # float with exponent diff --git a/test/t/module.rb b/test/t/module.rb index 4bde20fbe..6b0632414 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -494,6 +494,18 @@ end # Not ISO specified +assert('Module#define_method') do + c = Class.new { + define_method(:m1) { :ok } + define_method(:m2, Proc.new { :ok }) + } + assert_equal c.new.m1, :ok + assert_equal c.new.m2, :ok + assert_raise(TypeError) do + Class.new { define_method(:n1, nil) } + end +end + # @!group prepend assert('Module#prepend') do module M0 diff --git a/test/t/nomethoderror.rb b/test/t/nomethoderror.rb index 5fed79689..35cbdaee9 100644 --- a/test/t/nomethoderror.rb +++ b/test/t/nomethoderror.rb @@ -20,3 +20,52 @@ assert('NoMethodError#args', '15.2.32.2.1') do end end end + +assert('Can still raise when Kernel#method_missing is removed') do + assert_raise(NoMethodError) do + begin + Kernel.alias_method(:old_method_missing, :method_missing) + Kernel.remove_method(:method_missing) + 1.__send__(:foo) + ensure + Kernel.alias_method(:method_missing, :old_method_missing) + Kernel.remove_method(:old_method_missing) + end + end +end + +assert('Can still call super when Kernel#method_missing is removed') do + assert_raise(NoMethodError) do + class A + def foo + super + end + end + begin + Kernel.alias_method(:old_method_missing, :method_missing) + Kernel.remove_method(:method_missing) + A.new.foo + ensure + Kernel.alias_method(:method_missing, :old_method_missing) + Kernel.remove_method(:old_method_missing) + end + end +end + +assert("NoMethodError#new does not return an exception") do + begin + class << NoMethodError + def new(*) + nil + end + end + + assert_raise(TypeError) do + Object.q + end + ensure + class << NoMethodError + remove_method :new + end + end +end diff --git a/test/t/proc.rb b/test/t/proc.rb index 888b7d56a..ef4566e66 100644 --- a/test/t/proc.rb +++ b/test/t/proc.rb @@ -136,6 +136,18 @@ assert('Proc#return_does_not_break_self') do assert_equal c, c.block.call end +assert('call Proc#initialize if defined') do + a = [] + c = Class.new(Proc) do + define_method(:initialize) do + a << :ok + end + end + + assert_kind_of c, c.new{} + assert_equal [:ok], a +end + assert('&obj call to_proc if defined') do pr = Proc.new{} def mock(&b) diff --git a/test/t/range.rb b/test/t/range.rb index 278b26902..5391369de 100644 --- a/test/t/range.rb +++ b/test/t/range.rb @@ -43,10 +43,11 @@ assert('Range#first', '15.2.14.4.7') do end assert('Range#include?', '15.2.14.4.8') do - a = (1..10) + assert_true (1..10).include?(10) + assert_false (1..10).include?(11) - assert_true a.include?(5) - assert_false a.include?(20) + assert_true (1...10).include?(9) + assert_false (1...10).include?(10) end assert('Range#initialize', '15.2.14.4.9') do @@ -57,6 +58,8 @@ assert('Range#initialize', '15.2.14.4.9') do assert_true a.exclude_end? assert_equal (1..10), b assert_false b.exclude_end? + + assert_raise(NameError) { (0..1).send(:initialize, 1, 3) } end assert('Range#last', '15.2.14.4.10') do diff --git a/test/t/string.rb b/test/t/string.rb index fbaada451..20dc49d92 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -251,6 +251,19 @@ assert('String#chomp!', '15.2.10.5.10') do assert_equal 'abc', e end +assert('String#chomp! uses the correct length') do + class A + def to_str + $s.replace("AA") + "A" + end + end + + $s = "AAA" + $s.chomp!(A.new) + assert_equal $s, "A" +end + assert('String#chop', '15.2.10.5.11') do a = ''.chop b = 'abc'.chop @@ -381,8 +394,6 @@ assert('String#hash', '15.2.10.5.20') do end assert('String#include?', '15.2.10.5.21') do - assert_true 'abc'.include?(97) - assert_false 'abc'.include?(100) assert_true 'abc'.include?('a') assert_false 'abc'.include?('d') end @@ -585,10 +596,14 @@ assert('String#to_f', '15.2.10.5.38') do a = ''.to_f b = '123456789'.to_f c = '12345.6789'.to_f + d = '1e-2147483648'.to_f + e = '1e2147483648'.to_f assert_float(0.0, a) assert_float(123456789.0, b) assert_float(12345.6789, c) + assert_float(0, d) + assert_float(Float::INFINITY, e) end assert('String#to_i', '15.2.10.5.39') do @@ -685,4 +700,3 @@ assert('String#freeze') do assert_raise(RuntimeError) { str.upcase! } end - diff --git a/test/t/syntax.rb b/test/t/syntax.rb index 3bc68484b..461f5430b 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -47,6 +47,19 @@ assert('yield', '11.3.5') do end end +assert('redo in a for loop (#3275)') do + sum = 0 + for i in 1..10 + sum += i + i -= 1 + if i > 0 + redo + end + end + + assert_equal 220, sum +end + assert('Abbreviated variable assignment', '11.4.2.3.2') do a ||= 1 b &&= 1 @@ -255,6 +268,13 @@ assert('multiple assignment (nosplat array rhs)') do assert_equal 2, g end +assert('multiple assignment (empty array rhs #3236, #3239)') do + 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] +end + assert('Return values of case statements') do a = [] << case 1 when 3 then 2 diff --git a/test/t/unicode.rb b/test/t/unicode.rb index 7edd65ef2..8622ae08a 100644 --- a/test/t/unicode.rb +++ b/test/t/unicode.rb @@ -2,34 +2,38 @@ assert('bare \u notation test') do # Mininum and maximum one byte characters - assert_equal("\u0000", "\x00") - assert_equal("\u007F", "\x7F") + assert_equal("\x00", "\u0000") + assert_equal("\x7F", "\u007F") # Mininum and maximum two byte characters - assert_equal("\u0080", "\xC2\x80") - assert_equal("\u07FF", "\xDF\xBF") + assert_equal("\xC2\x80", "\u0080") + assert_equal("\xDF\xBF", "\u07FF") # Mininum and maximum three byte characters - assert_equal("\u0800", "\xE0\xA0\x80") - assert_equal("\uFFFF", "\xEF\xBF\xBF") + assert_equal("\xE0\xA0\x80", "\u0800") + assert_equal("\xEF\xBF\xBF", "\uFFFF") # Four byte characters require the \U notation end assert('braced \u notation test') do # Mininum and maximum one byte characters - assert_equal("\u{0000}", "\x00") - assert_equal("\u{007F}", "\x7F") + assert_equal("\x00", "\u{0000}") + assert_equal("\x7F", "\u{007F}") # Mininum and maximum two byte characters - assert_equal("\u{0080}", "\xC2\x80") - assert_equal("\u{07FF}", "\xDF\xBF") + assert_equal("\xC2\x80", "\u{0080}") + assert_equal("\xDF\xBF", "\u{07FF}") # Mininum and maximum three byte characters - assert_equal("\u{0800}", "\xE0\xA0\x80") - assert_equal("\u{FFFF}", "\xEF\xBF\xBF") + assert_equal("\xE0\xA0\x80", "\u{0800}") + assert_equal("\xEF\xBF\xBF", "\u{FFFF}") # Mininum and maximum four byte characters - assert_equal("\u{10000}", "\xF0\x90\x80\x80") - assert_equal("\u{10FFFF}", "\xF4\x8F\xBF\xBF") + assert_equal("\xF0\x90\x80\x80", "\u{10000}") + assert_equal("\xF4\x8F\xBF\xBF", "\u{10FFFF}") +end + +assert('braced multiple \u notation test') do + assert_equal("ABC", "\u{41 42 43}") end |
