mrubyを超漢字で動作させる
Revisão | 4a6c651f82c2d416682e9729842d4fda6beee2bf (tree) |
---|---|
Hora | 2014-07-12 20:36:45 |
Autor | take_cheeze <takechi101010@gmai...> |
Commiter | Yukihiro "Matz" Matsumoto |
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.
@@ -2,5 +2,6 @@ MRuby::Gem::Specification.new('mruby-enumerator') do |spec| | ||
2 | 2 | spec.license = 'MIT' |
3 | 3 | spec.author = 'mruby developers' |
4 | 4 | spec.add_dependency('mruby-fiber', :core => 'mruby-fiber') |
5 | + spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' | |
5 | 6 | spec.summary = 'Enumerator class' |
6 | 7 | end |
@@ -2,4 +2,6 @@ MRuby::Gem::Specification.new('mruby-hash-ext') do |spec| | ||
2 | 2 | spec.license = 'MIT' |
3 | 3 | spec.author = 'mruby developers' |
4 | 4 | spec.summary = 'extensional Hash class' |
5 | + spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' | |
6 | + spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext' | |
5 | 7 | end |
@@ -5,13 +5,8 @@ assert('Integer#chr') do | ||
5 | 5 | assert_equal("A", 65.chr) |
6 | 6 | assert_equal("B", 0x42.chr) |
7 | 7 | |
8 | - if "こんにちわ世界".size == 7 then | |
9 | - # UTF-8 gem is configured | |
10 | - assert_raise(RangeError) { 0x110000.chr } | |
11 | - else | |
12 | - # multibyte encoding (not support yet) | |
13 | - assert_raise(RangeError) { 256.chr } | |
14 | - end | |
8 | + # multibyte encoding (not support yet) | |
9 | + assert_raise(RangeError) { 256.chr } | |
15 | 10 | end |
16 | 11 | |
17 | 12 | assert('Integer#div') do |
@@ -45,10 +45,6 @@ module MRuby | ||
45 | 45 | MRuby::Gem.current = self |
46 | 46 | end |
47 | 47 | |
48 | - def run_test_in_other_mrb_state? | |
49 | - not test_preload.nil? or not test_objs.empty? or not test_args.empty? | |
50 | - end | |
51 | - | |
52 | 48 | def setup |
53 | 49 | MRuby::Gem.current = self |
54 | 50 | MRuby::Build::COMMANDS.each do |command| |
@@ -184,13 +180,15 @@ module MRuby | ||
184 | 180 | print_gem_comment(f) |
185 | 181 | f.puts %Q[#include <stdlib.h>] |
186 | 182 | f.puts %Q[#include "mruby.h"] |
187 | - f.puts %Q[#include "mruby/array.h"] | |
188 | 183 | f.puts %Q[#include "mruby/irep.h"] |
189 | - f.puts %Q[#include "mruby/string.h"] | |
190 | 184 | f.puts %Q[#include "mruby/variable.h"] |
191 | 185 | f.puts %Q[#include "mruby/hash.h"] unless test_args.empty? |
192 | 186 | end |
193 | 187 | |
188 | + def test_dependencies | |
189 | + [@name] | |
190 | + end | |
191 | + | |
194 | 192 | def version_ok?(req_versions) |
195 | 193 | req_versions.map do |req| |
196 | 194 | cmp, ver = req.split |
@@ -290,7 +288,7 @@ module MRuby | ||
290 | 288 | @ary.empty? |
291 | 289 | end |
292 | 290 | |
293 | - def check(build) | |
291 | + def generate_gem_table | |
294 | 292 | gem_table = @ary.reduce({}) { |res,v| res[v.name] = v; res } |
295 | 293 | |
296 | 294 | default_gems = [] |
@@ -335,9 +333,29 @@ module MRuby | ||
335 | 333 | fail "Conflicts of gem `#{g.name}` found: #{cfls.join ', '}" unless cfls.empty? |
336 | 334 | end |
337 | 335 | |
338 | - class << gem_table | |
336 | + gem_table | |
337 | + end | |
338 | + | |
339 | + def tsort_dependencies ary, table, all_dependency_listed = false | |
340 | + unless all_dependency_listed | |
341 | + left = ary.dup | |
342 | + until left.empty? | |
343 | + v = left.pop | |
344 | + table[v].dependencies.each do |dep| | |
345 | + left.push dep[:gem] | |
346 | + ary.push dep[:gem] | |
347 | + end | |
348 | + end | |
349 | + end | |
350 | + | |
351 | + ary.uniq! | |
352 | + table.instance_variable_set :@root_gems, ary | |
353 | + class << table | |
339 | 354 | include TSort |
340 | - alias tsort_each_node each_key | |
355 | + def tsort_each_node &b | |
356 | + @root_gems.each &b | |
357 | + end | |
358 | + | |
341 | 359 | def tsort_each_child(n, &b) |
342 | 360 | fetch(n).dependencies.each do |v| |
343 | 361 | b.call v[:gem] |
@@ -346,10 +364,16 @@ module MRuby | ||
346 | 364 | end |
347 | 365 | |
348 | 366 | begin |
349 | - @ary = gem_table.tsort.map { |v| gem_table[v] } | |
367 | + table.tsort.map { |v| table[v] } | |
350 | 368 | rescue TSort::Cyclic => e |
351 | 369 | fail "Circular mrbgem dependency found: #{e.message}" |
352 | 370 | end |
371 | + end | |
372 | + | |
373 | + def check(build) | |
374 | + gem_table = generate_gem_table | |
375 | + | |
376 | + @ary = tsort_dependencies gem_table.keys, gem_table, true | |
353 | 377 | |
354 | 378 | each do |g| |
355 | 379 | import_include_paths(g) |
@@ -1,16 +1,12 @@ | ||
1 | 1 | MRuby.each_target do |
2 | - no_mrb_open_test_gem = [] | |
2 | + gem_table = gems.generate_gem_table | |
3 | 3 | |
4 | 4 | gems.each do |g| |
5 | - unless g.run_test_in_other_mrb_state? | |
6 | - no_mrb_open_test_gem << g | |
7 | - next | |
8 | - end | |
9 | - | |
10 | 5 | test_rbobj = g.test_rbireps.ext(exts.object) |
6 | + dep_list = gems.tsort_dependencies g.test_dependencies, gem_table | |
11 | 7 | |
12 | 8 | file test_rbobj => g.test_rbireps |
13 | - file g.test_rbireps => [g.test_rbfiles].flatten + [g.build.mrbcfile, __FILE__] do |t| | |
9 | + 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| | |
14 | 10 | open(t.name, 'w') do |f| |
15 | 11 | g.print_gem_test_header(f) |
16 | 12 | test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir| |
@@ -33,21 +29,32 @@ MRuby.each_target do | ||
33 | 29 | g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}" |
34 | 30 | end |
35 | 31 | f.puts %Q[void mrb_#{g.funcname}_gem_test(mrb_state *mrb);] unless g.test_objs.empty? |
32 | + dep_list.each do |d| | |
33 | + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);] | |
34 | + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);] | |
35 | + end | |
36 | + f.puts %Q[void mrb_init_test_driver(mrb_state *mrb);] | |
37 | + f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] | |
36 | 38 | f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] |
37 | 39 | unless g.test_rbfiles.empty? |
38 | 40 | f.puts %Q[ mrb_state *mrb2;] |
39 | 41 | if g.test_args.empty? |
40 | - f.puts %Q[ mrb_value val1, val2, val3, ary1, ary2;] | |
42 | + f.puts %Q[ mrb_value verbose;] | |
41 | 43 | else |
42 | - f.puts %Q[ mrb_value val1, val2, val3, ary1, ary2, test_args_hash;] | |
44 | + f.puts %Q[ mrb_value verbose, test_args_hash;] | |
43 | 45 | end |
44 | 46 | f.puts %Q[ int ai;] |
45 | 47 | g.test_rbfiles.count.times do |i| |
46 | 48 | f.puts %Q[ ai = mrb_gc_arena_save(mrb);] |
47 | - f.puts %Q[ mrb2 = mrb_open();] | |
48 | - f.puts %Q[ val3 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"));] | |
49 | - f.puts %Q[ if (mrb_test(val3)) {] | |
50 | - f.puts %Q[ mrb_gv_set(mrb2, mrb_intern_lit(mrb2, "$mrbtest_verbose"), val3);] | |
49 | + f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] | |
50 | + dep_list.each do |d| | |
51 | + f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] | |
52 | + f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] | |
53 | + end | |
54 | + f.puts %Q[ mrb_init_test_driver(mrb2);] | |
55 | + f.puts %Q[ verbose = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"));] | |
56 | + f.puts %Q[ if (mrb_test(verbose)) {] | |
57 | + f.puts %Q[ mrb_gv_set(mrb2, mrb_intern_lit(mrb2, "$mrbtest_verbose"), verbose);] | |
51 | 58 | f.puts %Q[ }] |
52 | 59 | if test_preload.nil? |
53 | 60 | f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] |
@@ -73,30 +80,9 @@ MRuby.each_target do | ||
73 | 80 | f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] unless g.test_objs.empty? |
74 | 81 | |
75 | 82 | f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] |
76 | - f.puts %Q[ if (mrb2->exc) {] | |
77 | - f.puts %Q[ mrb_print_error(mrb2);] | |
78 | - f.puts %Q[ exit(EXIT_FAILURE);] | |
79 | - f.puts %Q[ }] | |
80 | 83 | f.puts %Q[ ] |
81 | 84 | |
82 | - %w(ok_test ko_test kill_test).each do |vname| | |
83 | - f.puts %Q[ val2 = mrb_gv_get(mrb2, mrb_intern_lit(mrb2, "$#{vname}"));] | |
84 | - f.puts %Q[ if (mrb_fixnum_p(val2)) {] | |
85 | - f.puts %Q[ val1 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$#{vname}"));] | |
86 | - f.puts %Q[ mrb_gv_set(mrb, mrb_intern_lit(mrb, "$#{vname}"), mrb_fixnum_value(mrb_fixnum(val1) + mrb_fixnum(val2)));] | |
87 | - f.puts %Q[ }\n] | |
88 | - end | |
89 | - | |
90 | - f.puts %Q[ ary2 = mrb_gv_get(mrb2, mrb_intern_lit(mrb2, "$asserts"));] | |
91 | - f.puts %Q[ if (mrb_test(ary2)) {] | |
92 | - f.puts %Q[ ary1 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$asserts"));] | |
93 | - f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);] | |
94 | - f.puts %Q[ ] | |
95 | - f.puts %Q[ while (mrb_test(val2)) {] | |
96 | - f.puts %Q[ mrb_ary_push(mrb, ary1, mrb_str_new(mrb, RSTRING_PTR(val2), RSTRING_LEN(val2)));] | |
97 | - f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);] | |
98 | - f.puts %Q[ }] | |
99 | - f.puts %Q[ }] | |
85 | + f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] | |
100 | 86 | f.puts %Q[ mrb_close(mrb2);] |
101 | 87 | f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] |
102 | 88 | end |
@@ -104,44 +90,5 @@ MRuby.each_target do | ||
104 | 90 | f.puts %Q[}] |
105 | 91 | end |
106 | 92 | end |
107 | - | |
108 | - end | |
109 | - | |
110 | - no_mrb_open_test = "#{build_dir}/test/no_mrb_open_test" | |
111 | - no_mrb_open_test_rbfiles = no_mrb_open_test_gem.reduce([]) { |res, v| | |
112 | - res += v.test_rbfiles | |
113 | - } | |
114 | - if no_mrb_open_test_rbfiles.empty? | |
115 | - no_mrb_open_test_rbfiles << "#{MRUBY_ROOT}/test/no_mrb_open_test_dummy.rb" | |
116 | - end | |
117 | - | |
118 | - no_mrb_open_test_lib = no_mrb_open_test.ext(exts.object) | |
119 | - file no_mrb_open_test_lib => "#{no_mrb_open_test}.c" | |
120 | - file "#{no_mrb_open_test}.c" => no_mrb_open_test_rbfiles + [MRUBY_CONFIG, __FILE__] do |t| | |
121 | - open(t.name, 'w') do |f| | |
122 | - f.puts %Q[/*] | |
123 | - f.puts %Q[ * This file contains a test code for following gems:] | |
124 | - no_mrb_open_test_gem.each { |g| f.puts %Q[ * #{g.name}] } | |
125 | - f.puts %Q[ *] | |
126 | - f.puts %Q[ * IMPORTANT:] | |
127 | - f.puts %Q[ * This file was generated!] | |
128 | - f.puts %Q[ * All manual changes will get lost.] | |
129 | - f.puts %Q[ */] | |
130 | - | |
131 | - f.puts %Q[] | |
132 | - | |
133 | - f.puts %Q[\#include "mruby.h"] | |
134 | - f.puts %Q[\#include "mruby/irep.h"] | |
135 | - | |
136 | - f.puts %Q[] | |
137 | - | |
138 | - mrbc.run f, no_mrb_open_test_rbfiles, "no_mrb_open_gem_test_irep" | |
139 | - | |
140 | - f.puts %Q[] | |
141 | - | |
142 | - f.puts %Q[void no_mrb_open_mrbgem_test(mrb_state *mrb) {] | |
143 | - f.puts %Q[ mrb_load_irep(mrb, no_mrb_open_gem_test_irep);] | |
144 | - f.puts %Q[}] | |
145 | - end | |
146 | 93 | end |
147 | 94 | end |
@@ -16,6 +16,7 @@ | ||
16 | 16 | #include "mruby/compile.h" |
17 | 17 | #include "mruby/string.h" |
18 | 18 | #include "mruby/variable.h" |
19 | +#include "mruby/array.h" | |
19 | 20 | |
20 | 21 | void |
21 | 22 | mrb_init_mrbtest(mrb_state *); |
@@ -81,12 +82,62 @@ mrb_t_printstr(mrb_state *mrb, mrb_value self) | ||
81 | 82 | return argv; |
82 | 83 | } |
83 | 84 | |
85 | +void | |
86 | +mrb_init_test_driver(mrb_state *mrb) | |
87 | +{ | |
88 | + struct RClass *krn, *mrbtest; | |
89 | + | |
90 | + krn = mrb->kernel_module; | |
91 | + mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1)); | |
92 | + | |
93 | + mrbtest = mrb_define_module(mrb, "Mrbtest"); | |
94 | + | |
95 | + mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX)); | |
96 | + mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN)); | |
97 | + mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT)); | |
98 | +} | |
99 | + | |
100 | +void | |
101 | +mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src) | |
102 | +{ | |
103 | + mrb_value res_src; | |
104 | + | |
105 | + if (mrb_src->exc) { | |
106 | + mrb_print_error(mrb_src); | |
107 | + exit(EXIT_FAILURE); | |
108 | + } | |
109 | + | |
110 | +#define TEST_COUNT_PASS(name) \ | |
111 | + do { \ | |
112 | + res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$" #name)); \ | |
113 | + if (mrb_fixnum_p(res_src)) { \ | |
114 | + mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name)); \ | |
115 | + mrb_gv_set(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name), mrb_fixnum_value(mrb_fixnum(res_dst) + mrb_fixnum(res_src))); \ | |
116 | + } \ | |
117 | + } while (FALSE) \ | |
118 | + | |
119 | + TEST_COUNT_PASS(ok_test); | |
120 | + TEST_COUNT_PASS(ko_test); | |
121 | + TEST_COUNT_PASS(kill_test); | |
122 | + | |
123 | +#undef TEST_COUNT_PASS | |
124 | + | |
125 | + res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$asserts")); | |
126 | + | |
127 | + if (mrb_array_p(res_src)) { | |
128 | + mrb_int i; | |
129 | + mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$asserts")); | |
130 | + for (i = 0; i < RARRAY_LEN(res_src); ++i) { | |
131 | + mrb_value val_src = RARRAY_PTR(res_src)[i]; | |
132 | + mrb_ary_push(mrb_dst, res_dst, mrb_str_new(mrb_dst, RSTRING_PTR(val_src), RSTRING_LEN(val_src))); | |
133 | + } | |
134 | + } | |
135 | +} | |
136 | + | |
84 | 137 | int |
85 | 138 | main(int argc, char **argv) |
86 | 139 | { |
87 | 140 | mrb_state *mrb; |
88 | - struct RClass *krn; | |
89 | - struct RClass *mrbtest; | |
90 | 141 | int ret; |
91 | 142 | |
92 | 143 | print_hint(); |
@@ -103,15 +154,7 @@ main(int argc, char **argv) | ||
103 | 154 | mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value()); |
104 | 155 | } |
105 | 156 | |
106 | - krn = mrb->kernel_module; | |
107 | - mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1)); | |
108 | - | |
109 | - mrbtest = mrb_define_module(mrb, "Mrbtest"); | |
110 | - | |
111 | - mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX)); | |
112 | - mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN)); | |
113 | - mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT)); | |
114 | - | |
157 | + mrb_init_test_driver(mrb); | |
115 | 158 | mrb_init_mrbtest(mrb); |
116 | 159 | ret = eval_test(mrb); |
117 | 160 | mrb_close(mrb); |
@@ -6,15 +6,26 @@ extern const uint8_t mrbtest_assert_irep[]; | ||
6 | 6 | extern const uint8_t mrbtest_irep[]; |
7 | 7 | |
8 | 8 | void mrbgemtest_init(mrb_state* mrb); |
9 | +void mrb_init_test_driver(mrb_state* mrb); | |
10 | +void mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src); | |
9 | 11 | |
10 | 12 | void |
11 | 13 | mrb_init_mrbtest(mrb_state *mrb) |
12 | 14 | { |
15 | + mrb_state *core_test; | |
16 | + | |
13 | 17 | mrb_load_irep(mrb, mrbtest_assert_irep); |
14 | - mrb_load_irep(mrb, mrbtest_irep); | |
18 | + | |
19 | + core_test = mrb_open_core(mrb_default_allocf, NULL); | |
20 | + mrb_init_test_driver(core_test); | |
21 | + mrb_load_irep(core_test, mrbtest_assert_irep); | |
22 | + mrb_load_irep(core_test, mrbtest_irep); | |
23 | + mrb_t_pass_result(mrb, core_test); | |
24 | + | |
15 | 25 | #ifndef DISABLE_GEMS |
16 | 26 | mrbgemtest_init(mrb); |
17 | 27 | #endif |
28 | + | |
18 | 29 | if (mrb->exc) { |
19 | 30 | mrb_print_error(mrb); |
20 | 31 | exit(EXIT_FAILURE); |
@@ -12,11 +12,12 @@ MRuby.each_target do | ||
12 | 12 | ass_lib = ass_c.ext(exts.object) |
13 | 13 | |
14 | 14 | mrbtest_lib = libfile("#{current_build_dir}/mrbtest") |
15 | - gem_test_files = gems.select { |g| g.run_test_in_other_mrb_state? }.map { |g| g.test_rbireps.ext(exts.object) } | |
16 | - file mrbtest_lib => [mlib, ass_lib, gems.map(&:test_objs), gem_test_files].flatten do |t| | |
15 | + mrbtest_objs = gems.map do |v| | |
16 | + v.test_objs + [v.test_rbireps.ext(exts.object)] | |
17 | + end | |
18 | + file mrbtest_lib => [mlib, ass_lib] + mrbtest_objs do |t| | |
17 | 19 | archiver.run t.name, t.prerequisites |
18 | 20 | end |
19 | - file mrbtest_lib => "#{build_dir}/test/no_mrb_open_test.c".ext(exts.object) | |
20 | 21 | |
21 | 22 | unless build_mrbtest_lib_only? |
22 | 23 | driver_obj = objfile("#{current_build_dir}/driver") |
@@ -55,16 +56,12 @@ MRuby.each_target do | ||
55 | 56 | f.puts IO.read(init) |
56 | 57 | mrbc.run f, mrbs, 'mrbtest_irep' |
57 | 58 | gems.each do |g| |
58 | - next unless g.run_test_in_other_mrb_state? | |
59 | 59 | f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] |
60 | 60 | end |
61 | - f.puts %Q[void no_mrb_open_mrbgem_test(mrb_state *mrb);] | |
62 | 61 | f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {] |
63 | 62 | gems.each do |g| |
64 | - next unless g.run_test_in_other_mrb_state? | |
65 | 63 | f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] |
66 | 64 | end |
67 | - f.puts %Q[ no_mrb_open_mrbgem_test(mrb);] | |
68 | 65 | f.puts %Q[}] |
69 | 66 | end |
70 | 67 | end |
@@ -1,2 +0,0 @@ | ||
1 | -#dummy | |
2 | - |