diff options
| author | take_cheeze <[email protected]> | 2014-07-10 21:43:07 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-07-12 20:36:45 +0900 |
| commit | 4a6c651f82c2d416682e9729842d4fda6beee2bf (patch) | |
| tree | 890a25f96916c8eea4906f423f8ffcfc9d41f01c | |
| parent | aff65afe97cc241af396ceb8df15bed27788c108 (diff) | |
| download | mruby-4a6c651f82c2d416682e9729842d4fda6beee2bf.tar.gz mruby-4a6c651f82c2d416682e9729842d4fda6beee2bf.zip | |
Run mrbgem and core tests on minimum dependencies.
Solves #2355.
In test drivers:
* Uses `mrb_t_pass_result` to check and pass test result to main `mrb_state`.
* Adds `mrb_init_test_driver` to init test `mrb_state`.
| -rw-r--r-- | mrbgems/mruby-enumerator/mrbgem.rake | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-hash-ext/mrbgem.rake | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-numeric-ext/test/numeric.rb | 9 | ||||
| -rw-r--r-- | tasks/mrbgem_spec.rake | 44 | ||||
| -rw-r--r-- | tasks/mrbgems_test.rake | 95 | ||||
| -rw-r--r-- | test/driver.c | 65 | ||||
| -rw-r--r-- | test/init_mrbtest.c | 13 | ||||
| -rw-r--r-- | test/mrbtest.rake | 11 | ||||
| -rw-r--r-- | test/no_mrb_open_test_dummy.rb | 2 |
9 files changed, 130 insertions, 112 deletions
diff --git a/mrbgems/mruby-enumerator/mrbgem.rake b/mrbgems/mruby-enumerator/mrbgem.rake index abcc54e7a..8757a15ea 100644 --- a/mrbgems/mruby-enumerator/mrbgem.rake +++ b/mrbgems/mruby-enumerator/mrbgem.rake @@ -2,5 +2,6 @@ MRuby::Gem::Specification.new('mruby-enumerator') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.add_dependency('mruby-fiber', :core => 'mruby-fiber') + spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' spec.summary = 'Enumerator class' end diff --git a/mrbgems/mruby-hash-ext/mrbgem.rake b/mrbgems/mruby-hash-ext/mrbgem.rake index e1ce8e767..663de2166 100644 --- a/mrbgems/mruby-hash-ext/mrbgem.rake +++ b/mrbgems/mruby-hash-ext/mrbgem.rake @@ -2,4 +2,6 @@ MRuby::Gem::Specification.new('mruby-hash-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'extensional Hash class' + spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' + spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext' end diff --git a/mrbgems/mruby-numeric-ext/test/numeric.rb b/mrbgems/mruby-numeric-ext/test/numeric.rb index 4d9e83113..96644da69 100644 --- a/mrbgems/mruby-numeric-ext/test/numeric.rb +++ b/mrbgems/mruby-numeric-ext/test/numeric.rb @@ -5,13 +5,8 @@ assert('Integer#chr') do assert_equal("A", 65.chr) assert_equal("B", 0x42.chr) - if "こんにちわ世界".size == 7 then - # UTF-8 gem is configured - assert_raise(RangeError) { 0x110000.chr } - else - # multibyte encoding (not support yet) - assert_raise(RangeError) { 256.chr } - end + # multibyte encoding (not support yet) + assert_raise(RangeError) { 256.chr } end assert('Integer#div') do diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index 2a15a1f46..9e461d42b 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -45,10 +45,6 @@ module MRuby MRuby::Gem.current = self end - def run_test_in_other_mrb_state? - not test_preload.nil? or not test_objs.empty? or not test_args.empty? - end - def setup MRuby::Gem.current = self MRuby::Build::COMMANDS.each do |command| @@ -184,13 +180,15 @@ module MRuby print_gem_comment(f) f.puts %Q[#include <stdlib.h>] f.puts %Q[#include "mruby.h"] - f.puts %Q[#include "mruby/array.h"] f.puts %Q[#include "mruby/irep.h"] - f.puts %Q[#include "mruby/string.h"] f.puts %Q[#include "mruby/variable.h"] f.puts %Q[#include "mruby/hash.h"] unless test_args.empty? end + def test_dependencies + [@name] + end + def version_ok?(req_versions) req_versions.map do |req| cmp, ver = req.split @@ -290,7 +288,7 @@ module MRuby @ary.empty? end - def check(build) + def generate_gem_table gem_table = @ary.reduce({}) { |res,v| res[v.name] = v; res } default_gems = [] @@ -335,9 +333,29 @@ module MRuby fail "Conflicts of gem `#{g.name}` found: #{cfls.join ', '}" unless cfls.empty? end - class << gem_table + gem_table + end + + def tsort_dependencies ary, table, all_dependency_listed = false + unless all_dependency_listed + left = ary.dup + until left.empty? + v = left.pop + table[v].dependencies.each do |dep| + left.push dep[:gem] + ary.push dep[:gem] + end + end + end + + ary.uniq! + table.instance_variable_set :@root_gems, ary + class << table include TSort - alias tsort_each_node each_key + def tsort_each_node &b + @root_gems.each &b + end + def tsort_each_child(n, &b) fetch(n).dependencies.each do |v| b.call v[:gem] @@ -346,10 +364,16 @@ module MRuby end begin - @ary = gem_table.tsort.map { |v| gem_table[v] } + table.tsort.map { |v| table[v] } rescue TSort::Cyclic => e fail "Circular mrbgem dependency found: #{e.message}" end + end + + def check(build) + gem_table = generate_gem_table + + @ary = tsort_dependencies gem_table.keys, gem_table, true each do |g| import_include_paths(g) diff --git a/tasks/mrbgems_test.rake b/tasks/mrbgems_test.rake index 2fdf5f171..9fc9a9d2a 100644 --- a/tasks/mrbgems_test.rake +++ b/tasks/mrbgems_test.rake @@ -1,16 +1,12 @@ MRuby.each_target do - no_mrb_open_test_gem = [] + gem_table = gems.generate_gem_table gems.each do |g| - unless g.run_test_in_other_mrb_state? - no_mrb_open_test_gem << g - next - end - test_rbobj = g.test_rbireps.ext(exts.object) + dep_list = gems.tsort_dependencies g.test_dependencies, gem_table file test_rbobj => g.test_rbireps - file g.test_rbireps => [g.test_rbfiles].flatten + [g.build.mrbcfile, __FILE__] do |t| + file g.test_rbireps => [g.test_rbfiles].flatten + [File.join(g.dir, 'mrbgem.rake'), g.build.mrbcfile, __FILE__, "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"] do |t| open(t.name, 'w') do |f| g.print_gem_test_header(f) test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir| @@ -33,21 +29,32 @@ MRuby.each_target do g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}" end f.puts %Q[void mrb_#{g.funcname}_gem_test(mrb_state *mrb);] unless g.test_objs.empty? + dep_list.each do |d| + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);] + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);] + end + f.puts %Q[void mrb_init_test_driver(mrb_state *mrb);] + f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] unless g.test_rbfiles.empty? f.puts %Q[ mrb_state *mrb2;] if g.test_args.empty? - f.puts %Q[ mrb_value val1, val2, val3, ary1, ary2;] + f.puts %Q[ mrb_value verbose;] else - f.puts %Q[ mrb_value val1, val2, val3, ary1, ary2, test_args_hash;] + f.puts %Q[ mrb_value verbose, test_args_hash;] end f.puts %Q[ int ai;] g.test_rbfiles.count.times do |i| f.puts %Q[ ai = mrb_gc_arena_save(mrb);] - f.puts %Q[ mrb2 = mrb_open();] - f.puts %Q[ val3 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"));] - f.puts %Q[ if (mrb_test(val3)) {] - f.puts %Q[ mrb_gv_set(mrb2, mrb_intern_lit(mrb2, "$mrbtest_verbose"), val3);] + f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] + dep_list.each do |d| + f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] + f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] + end + f.puts %Q[ mrb_init_test_driver(mrb2);] + f.puts %Q[ verbose = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"));] + f.puts %Q[ if (mrb_test(verbose)) {] + f.puts %Q[ mrb_gv_set(mrb2, mrb_intern_lit(mrb2, "$mrbtest_verbose"), verbose);] f.puts %Q[ }] if test_preload.nil? f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] @@ -73,30 +80,9 @@ MRuby.each_target do f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] unless g.test_objs.empty? f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] - f.puts %Q[ if (mrb2->exc) {] - f.puts %Q[ mrb_print_error(mrb2);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] f.puts %Q[ ] - %w(ok_test ko_test kill_test).each do |vname| - f.puts %Q[ val2 = mrb_gv_get(mrb2, mrb_intern_lit(mrb2, "$#{vname}"));] - f.puts %Q[ if (mrb_fixnum_p(val2)) {] - f.puts %Q[ val1 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$#{vname}"));] - f.puts %Q[ mrb_gv_set(mrb, mrb_intern_lit(mrb, "$#{vname}"), mrb_fixnum_value(mrb_fixnum(val1) + mrb_fixnum(val2)));] - f.puts %Q[ }\n] - end - - f.puts %Q[ ary2 = mrb_gv_get(mrb2, mrb_intern_lit(mrb2, "$asserts"));] - f.puts %Q[ if (mrb_test(ary2)) {] - f.puts %Q[ ary1 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$asserts"));] - f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);] - f.puts %Q[ ] - f.puts %Q[ while (mrb_test(val2)) {] - f.puts %Q[ mrb_ary_push(mrb, ary1, mrb_str_new(mrb, RSTRING_PTR(val2), RSTRING_LEN(val2)));] - f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);] - f.puts %Q[ }] - f.puts %Q[ }] + f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] f.puts %Q[ mrb_close(mrb2);] f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] end @@ -104,44 +90,5 @@ MRuby.each_target do f.puts %Q[}] end end - - end - - no_mrb_open_test = "#{build_dir}/test/no_mrb_open_test" - no_mrb_open_test_rbfiles = no_mrb_open_test_gem.reduce([]) { |res, v| - res += v.test_rbfiles - } - if no_mrb_open_test_rbfiles.empty? - no_mrb_open_test_rbfiles << "#{MRUBY_ROOT}/test/no_mrb_open_test_dummy.rb" - end - - no_mrb_open_test_lib = no_mrb_open_test.ext(exts.object) - file no_mrb_open_test_lib => "#{no_mrb_open_test}.c" - file "#{no_mrb_open_test}.c" => no_mrb_open_test_rbfiles + [MRUBY_CONFIG, __FILE__] do |t| - open(t.name, 'w') do |f| - f.puts %Q[/*] - f.puts %Q[ * This file contains a test code for following gems:] - no_mrb_open_test_gem.each { |g| f.puts %Q[ * #{g.name}] } - 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 %Q[\#include "mruby.h"] - f.puts %Q[\#include "mruby/irep.h"] - - f.puts %Q[] - - mrbc.run f, no_mrb_open_test_rbfiles, "no_mrb_open_gem_test_irep" - - f.puts %Q[] - - f.puts %Q[void no_mrb_open_mrbgem_test(mrb_state *mrb) {] - f.puts %Q[ mrb_load_irep(mrb, no_mrb_open_gem_test_irep);] - f.puts %Q[}] - end end end diff --git a/test/driver.c b/test/driver.c index 7fd8ef720..c696262bf 100644 --- a/test/driver.c +++ b/test/driver.c @@ -16,6 +16,7 @@ #include "mruby/compile.h" #include "mruby/string.h" #include "mruby/variable.h" +#include "mruby/array.h" void mrb_init_mrbtest(mrb_state *); @@ -81,12 +82,62 @@ mrb_t_printstr(mrb_state *mrb, mrb_value self) return argv; } +void +mrb_init_test_driver(mrb_state *mrb) +{ + 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)); +} + +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; - struct RClass *krn; - struct RClass *mrbtest; int ret; print_hint(); @@ -103,15 +154,7 @@ main(int argc, char **argv) mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value()); } - 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)); - + mrb_init_test_driver(mrb); mrb_init_mrbtest(mrb); ret = eval_test(mrb); mrb_close(mrb); diff --git a/test/init_mrbtest.c b/test/init_mrbtest.c index 3ce42f661..3a61a6f39 100644 --- a/test/init_mrbtest.c +++ b/test/init_mrbtest.c @@ -6,15 +6,26 @@ 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); +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); - mrb_load_irep(mrb, mrbtest_irep); + + core_test = mrb_open_core(mrb_default_allocf, NULL); + mrb_init_test_driver(core_test); + 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); diff --git a/test/mrbtest.rake b/test/mrbtest.rake index c28cf3577..21afad946 100644 --- a/test/mrbtest.rake +++ b/test/mrbtest.rake @@ -12,11 +12,12 @@ MRuby.each_target do ass_lib = ass_c.ext(exts.object) mrbtest_lib = libfile("#{current_build_dir}/mrbtest") - gem_test_files = gems.select { |g| g.run_test_in_other_mrb_state? }.map { |g| g.test_rbireps.ext(exts.object) } - file mrbtest_lib => [mlib, ass_lib, gems.map(&:test_objs), gem_test_files].flatten do |t| + mrbtest_objs = gems.map do |v| + v.test_objs + [v.test_rbireps.ext(exts.object)] + end + file mrbtest_lib => [mlib, ass_lib] + mrbtest_objs do |t| archiver.run t.name, t.prerequisites end - file mrbtest_lib => "#{build_dir}/test/no_mrb_open_test.c".ext(exts.object) unless build_mrbtest_lib_only? driver_obj = objfile("#{current_build_dir}/driver") @@ -55,16 +56,12 @@ MRuby.each_target do f.puts IO.read(init) mrbc.run f, mrbs, 'mrbtest_irep' gems.each do |g| - next unless g.run_test_in_other_mrb_state? f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] end - f.puts %Q[void no_mrb_open_mrbgem_test(mrb_state *mrb);] f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {] gems.each do |g| - next unless g.run_test_in_other_mrb_state? f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] end - f.puts %Q[ no_mrb_open_mrbgem_test(mrb);] f.puts %Q[}] end end diff --git a/test/no_mrb_open_test_dummy.rb b/test/no_mrb_open_test_dummy.rb deleted file mode 100644 index 5181c0a45..000000000 --- a/test/no_mrb_open_test_dummy.rb +++ /dev/null @@ -1,2 +0,0 @@ -#dummy - |
