summaryrefslogtreecommitdiffhomepage
path: root/test/t
diff options
context:
space:
mode:
Diffstat (limited to 'test/t')
-rw-r--r--test/t/array.rb35
-rw-r--r--test/t/class.rb21
-rw-r--r--test/t/codegen.rb93
-rw-r--r--test/t/hash.rb18
-rw-r--r--test/t/kernel.rb38
-rw-r--r--test/t/literals.rb2
-rw-r--r--test/t/module.rb12
-rw-r--r--test/t/nomethoderror.rb49
-rw-r--r--test/t/proc.rb12
-rw-r--r--test/t/range.rb9
-rw-r--r--test/t/string.rb20
-rw-r--r--test/t/syntax.rb20
-rw-r--r--test/t/unicode.rb32
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