summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/README.md7
-rw-r--r--test/bintest.rb2
-rw-r--r--test/driver.c166
-rw-r--r--test/init_mrbtest.c40
-rw-r--r--test/mrbtest.rake69
-rw-r--r--test/t/class.rb5
-rw-r--r--test/t/float.rb22
-rw-r--r--test/t/hash.rb9
-rw-r--r--test/t/integer.rb10
-rw-r--r--test/t/module.rb304
-rw-r--r--test/t/proc.rb8
-rw-r--r--test/t/string.rb89
-rw-r--r--test/t/syntax.rb33
13 files changed, 469 insertions, 295 deletions
diff --git a/test/README.md b/test/README.md
deleted file mode 100644
index fa4b91e3a..000000000
--- a/test/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Running Tests
-=============
-
-To run the tests, execute the following from the project's root directory.
-
- $ make test
-
diff --git a/test/bintest.rb b/test/bintest.rb
index 0ff3341a0..49990abb9 100644
--- a/test/bintest.rb
+++ b/test/bintest.rb
@@ -2,7 +2,7 @@ $:.unshift File.dirname(File.dirname(File.expand_path(__FILE__)))
require 'test/assert.rb'
ARGV.each do |gem|
- Dir["#{gem}/bintest/*.rb"].each do |file|
+ Dir["#{gem}/bintest/**/*.rb"].each do |file|
load file
end
end
diff --git a/test/driver.c b/test/driver.c
deleted file mode 100644
index 7f0633723..000000000
--- a/test/driver.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-** mrbtest - Test for Embeddable Ruby
-**
-** This program runs Ruby test programs in test/t directory
-** against the current mruby implementation.
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mruby.h"
-#include "mruby/proc.h"
-#include "mruby/data.h"
-#include "mruby/compile.h"
-#include "mruby/string.h"
-#include "mruby/variable.h"
-#include "mruby/array.h"
-
-void
-mrb_init_mrbtest(mrb_state *);
-
-/* Print a short remark for the user */
-static void
-print_hint(void)
-{
- printf("mrbtest - Embeddable Ruby Test\n\n");
-}
-
-static int
-check_error(mrb_state *mrb)
-{
- /* Error check */
- /* $ko_test and $kill_test should be 0 */
- mrb_value ko_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$ko_test"));
- mrb_value kill_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$kill_test"));
-
- return mrb_fixnum_p(ko_test) && mrb_fixnum(ko_test) == 0 && mrb_fixnum_p(kill_test) && mrb_fixnum(kill_test) == 0;
-}
-
-static int
-eval_test(mrb_state *mrb)
-{
- /* evaluate the test */
- mrb_funcall(mrb, mrb_top_self(mrb), "report", 0);
- /* did an exception occur? */
- if (mrb->exc) {
- mrb_print_error(mrb);
- mrb->exc = 0;
- return EXIT_FAILURE;
- }
- else if (!check_error(mrb)) {
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
-static void
-t_printstr(mrb_state *mrb, mrb_value obj)
-{
- char *s;
- int len;
-
- if (mrb_string_p(obj)) {
- s = RSTRING_PTR(obj);
- len = RSTRING_LEN(obj);
- fwrite(s, len, 1, stdout);
- }
-}
-
-mrb_value
-mrb_t_printstr(mrb_state *mrb, mrb_value self)
-{
- mrb_value argv;
-
- mrb_get_args(mrb, "o", &argv);
- t_printstr(mrb, argv);
-
- return argv;
-}
-
-void
-mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose)
-{
- struct RClass *krn, *mrbtest;
-
- krn = mrb->kernel_module;
- mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1));
-
- mrbtest = mrb_define_module(mrb, "Mrbtest");
-
- mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX));
- mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN));
- mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT));
-
- if (verbose) {
- mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value());
- }
-}
-
-void
-mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src)
-{
- mrb_value res_src;
-
- if (mrb_src->exc) {
- mrb_print_error(mrb_src);
- exit(EXIT_FAILURE);
- }
-
-#define TEST_COUNT_PASS(name) \
- do { \
- res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$" #name)); \
- if (mrb_fixnum_p(res_src)) { \
- mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name)); \
- mrb_gv_set(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name), mrb_fixnum_value(mrb_fixnum(res_dst) + mrb_fixnum(res_src))); \
- } \
- } while (FALSE) \
-
- TEST_COUNT_PASS(ok_test);
- TEST_COUNT_PASS(ko_test);
- TEST_COUNT_PASS(kill_test);
-
-#undef TEST_COUNT_PASS
-
- res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$asserts"));
-
- if (mrb_array_p(res_src)) {
- mrb_int i;
- mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$asserts"));
- for (i = 0; i < RARRAY_LEN(res_src); ++i) {
- mrb_value val_src = RARRAY_PTR(res_src)[i];
- mrb_ary_push(mrb_dst, res_dst, mrb_str_new(mrb_dst, RSTRING_PTR(val_src), RSTRING_LEN(val_src)));
- }
- }
-}
-
-int
-main(int argc, char **argv)
-{
- mrb_state *mrb;
- int ret;
- mrb_bool verbose = FALSE;
-
- print_hint();
-
- /* new interpreter instance */
- mrb = mrb_open();
- if (mrb == NULL) {
- fprintf(stderr, "Invalid mrb_state, exiting test driver");
- return EXIT_FAILURE;
- }
-
- if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v') {
- printf("verbose mode: enable\n\n");
- verbose = TRUE;
- }
-
- mrb_init_test_driver(mrb, verbose);
- mrb_init_mrbtest(mrb);
- ret = eval_test(mrb);
- mrb_close(mrb);
-
- return ret;
-}
diff --git a/test/init_mrbtest.c b/test/init_mrbtest.c
deleted file mode 100644
index 1e2ba92bd..000000000
--- a/test/init_mrbtest.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <stdlib.h>
-#include "mruby.h"
-#include "mruby/irep.h"
-#include "mruby/variable.h"
-
-extern const uint8_t mrbtest_assert_irep[];
-extern const uint8_t mrbtest_irep[];
-
-void mrbgemtest_init(mrb_state* mrb);
-void mrb_init_test_driver(mrb_state* mrb, mrb_bool verbose);
-void mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src);
-
-void
-mrb_init_mrbtest(mrb_state *mrb)
-{
- mrb_state *core_test;
-
- mrb_load_irep(mrb, mrbtest_assert_irep);
-
- core_test = mrb_open_core(mrb_default_allocf, NULL);
- if (core_test == NULL) {
- fprintf(stderr, "Invalid mrb_state, exiting %s", __FUNCTION__);
- exit(EXIT_FAILURE);
- }
- mrb_init_test_driver(core_test, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));
- mrb_load_irep(core_test, mrbtest_assert_irep);
- mrb_load_irep(core_test, mrbtest_irep);
- mrb_t_pass_result(mrb, core_test);
-
-#ifndef DISABLE_GEMS
- mrbgemtest_init(mrb);
-#endif
-
- if (mrb->exc) {
- mrb_print_error(mrb);
- exit(EXIT_FAILURE);
- }
- mrb_close(core_test);
-}
-
diff --git a/test/mrbtest.rake b/test/mrbtest.rake
deleted file mode 100644
index b9616fe9d..000000000
--- a/test/mrbtest.rake
+++ /dev/null
@@ -1,69 +0,0 @@
-MRuby.each_target do
- current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd)
- relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT)
- current_build_dir = "#{build_dir}/#{relative_from_root}"
-
- exec = exefile("#{current_build_dir}/mrbtest")
- clib = "#{current_build_dir}/mrbtest.c"
- mlib = clib.ext(exts.object)
- mrbs = Dir.glob("#{current_dir}/t/*.rb")
- init = "#{current_dir}/init_mrbtest.c"
- ass_c = "#{current_build_dir}/assert.c"
- ass_lib = ass_c.ext(exts.object)
-
- mrbtest_lib = libfile("#{current_build_dir}/mrbtest")
- mrbtest_objs = [mlib, ass_lib]
- gems.each do |v|
- mrbtest_objs.concat v.test_objs
- end
- file mrbtest_lib => mrbtest_objs do |t|
- archiver.run t.name, t.prerequisites
- end
-
- unless build_mrbtest_lib_only?
- driver_obj = objfile("#{current_build_dir}/driver")
- file exec => [driver_obj, mrbtest_lib, libfile("#{build_dir}/lib/libmruby")] do |t|
- gem_flags = gems.map { |g| g.linker.flags }
- gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries }
- gem_flags_after_libraries = gems.map { |g| g.linker.flags_after_libraries }
- gem_libraries = gems.map { |g| g.linker.libraries }
- gem_library_paths = gems.map { |g| g.linker.library_paths }
- linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries
- end
- end
-
- file ass_lib => ass_c
- file ass_c => ["#{current_dir}/assert.rb", __FILE__] do |t|
- FileUtils.mkdir_p File.dirname t.name
- open(t.name, 'w') do |f|
- mrbc.run f, [t.prerequisites.first], 'mrbtest_assert_irep'
- end
- end
-
- file mlib => clib
- file clib => [mrbcfile, init, __FILE__] + mrbs do |t|
- _pp "GEN", "*.rb", "#{clib.relative_path}"
- FileUtils.mkdir_p File.dirname(clib)
- open(clib, 'w') do |f|
- f.puts %Q[/*]
- f.puts %Q[ * This file contains a list of all]
- f.puts %Q[ * test functions.]
- f.puts %Q[ *]
- f.puts %Q[ * IMPORTANT:]
- f.puts %Q[ * This file was generated!]
- f.puts %Q[ * All manual changes will get lost.]
- f.puts %Q[ */]
- f.puts %Q[]
- f.puts IO.read(init)
- mrbc.run f, mrbs, 'mrbtest_irep'
- gems.each do |g|
- f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);]
- end
- f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {]
- gems.each do |g|
- f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);]
- end
- f.puts %Q[}]
- end
- end
-end
diff --git a/test/t/class.rb b/test/t/class.rb
index d4ecf99d0..720fd37fa 100644
--- a/test/t/class.rb
+++ b/test/t/class.rb
@@ -383,3 +383,8 @@ assert('class variable and class << self style class method') do
assert_equal("value", ClassVariableTest.class_variable)
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
diff --git a/test/t/float.rb b/test/t/float.rb
index d45709173..0aab0b1f2 100644
--- a/test/t/float.rb
+++ b/test/t/float.rb
@@ -178,3 +178,25 @@ assert('Float#nan?') do
assert_false (1.0/0.0).nan?
assert_false (-1.0/0.0).nan?
end
+
+assert('Float#<<') do
+ # Left Shift by one
+ assert_equal 46, 23.0 << 1
+
+ # Left Shift by a negative is Right Shift
+ assert_equal 23, 46.0 << -1
+end
+
+assert('Float#>>') do
+ # Right Shift by one
+ assert_equal 23, 46.0 >> 1
+
+ # Right Shift by a negative is Left Shift
+ assert_equal 46, 23.0 >> -1
+
+ # Don't raise on large Right Shift
+ assert_equal 0, 23.0 >> 128
+
+ # Don't raise on large Right Shift
+ assert_equal -1, -23.0 >> 128
+end
diff --git a/test/t/hash.rb b/test/t/hash.rb
index eee7c7b6a..3196cc97a 100644
--- a/test/t/hash.rb
+++ b/test/t/hash.rb
@@ -342,3 +342,12 @@ assert('Hash#inspect') do
assert_include ret, '"a"=>100'
assert_include ret, '"d"=>400'
end
+
+assert('Hash#rehash') do
+ h = {[:a] => "b"}
+ # hash key modified
+ h.keys[0][0] = :b
+ # h[[:b]] => nil
+ h.rehash
+ assert_equal("b", h[[:b]])
+end
diff --git a/test/t/integer.rb b/test/t/integer.rb
index 6b8cc308d..be3c13db2 100644
--- a/test/t/integer.rb
+++ b/test/t/integer.rb
@@ -147,11 +147,6 @@ assert('Integer#<<', '15.2.8.3.12') do
# Left Shift by a negative is Right Shift
assert_equal 23, 46 << -1
-
- # Raise when shift is too large
- assert_raise(RangeError) do
- 2 << 128
- end
end
assert('Integer#>>', '15.2.8.3.13') do
@@ -165,11 +160,6 @@ assert('Integer#>>', '15.2.8.3.13') do
# Don't raise on large Right Shift
assert_equal 0, 23 >> 128
-
- # Raise when shift is too large
- assert_raise(RangeError) do
- 2 >> -128
- end
end
assert('Integer#ceil', '15.2.8.3.14') do
diff --git a/test/t/module.rb b/test/t/module.rb
index 9852328ce..4bde20fbe 100644
--- a/test/t/module.rb
+++ b/test/t/module.rb
@@ -1,6 +1,26 @@
##
# Module ISO Test
+def labeled_module(name, &block)
+ Module.new do
+ singleton_class.class_eval do
+ define_method(:to_s) { name }
+ alias_method :inspect, :to_s
+ end
+ class_eval(&block) if block
+ end
+end
+
+def labeled_class(name, supklass = Object, &block)
+ Class.new(supklass) do
+ singleton_class.class_eval do
+ define_method(:to_s) { name }
+ alias_method :inspect, :to_s
+ end
+ class_eval(&block) if block
+ end
+end
+
assert('Module', '15.2.2') do
assert_equal Class, Module.class
end
@@ -474,6 +494,286 @@ end
# Not ISO specified
+# @!group prepend
+ assert('Module#prepend') do
+ module M0
+ def m1; [:M0] end
+ end
+ module M1
+ def m1; [:M1, super, :M1] end
+ end
+ module M2
+ def m1; [:M2, super, :M2] end
+ end
+ M3 = Module.new do
+ def m1; [:M3, super, :M3] end
+ end
+ module M4
+ def m1; [:M4, super, :M4] end
+ end
+
+ class P0
+ include M0
+ prepend M1
+ def m1; [:C0, super, :C0] end
+ end
+ class P1 < P0
+ prepend M2, M3
+ include M4
+ def m1; [:C1, super, :C1] end
+ end
+
+ obj = P1.new
+ expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2]
+ assert_equal(expected, obj.m1)
+ end
+
+ # mruby shouldn't be affected by this since there is
+ # no visibility control (yet)
+ assert('Module#prepend public') do
+ assert_nothing_raised('ruby/ruby #8846') do
+ Class.new.prepend(Module.new)
+ end
+ end
+
+ assert('Module#prepend inheritance') do
+ bug6654 = '[ruby-core:45914]'
+ a = labeled_module('a')
+ b = labeled_module('b') { include a }
+ c = labeled_module('c') { prepend b }
+
+ #assert bug6654 do
+ # the Module#< operator should be used here instead, but we don't have it
+ assert_include(c.ancestors, a)
+ assert_include(c.ancestors, b)
+ #end
+
+ bug8357 = '[ruby-core:54736] [Bug #8357]'
+ b = labeled_module('b') { prepend a }
+ c = labeled_class('c') { include b }
+
+ #assert bug8357 do
+ # the Module#< operator should be used here instead, but we don't have it
+ assert_include(c.ancestors, a)
+ assert_include(c.ancestors, b)
+ #end
+
+ bug8357 = '[ruby-core:54742] [Bug #8357]'
+ assert_kind_of(b, c.new, bug8357)
+ end
+
+ assert('Moduler#prepend + #instance_methods') do
+ bug6655 = '[ruby-core:45915]'
+ assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655)
+ end
+
+ assert 'Module#prepend + #singleton_methods' do
+ o = Object.new
+ o.singleton_class.class_eval {prepend Module.new}
+ assert_equal([], o.singleton_methods)
+ end
+
+ assert 'Module#prepend + #remove_method' do
+ c = Class.new do
+ prepend Module.new { def foo; end }
+ end
+ assert_raise(NameError) do
+ c.class_eval do
+ remove_method(:foo)
+ end
+ end
+ c.class_eval do
+ def foo; end
+ end
+ removed = nil
+ c.singleton_class.class_eval do
+ define_method(:method_removed) {|id| removed = id}
+ end
+ assert_nothing_raised(NoMethodError, NameError, '[Bug #7843]') do
+ c.class_eval do
+ remove_method(:foo)
+ end
+ end
+ assert_equal(:foo, removed)
+ end
+
+ assert 'Module#prepend + Class#ancestors' do
+ bug6658 = '[ruby-core:45919]'
+ m = labeled_module("m")
+ c = labeled_class("c") {prepend m}
+ assert_equal([m, c], c.ancestors[0, 2], bug6658)
+
+ bug6662 = '[ruby-dev:45868]'
+ c2 = labeled_class("c2", c)
+ anc = c2.ancestors
+ assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662)
+ end
+
+ assert 'Module#prepend + Module#ancestors' do
+ bug6659 = '[ruby-dev:45861]'
+ m0 = labeled_module("m0") { def x; [:m0, *super] end }
+ m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 }
+ m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 }
+ c0 = labeled_class("c0") { def x; [:c0] end }
+ c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 }
+ c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 }
+ #
+ assert_equal([m0, m1], m1.ancestors, bug6659)
+ #
+ bug6662 = '[ruby-dev:45868]'
+ assert_equal([m0, m1, m2], m2.ancestors, bug6662)
+ assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662)
+ assert_equal([:m0, :m1, :m2, :c1], c1.new.x)
+ assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662)
+ assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x)
+ #
+ m3 = labeled_module("m3") { include m1; prepend m1 }
+ assert_equal([m3, m0, m1], m3.ancestors)
+ m3 = labeled_module("m3") { prepend m1; include m1 }
+ assert_equal([m0, m1, m3], m3.ancestors)
+ m3 = labeled_module("m3") { prepend m1; prepend m1 }
+ assert_equal([m0, m1, m3], m3.ancestors)
+ m3 = labeled_module("m3") { include m1; include m1 }
+ assert_equal([m3, m0, m1], m3.ancestors)
+ end
+
+ assert 'Module#prepend #instance_methods(false)' do
+ bug6660 = '[ruby-dev:45863]'
+ assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
+ assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
+ end
+
+ assert 'cyclic Module#prepend' do
+ bug7841 = '[ruby-core:52205] [Bug #7841]'
+ m1 = Module.new
+ m2 = Module.new
+ m1.instance_eval { prepend(m2) }
+ assert_raise(ArgumentError, bug7841) do
+ m2.instance_eval { prepend(m1) }
+ end
+ end
+
+ # these assertions will not run without a #assert_seperately method
+ #assert 'test_prepend_optmethod' do
+ # bug7983 = '[ruby-dev:47124] [Bug #7983]'
+ # assert_separately [], %{
+ # module M
+ # def /(other)
+ # to_f / other
+ # end
+ # end
+ # Fixnum.send(:prepend, M)
+ # assert_equal(0.5, 1 / 2, "#{bug7983}")
+ # }
+ # assert_equal(0, 1 / 2)
+ #end
+
+ # mruby has no visibility control
+ assert 'Module#prepend visibility' do
+ bug8005 = '[ruby-core:53106] [Bug #8005]'
+ c = Class.new do
+ prepend Module.new {}
+ def foo() end
+ protected :foo
+ end
+ a = c.new
+ assert_true a.respond_to?(:foo), bug8005
+ assert_nothing_raised(NoMethodError, bug8005) {a.send :foo}
+ end
+
+ # mruby has no visibility control
+ assert 'Module#prepend inherited visibility' do
+ bug8238 = '[ruby-core:54105] [Bug #8238]'
+ module Test4PrependVisibilityInherited
+ class A
+ def foo() A; end
+ private :foo
+ end
+ class B < A
+ public :foo
+ prepend Module.new
+ end
+ end
+ assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}")
+ end
+
+ assert 'Module#prepend + #included_modules' do
+ bug8025 = '[ruby-core:53158] [Bug #8025]'
+ mixin = labeled_module("mixin")
+ c = labeled_module("c") {prepend mixin}
+ im = c.included_modules
+ assert_not_include(im, c, bug8025)
+ assert_include(im, mixin, bug8025)
+ c1 = labeled_class("c1") {prepend mixin}
+ c2 = labeled_class("c2", c1)
+ im = c2.included_modules
+ assert_not_include(im, c1, bug8025)
+ assert_not_include(im, c2, bug8025)
+ assert_include(im, mixin, bug8025)
+ end
+
+ assert 'Module#prepend super in alias' do
+ skip "super does not currently work in aliased methods"
+ bug7842 = '[Bug #7842]'
+
+ p = labeled_module("P") do
+ def m; "P"+super; end
+ end
+
+ a = labeled_class("A") do
+ def m; "A"; end
+ end
+
+ b = labeled_class("B", a) do
+ def m; "B"+super; end
+ alias m2 m
+ prepend p
+ alias m3 m
+ end
+
+ assert_nothing_raised do
+ assert_equal("BA", b.new.m2, bug7842)
+ end
+
+ assert_nothing_raised do
+ assert_equal("PBA", b.new.m3, bug7842)
+ end
+ end
+
+ assert 'Module#prepend each class' do
+ m = labeled_module("M")
+ c1 = labeled_class("C1") {prepend m}
+ c2 = labeled_class("C2", c1) {prepend m}
+ assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each class")
+ end
+
+ assert 'Module#prepend no duplication' do
+ m = labeled_module("M")
+ c = labeled_class("C") {prepend m; prepend m}
+ assert_equal([m, c], c.ancestors[0, 2], "should never duplicate")
+ end
+
+ assert 'Module#prepend in superclass' do
+ m = labeled_module("M")
+ c1 = labeled_class("C1")
+ c2 = labeled_class("C2", c1) {prepend m}
+ c1.class_eval {prepend m}
+ assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should accesisble prepended module in superclass")
+ end
+
+ # requires #assert_seperately
+ #assert 'Module#prepend call super' do
+ # assert_separately([], <<-'end;') #do
+ # bug10847 = '[ruby-core:68093] [Bug #10847]'
+ # module M; end
+ # Float.prepend M
+ # assert_nothing_raised(SystemStackError, bug10847) do
+ # 0.3.numerator
+ # end
+ # end;
+ #end
+# @!endgroup prepend
+
assert('Module#to_s') do
module Test4to_sModules
end
@@ -533,3 +833,7 @@ assert('Module#module_function') do
assert_true M.respond_to?(:modfunc)
end
+assert('module with non-class/module outer raises TypeError') do
+ assert_raise(TypeError) { module 0::M1 end }
+ assert_raise(TypeError) { module []::M2 end }
+end
diff --git a/test/t/proc.rb b/test/t/proc.rb
index 22ccceb68..888b7d56a 100644
--- a/test/t/proc.rb
+++ b/test/t/proc.rb
@@ -36,6 +36,14 @@ assert('Proc#arity', '15.2.17.4.2') do
assert_equal(-3, b)
assert_equal 1, c
assert_equal 1, d
+
+ e = ->(x=0, y){}.arity
+ f = ->((x, y), z=0){}.arity
+ g = ->(x=0){}.arity
+
+ assert_equal(-2, e)
+ assert_equal(-2, f)
+ assert_equal(-1, g)
end
assert('Proc#call', '15.2.17.4.3') do
diff --git a/test/t/string.rb b/test/t/string.rb
index 63e4af000..87aec0e21 100644
--- a/test/t/string.rb
+++ b/test/t/string.rb
@@ -122,6 +122,69 @@ assert('String#[] with Range') do
assert_equal 'bc', j2
end
+assert('String#[]=') do
+ # length of args is 1
+ a = 'abc'
+ a[0] = 'X'
+ assert_equal 'Xbc', a
+
+ b = 'abc'
+ b[-1] = 'X'
+ assert_equal 'abX', b
+
+ c = 'abc'
+ assert_raise(IndexError) do
+ c[10] = 'X'
+ end
+
+ d = 'abc'
+ assert_raise(IndexError) do
+ d[-10] = 'X'
+ end
+
+ e = 'abc'
+ e[1.1] = 'X'
+ assert_equal 'aXc', e
+
+
+ # length of args is 2
+ a1 = 'abc'
+ assert_raise(IndexError) do
+ a1[0, -1] = 'X'
+ end
+
+ b1 = 'abc'
+ assert_raise(IndexError) do
+ b1[10, 0] = 'X'
+ end
+
+ c1 = 'abc'
+ assert_raise(IndexError) do
+ c1[-10, 0] = 'X'
+ end
+
+ d1 = 'abc'
+ d1[0, 0] = 'X'
+ assert_equal 'Xabc', d1
+
+ e1 = 'abc'
+ e1[1, 3] = 'X'
+ assert_equal 'aX', e1
+
+ # args is RegExp
+ # It will be tested in mrbgems.
+
+ # args is String
+ a3 = 'abc'
+ a3['bc'] = 'X'
+ assert_equal a3, 'aX'
+
+ b3 = 'abc'
+ assert_raise(IndexError) do
+ b3['XX'] = 'Y'
+ end
+end
+
assert('String#capitalize', '15.2.10.5.7') do
a = 'abc'
a.capitalize
@@ -254,6 +317,15 @@ assert('String#gsub', '15.2.10.5.18') do
assert_equal('A', 'a'.gsub('a'){|w| w.capitalize })
end
+assert('String#gsub with backslash') do
+ s = 'abXcdXef'
+ assert_equal 'ab<\\>cd<\\>ef', s.gsub('X', '<\\\\>')
+ assert_equal 'ab<X>cd<X>ef', s.gsub('X', '<\\&>')
+ assert_equal 'ab<X>cd<X>ef', s.gsub('X', '<\\0>')
+ assert_equal 'ab<ab>cd<abXcd>ef', s.gsub('X', '<\\`>')
+ assert_equal 'ab<cdXef>cd<ef>ef', s.gsub('X', '<\\\'>')
+end
+
assert('String#gsub!', '15.2.10.5.19') do
a = 'abcabc'
a.gsub!('b', 'B')
@@ -416,6 +488,15 @@ assert('String#sub', '15.2.10.5.36') do
assert_equal 'aa$', 'aa#'.sub('#', '$')
end
+assert('String#sub with backslash') do
+ s = 'abXcdXef'
+ assert_equal 'ab<\\>cdXef', s.sub('X', '<\\\\>')
+ assert_equal 'ab<X>cdXef', s.sub('X', '<\\&>')
+ assert_equal 'ab<X>cdXef', s.sub('X', '<\\0>')
+ assert_equal 'ab<ab>cdXef', s.sub('X', '<\\`>')
+ assert_equal 'ab<cdXef>cdXef', s.sub('X', '<\\\'>')
+end
+
assert('String#sub!', '15.2.10.5.37') do
a = 'abcabc'
a.sub!('b', 'B')
@@ -524,3 +605,11 @@ assert('String#each_byte') do
assert_equal bytes1, bytes2
end
+
+assert('String#freeze') do
+ str = "hello"
+ str.freeze
+
+ assert_raise(RuntimeError) { str.upcase! }
+end
+
diff --git a/test/t/syntax.rb b/test/t/syntax.rb
index 5ce4e0a63..fb6ffe408 100644
--- a/test/t/syntax.rb
+++ b/test/t/syntax.rb
@@ -1,6 +1,6 @@
assert('__FILE__') do
- file = __FILE__
- assert_true 'test/t/syntax.rb' == file || 'test\t\syntax.rb' == file
+ file = __FILE__.split('test/')[1]
+ assert_true 't/syntax.rb' == file || 't\syntax.rb' == file
end
assert('__LINE__') do
@@ -219,6 +219,35 @@ assert('Splat without assignment') do
assert_equal 1, a
end
+assert('multiple assignment (rest)') do
+ *a = 0
+ assert_equal [0], a
+end
+
+assert('multiple assignment (rest+post)') do
+ *a, b = 0, 1, 2
+ *c, d = 3
+
+ assert_equal [0, 1], a
+ assert_equal 2, b
+ assert_equal [], c
+ assert_equal 3, d
+end
+
+assert('multiple assignment (nosplat array rhs)') do
+ a, *b = []
+ *c, d = [0]
+ e, *f, g = [1, 2]
+
+ assert_nil a
+ assert_equal [], b
+ assert_equal [], c
+ assert_equal 0, d
+ assert_equal 1, e
+ assert_equal [], f
+ assert_equal 2, g
+end
+
assert('Return values of case statements') do
a = [] << case 1
when 3 then 2