超漢字上で、mrubyを使ってhello worldを表示させる。
Revisão | fc6f7d97a82d0fae63e7c3eab6d93f2feb37d78e (tree) |
---|---|
Hora | 2017-06-05 23:18:29 |
Autor | ornse01 <ornse01@user...> |
Commiter | ornse01 |
copy from mruby-test gem
@@ -0,0 +1,7 @@ | ||
1 | +Running Tests | |
2 | +============= | |
3 | + | |
4 | +To run the tests, execute the following from the project's root directory. | |
5 | + | |
6 | + $ make test | |
7 | + |
@@ -0,0 +1,166 @@ | ||
1 | +/* | |
2 | +** mrbtest - Test for Embeddable Ruby | |
3 | +** | |
4 | +** This program runs Ruby test programs in test/t directory | |
5 | +** against the current mruby implementation. | |
6 | +*/ | |
7 | + | |
8 | + | |
9 | +#include <stdio.h> | |
10 | +#include <stdlib.h> | |
11 | +#include <string.h> | |
12 | + | |
13 | +#include "mruby.h" | |
14 | +#include "mruby/proc.h" | |
15 | +#include "mruby/data.h" | |
16 | +#include "mruby/compile.h" | |
17 | +#include "mruby/string.h" | |
18 | +#include "mruby/variable.h" | |
19 | +#include "mruby/array.h" | |
20 | + | |
21 | +void | |
22 | +mrb_init_mrbtest(mrb_state *); | |
23 | + | |
24 | +/* Print a short remark for the user */ | |
25 | +static void | |
26 | +print_hint(void) | |
27 | +{ | |
28 | + printf("mrbtest - Embeddable Ruby Test\n\n"); | |
29 | +} | |
30 | + | |
31 | +static int | |
32 | +check_error(mrb_state *mrb) | |
33 | +{ | |
34 | + /* Error check */ | |
35 | + /* $ko_test and $kill_test should be 0 */ | |
36 | + mrb_value ko_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$ko_test")); | |
37 | + mrb_value kill_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$kill_test")); | |
38 | + | |
39 | + return mrb_fixnum_p(ko_test) && mrb_fixnum(ko_test) == 0 && mrb_fixnum_p(kill_test) && mrb_fixnum(kill_test) == 0; | |
40 | +} | |
41 | + | |
42 | +static int | |
43 | +eval_test(mrb_state *mrb) | |
44 | +{ | |
45 | + /* evaluate the test */ | |
46 | + mrb_funcall(mrb, mrb_top_self(mrb), "report", 0); | |
47 | + /* did an exception occur? */ | |
48 | + if (mrb->exc) { | |
49 | + mrb_print_error(mrb); | |
50 | + mrb->exc = 0; | |
51 | + return EXIT_FAILURE; | |
52 | + } | |
53 | + else if (!check_error(mrb)) { | |
54 | + return EXIT_FAILURE; | |
55 | + } | |
56 | + return EXIT_SUCCESS; | |
57 | +} | |
58 | + | |
59 | +static void | |
60 | +t_printstr(mrb_state *mrb, mrb_value obj) | |
61 | +{ | |
62 | + char *s; | |
63 | + int len; | |
64 | + | |
65 | + if (mrb_string_p(obj)) { | |
66 | + s = RSTRING_PTR(obj); | |
67 | + len = RSTRING_LEN(obj); | |
68 | + fwrite(s, len, 1, stdout); | |
69 | + } | |
70 | +} | |
71 | + | |
72 | +mrb_value | |
73 | +mrb_t_printstr(mrb_state *mrb, mrb_value self) | |
74 | +{ | |
75 | + mrb_value argv; | |
76 | + | |
77 | + mrb_get_args(mrb, "o", &argv); | |
78 | + t_printstr(mrb, argv); | |
79 | + | |
80 | + return argv; | |
81 | +} | |
82 | + | |
83 | +void | |
84 | +mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose) | |
85 | +{ | |
86 | + struct RClass *krn, *mrbtest; | |
87 | + | |
88 | + krn = mrb->kernel_module; | |
89 | + mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1)); | |
90 | + | |
91 | + mrbtest = mrb_define_module(mrb, "Mrbtest"); | |
92 | + | |
93 | + mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX)); | |
94 | + mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN)); | |
95 | + mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT)); | |
96 | + | |
97 | + if (verbose) { | |
98 | + mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value()); | |
99 | + } | |
100 | +} | |
101 | + | |
102 | +void | |
103 | +mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src) | |
104 | +{ | |
105 | + mrb_value res_src; | |
106 | + | |
107 | + if (mrb_src->exc) { | |
108 | + mrb_print_error(mrb_src); | |
109 | + exit(EXIT_FAILURE); | |
110 | + } | |
111 | + | |
112 | +#define TEST_COUNT_PASS(name) \ | |
113 | + do { \ | |
114 | + res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$" #name)); \ | |
115 | + if (mrb_fixnum_p(res_src)) { \ | |
116 | + mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name)); \ | |
117 | + mrb_gv_set(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name), mrb_fixnum_value(mrb_fixnum(res_dst) + mrb_fixnum(res_src))); \ | |
118 | + } \ | |
119 | + } while (FALSE) \ | |
120 | + | |
121 | + TEST_COUNT_PASS(ok_test); | |
122 | + TEST_COUNT_PASS(ko_test); | |
123 | + TEST_COUNT_PASS(kill_test); | |
124 | + | |
125 | +#undef TEST_COUNT_PASS | |
126 | + | |
127 | + res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$asserts")); | |
128 | + | |
129 | + if (mrb_array_p(res_src)) { | |
130 | + mrb_int i; | |
131 | + mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$asserts")); | |
132 | + for (i = 0; i < RARRAY_LEN(res_src); ++i) { | |
133 | + mrb_value val_src = RARRAY_PTR(res_src)[i]; | |
134 | + mrb_ary_push(mrb_dst, res_dst, mrb_str_new(mrb_dst, RSTRING_PTR(val_src), RSTRING_LEN(val_src))); | |
135 | + } | |
136 | + } | |
137 | +} | |
138 | + | |
139 | +int | |
140 | +main(int argc, char **argv) | |
141 | +{ | |
142 | + mrb_state *mrb; | |
143 | + int ret; | |
144 | + mrb_bool verbose = FALSE; | |
145 | + | |
146 | + print_hint(); | |
147 | + | |
148 | + /* new interpreter instance */ | |
149 | + mrb = mrb_open(); | |
150 | + if (mrb == NULL) { | |
151 | + fprintf(stderr, "Invalid mrb_state, exiting test driver"); | |
152 | + return EXIT_FAILURE; | |
153 | + } | |
154 | + | |
155 | + if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v') { | |
156 | + printf("verbose mode: enable\n\n"); | |
157 | + verbose = TRUE; | |
158 | + } | |
159 | + | |
160 | + mrb_init_test_driver(mrb, verbose); | |
161 | + mrb_init_mrbtest(mrb); | |
162 | + ret = eval_test(mrb); | |
163 | + mrb_close(mrb); | |
164 | + | |
165 | + return ret; | |
166 | +} |
@@ -0,0 +1,40 @@ | ||
1 | +#include <stdlib.h> | |
2 | +#include "mruby.h" | |
3 | +#include "mruby/irep.h" | |
4 | +#include "mruby/variable.h" | |
5 | + | |
6 | +extern const uint8_t mrbtest_assert_irep[]; | |
7 | +extern const uint8_t mrbtest_irep[]; | |
8 | + | |
9 | +void mrbgemtest_init(mrb_state* mrb); | |
10 | +void mrb_init_test_driver(mrb_state* mrb, mrb_bool verbose); | |
11 | +void mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src); | |
12 | + | |
13 | +void | |
14 | +mrb_init_mrbtest(mrb_state *mrb) | |
15 | +{ | |
16 | + mrb_state *core_test; | |
17 | + | |
18 | + mrb_load_irep(mrb, mrbtest_assert_irep); | |
19 | + | |
20 | + core_test = mrb_open_core(mrb_default_allocf, NULL); | |
21 | + if (core_test == NULL) { | |
22 | + fprintf(stderr, "Invalid mrb_state, exiting %s", __FUNCTION__); | |
23 | + exit(EXIT_FAILURE); | |
24 | + } | |
25 | + mrb_init_test_driver(core_test, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose")))); | |
26 | + mrb_load_irep(core_test, mrbtest_assert_irep); | |
27 | + mrb_load_irep(core_test, mrbtest_irep); | |
28 | + mrb_t_pass_result(mrb, core_test); | |
29 | + | |
30 | +#ifndef DISABLE_GEMS | |
31 | + mrbgemtest_init(mrb); | |
32 | +#endif | |
33 | + | |
34 | + if (mrb->exc) { | |
35 | + mrb_print_error(mrb); | |
36 | + exit(EXIT_FAILURE); | |
37 | + } | |
38 | + mrb_close(core_test); | |
39 | +} | |
40 | + |
@@ -0,0 +1,174 @@ | ||
1 | +MRuby::Gem::Specification.new('mruby-test') do |spec| | |
2 | + spec.license = 'MIT' | |
3 | + spec.author = 'mruby developers' | |
4 | + spec.summary = 'mruby test' | |
5 | + | |
6 | + build.bins << 'mrbtest' | |
7 | + spec.add_dependency('mruby-compiler', :core => 'mruby-compiler') | |
8 | + | |
9 | + clib = "#{build_dir}/mrbtest.c" | |
10 | + mlib = clib.ext(exts.object) | |
11 | + mrbs = Dir.glob("#{MRUBY_ROOT}/test/t/*.rb") | |
12 | + exec = exefile("#{build.build_dir}/bin/mrbtest") | |
13 | + | |
14 | + libmruby = libfile("#{build.build_dir}/lib/libmruby") | |
15 | + libmruby_core = libfile("#{build.build_dir}/lib/libmruby_core") | |
16 | + | |
17 | + mrbtest_lib = libfile("#{build_dir}/mrbtest") | |
18 | + mrbtest_objs = [] | |
19 | + | |
20 | + driver_obj = objfile("#{build_dir}/driver") | |
21 | + driver = "#{spec.dir}/driver.c" | |
22 | + | |
23 | + assert_c = "#{build_dir}/assert.c" | |
24 | + assert_rb = "#{MRUBY_ROOT}/test/assert.rb" | |
25 | + assert_lib = assert_c.ext(exts.object) | |
26 | + mrbtest_objs << assert_lib | |
27 | + | |
28 | + file assert_lib => assert_c | |
29 | + file assert_c => [build.mrbcfile, assert_rb] do |t| | |
30 | + open(t.name, 'w') do |f| | |
31 | + mrbc.run f, assert_rb, 'mrbtest_assert_irep' | |
32 | + end | |
33 | + end | |
34 | + | |
35 | + gem_table = build.gems.generate_gem_table build | |
36 | + | |
37 | + build.gems.each do |g| | |
38 | + test_rbobj = g.test_rbireps.ext(exts.object) | |
39 | + g.test_objs << test_rbobj | |
40 | + dep_list = build.gems.tsort_dependencies(g.test_dependencies, gem_table).select(&:generate_functions) | |
41 | + | |
42 | + file test_rbobj => g.test_rbireps | |
43 | + file g.test_rbireps => [g.test_rbfiles].flatten + [File.join(g.dir, 'mrbgem.rake'), g.build.mrbcfile, "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"] do |t| | |
44 | + FileUtils.mkdir_p File.dirname(t.name) | |
45 | + open(t.name, 'w') do |f| | |
46 | + g.print_gem_test_header(f) | |
47 | + test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir| | |
48 | + File.expand_path(g.test_preload, dir) | |
49 | + }.find {|file| File.exist?(file) } | |
50 | + | |
51 | + f.puts %Q[/*] | |
52 | + f.puts %Q[ * This file contains a test code for #{g.name} gem.] | |
53 | + f.puts %Q[ *] | |
54 | + f.puts %Q[ * IMPORTANT:] | |
55 | + f.puts %Q[ * This file was generated!] | |
56 | + f.puts %Q[ * All manual changes will get lost.] | |
57 | + f.puts %Q[ */] | |
58 | + if test_preload.nil? | |
59 | + f.puts %Q[extern const uint8_t mrbtest_assert_irep[];] | |
60 | + else | |
61 | + g.build.mrbc.run f, test_preload, "gem_test_irep_#{g.funcname}_preload" | |
62 | + end | |
63 | + g.test_rbfiles.flatten.each_with_index do |rbfile, i| | |
64 | + g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}" | |
65 | + end | |
66 | + f.puts %Q[void mrb_#{g.funcname}_gem_test(mrb_state *mrb);] unless g.test_objs.empty? | |
67 | + dep_list.each do |d| | |
68 | + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);] | |
69 | + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);] | |
70 | + end | |
71 | + f.puts %Q[void mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose);] | |
72 | + f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] | |
73 | + f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] | |
74 | + unless g.test_rbfiles.empty? | |
75 | + f.puts %Q[ mrb_state *mrb2;] | |
76 | + unless g.test_args.empty? | |
77 | + f.puts %Q[ mrb_value test_args_hash;] | |
78 | + end | |
79 | + f.puts %Q[ int ai;] | |
80 | + g.test_rbfiles.count.times do |i| | |
81 | + f.puts %Q[ ai = mrb_gc_arena_save(mrb);] | |
82 | + f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] | |
83 | + f.puts %Q[ if (mrb2 == NULL) {] | |
84 | + f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __FUNCTION__);] | |
85 | + f.puts %Q[ exit(EXIT_FAILURE);] | |
86 | + f.puts %Q[ }] | |
87 | + dep_list.each do |d| | |
88 | + f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] | |
89 | + f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] | |
90 | + end | |
91 | + f.puts %Q[ mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));] | |
92 | + if test_preload.nil? | |
93 | + f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] | |
94 | + else | |
95 | + f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);] | |
96 | + end | |
97 | + f.puts %Q[ if (mrb2->exc) {] | |
98 | + f.puts %Q[ mrb_print_error(mrb2);] | |
99 | + f.puts %Q[ exit(EXIT_FAILURE);] | |
100 | + f.puts %Q[ }] | |
101 | + f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));] | |
102 | + | |
103 | + unless g.test_args.empty? | |
104 | + f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ] | |
105 | + g.test_args.each do |arg_name, arg_value| | |
106 | + escaped_arg_name = arg_name.gsub('\\', '\\\\\\\\').gsub('"', '\"') | |
107 | + escaped_arg_value = arg_value.gsub('\\', '\\\\\\\\').gsub('"', '\"') | |
108 | + f.puts %Q[ mrb_hash_set(mrb2, test_args_hash, mrb_str_new(mrb2, "#{escaped_arg_name.to_s}", #{escaped_arg_name.to_s.length}), mrb_str_new(mrb2, "#{escaped_arg_value.to_s}", #{escaped_arg_value.to_s.length})); ] | |
109 | + end | |
110 | + f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "TEST_ARGS"), test_args_hash); ] | |
111 | + end | |
112 | + | |
113 | + f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] if g.custom_test_init? | |
114 | + | |
115 | + f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] | |
116 | + f.puts %Q[ ] | |
117 | + | |
118 | + f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] | |
119 | + f.puts %Q[ mrb_close(mrb2);] | |
120 | + f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] | |
121 | + end | |
122 | + end | |
123 | + f.puts %Q[}] | |
124 | + end | |
125 | + end | |
126 | + end | |
127 | + | |
128 | + build.gems.each do |v| | |
129 | + mrbtest_objs.concat v.test_objs | |
130 | + end | |
131 | + | |
132 | + file mrbtest_lib => mrbtest_objs do |t| | |
133 | + build.archiver.run t.name, t.prerequisites | |
134 | + end | |
135 | + | |
136 | + unless build.build_mrbtest_lib_only? | |
137 | + file exec => [driver_obj, mlib, mrbtest_lib, libmruby_core, libmruby] do |t| | |
138 | + gem_flags = build.gems.map { |g| g.linker.flags } | |
139 | + gem_flags_before_libraries = build.gems.map { |g| g.linker.flags_before_libraries } | |
140 | + gem_flags_after_libraries = build.gems.map { |g| g.linker.flags_after_libraries } | |
141 | + gem_libraries = build.gems.map { |g| g.linker.libraries } | |
142 | + gem_library_paths = build.gems.map { |g| g.linker.library_paths } | |
143 | + build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries | |
144 | + end | |
145 | + end | |
146 | + | |
147 | + init = "#{spec.dir}/init_mrbtest.c" | |
148 | + file mlib => clib | |
149 | + file clib => [build.mrbcfile, init] + mrbs do |t| | |
150 | + _pp "GEN", "*.rb", "#{clib.relative_path}" | |
151 | + FileUtils.mkdir_p File.dirname(clib) | |
152 | + open(clib, 'w') do |f| | |
153 | + f.puts %Q[/*] | |
154 | + f.puts %Q[ * This file contains a list of all] | |
155 | + f.puts %Q[ * test functions.] | |
156 | + f.puts %Q[ *] | |
157 | + f.puts %Q[ * IMPORTANT:] | |
158 | + f.puts %Q[ * This file was generated!] | |
159 | + f.puts %Q[ * All manual changes will get lost.] | |
160 | + f.puts %Q[ */] | |
161 | + f.puts %Q[] | |
162 | + f.puts IO.read(init) | |
163 | + mrbc.run f, mrbs, 'mrbtest_irep' | |
164 | + build.gems.each do |g| | |
165 | + f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] | |
166 | + end | |
167 | + f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {] | |
168 | + build.gems.each do |g| | |
169 | + f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] | |
170 | + end | |
171 | + f.puts %Q[}] | |
172 | + end | |
173 | + end | |
174 | +end |