webruby 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/lib/webruby.rb +0 -4
  3. data/lib/webruby/app.rb +4 -0
  4. data/lib/webruby/rake/files.rake +2 -1
  5. data/lib/webruby/rake/mruby.rake +1 -1
  6. data/modules/emscripten/AUTHORS +1 -0
  7. data/modules/emscripten/ChangeLog +34 -1
  8. data/modules/emscripten/cmake/Platform/Emscripten.cmake +30 -9
  9. data/modules/emscripten/emcc +61 -28
  10. data/modules/emscripten/emrun +15 -11
  11. data/modules/emscripten/emscripten.py +3 -0
  12. data/modules/emscripten/src/closure-externs.js +110 -0
  13. data/modules/emscripten/src/intertyper.js +1 -1
  14. data/modules/emscripten/src/jsifier.js +7 -21
  15. data/modules/emscripten/src/library.js +2 -1
  16. data/modules/emscripten/src/library_browser.js +16 -5
  17. data/modules/emscripten/src/library_fs.js +3 -1
  18. data/modules/emscripten/src/library_gl.js +691 -591
  19. data/modules/emscripten/src/library_glut.js +2 -0
  20. data/modules/emscripten/src/library_sdl.js +29 -5
  21. data/modules/emscripten/src/library_uuid.js +140 -0
  22. data/modules/emscripten/src/modules.js +1 -1
  23. data/modules/emscripten/src/parseTools.js +29 -19
  24. data/modules/emscripten/src/postamble.js +3 -4
  25. data/modules/emscripten/src/preamble.js +17 -1
  26. data/modules/emscripten/src/relooper/Relooper.cpp +8 -8
  27. data/modules/emscripten/src/relooper/Relooper.h +5 -5
  28. data/modules/emscripten/src/relooper/test.txt +2 -2
  29. data/modules/emscripten/src/runtime.js +1 -1
  30. data/modules/emscripten/src/settings.js +3 -0
  31. data/modules/emscripten/src/struct_info.json +12 -0
  32. data/modules/emscripten/system/include/uuid/uuid.h +35 -0
  33. data/modules/emscripten/tools/js-optimizer.js +191 -142
  34. data/modules/emscripten/tools/js_optimizer.py +3 -29
  35. data/modules/emscripten/tools/shared.py +43 -6
  36. data/modules/mruby/include/mruby/value.h +3 -2
  37. data/modules/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +5 -9
  38. data/modules/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +3 -5
  39. data/modules/mruby/mrbgems/mruby-hash-ext/src/hash-ext.c +0 -3
  40. data/modules/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +0 -1
  41. data/modules/mruby/mrbgems/mruby-random/src/mt19937ar.c +0 -1
  42. data/modules/mruby/mrbgems/mruby-range-ext/src/range.c +2 -6
  43. data/modules/mruby/mrbgems/mruby-sprintf/src/sprintf.c +0 -4
  44. data/modules/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +22 -0
  45. data/modules/mruby/mrbgems/mruby-string-ext/src/string.c +2 -2
  46. data/modules/mruby/mrbgems/mruby-string-ext/test/string.rb +21 -2
  47. data/modules/mruby/mrbgems/mruby-string-utf8/mrbgem.rake +4 -0
  48. data/modules/mruby/mrbgems/mruby-string-utf8/src/string.c +297 -0
  49. data/modules/mruby/mrbgems/mruby-string-utf8/test/string.rb +27 -0
  50. data/modules/mruby/mrbgems/mruby-struct/src/struct.c +0 -1
  51. data/modules/mruby/mrblib/init_mrblib.c +0 -3
  52. data/modules/mruby/src/array.c +22 -8
  53. data/modules/mruby/src/backtrace.c +12 -9
  54. data/modules/mruby/src/class.c +3 -3
  55. data/modules/mruby/src/codegen.c +17 -5
  56. data/modules/mruby/src/dump.c +5 -6
  57. data/modules/mruby/src/error.c +0 -2
  58. data/modules/mruby/src/etc.c +0 -2
  59. data/modules/mruby/src/gc.c +4 -8
  60. data/modules/mruby/src/load.c +1 -6
  61. data/modules/mruby/src/numeric.c +0 -6
  62. data/modules/mruby/src/object.c +3 -5
  63. data/modules/mruby/src/parse.y +37 -38
  64. data/modules/mruby/src/proc.c +8 -1
  65. data/modules/mruby/src/range.c +3 -7
  66. data/modules/mruby/src/state.c +0 -1
  67. data/modules/mruby/src/string.c +2 -17
  68. data/modules/mruby/src/symbol.c +0 -1
  69. data/modules/mruby/src/variable.c +3 -22
  70. data/modules/mruby/src/vm.c +9 -8
  71. data/modules/mruby/tasks/mrbgem_spec.rake +13 -5
  72. data/modules/mruby/tasks/mrbgems_test.rake +3 -3
  73. data/modules/mruby/tasks/mruby_build_commands.rake +2 -2
  74. data/modules/mruby/tasks/mruby_build_gem.rake +3 -3
  75. data/modules/mruby/test/init_mrbtest.c +0 -3
  76. data/modules/mruby/test/t/array.rb +12 -1
  77. data/modules/mruby/test/t/class.rb +67 -0
  78. data/modules/mruby/test/t/exception.rb +12 -0
  79. data/modules/mruby/test/t/kernel.rb +75 -1
  80. data/modules/mruby/test/t/syntax.rb +115 -0
  81. data/scripts/gen_require.rb +12 -1
  82. metadata +8 -2
@@ -17,9 +17,16 @@ struct RProc *
17
17
  mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
18
18
  {
19
19
  struct RProc *p;
20
+ mrb_callinfo *ci = mrb->c->ci;
20
21
 
21
22
  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
22
- p->target_class = (mrb->c->ci) ? mrb->c->ci->target_class : 0;
23
+ p->target_class = 0;
24
+ if (ci) {
25
+ if (ci->proc)
26
+ p->target_class = ci->proc->target_class;
27
+ if (!p->target_class)
28
+ p->target_class = ci->target_class;
29
+ }
23
30
  p->body.irep = irep;
24
31
  p->env = 0;
25
32
  mrb_irep_incref(mrb, irep);
@@ -176,7 +176,7 @@ r_le(mrb_state *mrb, mrb_value a, mrb_value b)
176
176
  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
177
177
  /* output :a < b => -1, a = b => 0, a > b => +1 */
178
178
 
179
- if (mrb_type(r) == MRB_TT_FIXNUM) {
179
+ if (mrb_fixnum_p(r)) {
180
180
  mrb_int c = mrb_fixnum(r);
181
181
  if (c == 0 || c == -1) return TRUE;
182
182
  }
@@ -190,11 +190,7 @@ r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
190
190
  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
191
191
  /* output :a < b => -1, a = b => 0, a > b => +1 */
192
192
 
193
- if (mrb_type(r) == MRB_TT_FIXNUM) {
194
- if (mrb_fixnum(r) == 1) return TRUE;
195
- }
196
-
197
- return FALSE;
193
+ return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;
198
194
  }
199
195
 
200
196
  static mrb_bool
@@ -203,7 +199,7 @@ r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
203
199
  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
204
200
  /* output :a < b => -1, a = b => 0, a > b => +1 */
205
201
 
206
- if (mrb_type(r) == MRB_TT_FIXNUM) {
202
+ if (mrb_fixnum_p(r)) {
207
203
  mrb_int c = mrb_fixnum(r);
208
204
  if (c == 0 || c == 1) return TRUE;
209
205
  }
@@ -7,7 +7,6 @@
7
7
  #include <stdlib.h>
8
8
  #include <string.h>
9
9
  #include "mruby.h"
10
- #include "mruby/class.h"
11
10
  #include "mruby/irep.h"
12
11
  #include "mruby/variable.h"
13
12
  #include "mruby/debug.h"
@@ -5,12 +5,7 @@
5
5
  */
6
6
 
7
7
  #include <ctype.h>
8
- #ifndef SIZE_MAX
9
- /* Some versions of VC++
10
- * has SIZE_MAX in stdint.h
11
- */
12
- # include <limits.h>
13
- #endif
8
+ #include <limits.h>
14
9
  #include <stddef.h>
15
10
  #include <stdlib.h>
16
11
  #include <string.h>
@@ -112,16 +107,6 @@ mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len)
112
107
  return str;
113
108
  }
114
109
 
115
- static inline void
116
- str_mod_check(mrb_state *mrb, mrb_value str, char *p, mrb_int len)
117
- {
118
- struct RString *s = mrb_str_ptr(str);
119
-
120
- if (s->ptr != p || s->len != len) {
121
- mrb_raise(mrb, E_RUNTIME_ERROR, "string modified");
122
- }
123
- }
124
-
125
110
  #define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
126
111
 
127
112
  /* char offset to byte offset */
@@ -1248,7 +1233,7 @@ mrb_str_include(mrb_state *mrb, mrb_value self)
1248
1233
  mrb_bool include_p;
1249
1234
 
1250
1235
  mrb_get_args(mrb, "o", &str2);
1251
- if (mrb_type(str2) == MRB_TT_FIXNUM) {
1236
+ if (mrb_fixnum_p(str2)) {
1252
1237
  include_p = (memchr(RSTRING_PTR(self), mrb_fixnum(str2), RSTRING_LEN(self)) != NULL);
1253
1238
  }
1254
1239
  else {
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  #include <ctype.h>
8
- #include <limits.h>
9
8
  #include <string.h>
10
9
  #include "mruby.h"
11
10
  #include "mruby/khash.h"
@@ -4,14 +4,12 @@
4
4
  ** See Copyright Notice in mruby.h
5
5
  */
6
6
 
7
+ #include <ctype.h>
7
8
  #include "mruby.h"
8
9
  #include "mruby/array.h"
9
10
  #include "mruby/class.h"
10
11
  #include "mruby/proc.h"
11
12
  #include "mruby/string.h"
12
- #include "mruby/variable.h"
13
- #include "error.h"
14
- #include <ctype.h>
15
13
 
16
14
  typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
17
15
 
@@ -756,7 +754,7 @@ mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym)
756
754
  }
757
755
 
758
756
  void
759
- mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_value v)
757
+ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
760
758
  {
761
759
  struct RClass * cls = c;
762
760
 
@@ -823,24 +821,7 @@ mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
823
821
  struct RClass *c = mrb->c->ci->proc->target_class;
824
822
 
825
823
  if (!c) c = mrb->c->ci->target_class;
826
- while (c) {
827
- if (c->iv) {
828
- iv_tbl *t = c->iv;
829
-
830
- if (iv_get(mrb, t, sym, NULL)) {
831
- mrb_write_barrier(mrb, (struct RBasic*)c);
832
- iv_put(mrb, t, sym, v);
833
- return;
834
- }
835
- }
836
- c = c->super;
837
- }
838
- c = mrb->c->ci->target_class;
839
- if (!c->iv) {
840
- c->iv = iv_new(mrb);
841
- }
842
- mrb_write_barrier(mrb, (struct RBasic*)c);
843
- iv_put(mrb, c->iv, sym, v);
824
+ mrb_mod_cv_set(mrb, c, sym, v);
844
825
  }
845
826
 
846
827
  mrb_bool
@@ -4,7 +4,6 @@
4
4
  ** See Copyright Notice in mruby.h
5
5
  */
6
6
 
7
- #include <string.h>
8
7
  #include <setjmp.h>
9
8
  #include <stddef.h>
10
9
  #include <stdarg.h>
@@ -13,7 +12,6 @@
13
12
  #include "mruby/class.h"
14
13
  #include "mruby/hash.h"
15
14
  #include "mruby/irep.h"
16
- #include "mruby/numeric.h"
17
15
  #include "mruby/proc.h"
18
16
  #include "mruby/range.h"
19
17
  #include "mruby/string.h"
@@ -231,6 +229,7 @@ cipush(mrb_state *mrb)
231
229
  ci->ridx = ridx;
232
230
  ci->env = 0;
233
231
  ci->pc = 0;
232
+ ci->err = 0;
234
233
 
235
234
  return ci;
236
235
  }
@@ -263,6 +262,8 @@ ecall(mrb_state *mrb, int i)
263
262
 
264
263
  p = mrb->c->ensure[i];
265
264
  if (!p) return;
265
+ if (mrb->c->ci->eidx > i)
266
+ mrb->c->ci->eidx = i;
266
267
  ci = cipush(mrb);
267
268
  ci->stackidx = mrb->c->stack - mrb->c->stbase;
268
269
  ci->mid = ci[-1].mid;
@@ -601,7 +602,6 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
601
602
  stack_init(mrb);
602
603
  }
603
604
  stack_extend(mrb, irep->nregs, stack_keep);
604
- mrb->c->ci->err = pc;
605
605
  mrb->c->ci->proc = proc;
606
606
  mrb->c->ci->nregs = irep->nregs + 1;
607
607
  regs = mrb->c->stack;
@@ -852,13 +852,14 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
852
852
 
853
853
  CASE(OP_EPOP) {
854
854
  /* A A.times{ensure_pop().call} */
855
- int n;
856
855
  int a = GETARG_A(i);
856
+ mrb_callinfo *ci = mrb->c->ci;
857
+ int n, eidx = ci->eidx;
857
858
 
858
- for (n=0; n<a; n++) {
859
- ecall(mrb, --mrb->c->ci->eidx);
859
+ for (n=0; n<a && eidx > ci[-1].eidx; n++) {
860
+ ecall(mrb, --eidx);
861
+ ARENA_RESTORE(mrb, ai);
860
862
  }
861
- ARENA_RESTORE(mrb, ai);
862
863
  NEXT;
863
864
  }
864
865
 
@@ -2130,7 +2131,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
2130
2131
  ecall(mrb, n);
2131
2132
  }
2132
2133
  }
2133
- mrb->c->ci->err = 0;
2134
+ ERR_PC_CLR(mrb);
2134
2135
  mrb->jmp = prev_jmp;
2135
2136
  if (mrb->exc) {
2136
2137
  return mrb_obj_value(mrb->exc);
@@ -149,7 +149,7 @@ module MRuby
149
149
  end
150
150
  end # generate_gem_init
151
151
 
152
- def print_gem_init_header(f)
152
+ def print_gem_comment(f)
153
153
  f.puts %Q[/*]
154
154
  f.puts %Q[ * This file is loading the irep]
155
155
  f.puts %Q[ * Ruby GEM code.]
@@ -158,15 +158,23 @@ module MRuby
158
158
  f.puts %Q[ * This file was generated!]
159
159
  f.puts %Q[ * All manual changes will get lost.]
160
160
  f.puts %Q[ */]
161
+ end
162
+
163
+ def print_gem_init_header(f)
164
+ print_gem_comment(f)
165
+ f.puts %Q[#include <stdlib.h>] unless rbfiles.empty?
166
+ f.puts %Q[#include "mruby.h"]
167
+ f.puts %Q[#include "mruby/irep.h"] unless rbfiles.empty?
168
+ end
169
+
170
+ def print_gem_test_header(f)
171
+ print_gem_comment(f)
161
172
  f.puts %Q[#include <stdlib.h>]
162
173
  f.puts %Q[#include "mruby.h"]
174
+ f.puts %Q[#include "mruby/array.h"]
163
175
  f.puts %Q[#include "mruby/irep.h"]
164
- f.puts %Q[#include "mruby/dump.h"]
165
176
  f.puts %Q[#include "mruby/string.h"]
166
- f.puts %Q[#include "mruby/proc.h"]
167
177
  f.puts %Q[#include "mruby/variable.h"]
168
- f.puts %Q[#include "mruby/array.h"]
169
- f.puts %Q[#include "mruby/hash.h"]
170
178
  end
171
179
 
172
180
  def version_ok?(req_versions)
@@ -3,12 +3,12 @@ MRuby.each_target do
3
3
  test_rbobj = g.test_rbireps.ext(exts.object)
4
4
 
5
5
  file test_rbobj => g.test_rbireps
6
- file g.test_rbireps => [g.test_rbfiles].flatten + [g.build.mrbcfile, libfile("#{build_dir}/lib/libmruby")] do |t|
6
+ file g.test_rbireps => [g.test_rbfiles].flatten + [g.build.mrbcfile] do |t|
7
7
  open(t.name, 'w') do |f|
8
- g.print_gem_init_header(f)
8
+ g.print_gem_test_header(f)
9
9
  test_preload = [g.dir, MRUBY_ROOT].map {|dir|
10
10
  File.expand_path(g.test_preload, dir)
11
- }.find {|file| File.exists?(file) }
11
+ }.find {|file| File.exist?(file) }
12
12
 
13
13
  g.build.mrbc.run f, test_preload, "gem_test_irep_#{g.funcname}_preload"
14
14
  g.test_rbfiles.flatten.each_with_index do |rbfile, i|
@@ -106,7 +106,7 @@ module MRuby
106
106
  private
107
107
  def get_dependencies(file)
108
108
  file = file.ext('d') unless File.extname(file) == '.d'
109
- if File.exists?(file)
109
+ if File.exist?(file)
110
110
  File.read(file).gsub("\\\n ", "").scan(/^\S+:\s+(.+)$/).flatten.map {|s| s.split(' ') }.flatten
111
111
  else
112
112
  []
@@ -265,7 +265,7 @@ module MRuby
265
265
  # if mrbc execution fail, drop the file
266
266
  unless $?.exitstatus
267
267
  File.delete(out.path)
268
- exit -1
268
+ exit(-1)
269
269
  end
270
270
  end
271
271
  end
@@ -2,7 +2,7 @@ module MRuby
2
2
  module LoadGems
3
3
  def gembox(gemboxfile)
4
4
  gembox = File.expand_path("#{gemboxfile}.gembox", "#{MRUBY_ROOT}/mrbgems")
5
- fail "Can't find gembox '#{gembox}'" unless File.exists?(gembox)
5
+ fail "Can't find gembox '#{gembox}'" unless File.exist?(gembox)
6
6
 
7
7
  GemBox.config = self
8
8
  GemBox.path = gembox
@@ -25,7 +25,7 @@ module MRuby
25
25
 
26
26
  gemrake = File.join(gemdir, "mrbgem.rake")
27
27
 
28
- fail "Can't find #{gemrake}" unless File.exists?(gemrake)
28
+ fail "Can't find #{gemrake}" unless File.exist?(gemrake)
29
29
  Gem.current = nil
30
30
  load gemrake
31
31
  return nil unless Gem.current
@@ -50,7 +50,7 @@ module MRuby
50
50
  url = params[:git]
51
51
  gemdir = "#{gem_clone_dir}/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}"
52
52
 
53
- if File.exists?(gemdir)
53
+ if File.exist?(gemdir)
54
54
  if $pull_gems
55
55
  git.run_pull gemdir, url
56
56
  else
@@ -1,9 +1,6 @@
1
1
  #include <stdlib.h>
2
2
  #include "mruby.h"
3
3
  #include "mruby/irep.h"
4
- #include "mruby/dump.h"
5
- #include "mruby/string.h"
6
- #include "mruby/proc.h"
7
4
 
8
5
  extern const uint8_t mrbtest_irep[];
9
6
 
@@ -46,6 +46,9 @@ assert('Array#[]', '15.2.12.5.4') do
46
46
  end
47
47
 
48
48
  assert_equal(2, [1,2,3].[](1))
49
+ assert_equal(nil, [1,2,3].[](4))
50
+ assert_equal(3, [1,2,3].[](-1))
51
+ assert_equal(nil, [1,2,3].[](-4))
49
52
  end
50
53
 
51
54
  assert('Array#[]=', '15.2.12.5.5') do
@@ -81,8 +84,14 @@ end
81
84
 
82
85
  assert('Array#delete_at', '15.2.12.5.9') do
83
86
  a = [1,2,3]
84
- a.delete_at(1)
87
+ assert_equal(2, a.delete_at(1))
85
88
  assert_equal([1,3], a)
89
+ assert_equal(nil, a.delete_at(3))
90
+ assert_equal([1,3], a)
91
+ assert_equal(nil, a.delete_at(-3))
92
+ assert_equal([1,3], a)
93
+ assert_equal(3, a.delete_at(-1))
94
+ assert_equal([1], a)
86
95
  end
87
96
 
88
97
  assert('Array#each', '15.2.12.5.10') do
@@ -129,6 +138,7 @@ assert('Array#index', '15.2.12.5.14') do
129
138
  a = [1,2,3]
130
139
 
131
140
  assert_equal(1, a.index(2))
141
+ assert_equal(nil, a.index(0))
132
142
  end
133
143
 
134
144
  assert('Array#initialize', '15.2.12.5.15') do
@@ -225,6 +235,7 @@ assert('Array#rindex', '15.2.12.5.26') do
225
235
  a = [1,2,3]
226
236
 
227
237
  assert_equal(1, a.rindex(2))
238
+ assert_equal(nil, a.rindex(0))
228
239
  end
229
240
 
230
241
  assert('Array#shift', '15.2.12.5.27') do
@@ -235,6 +235,23 @@ assert('class to return the last value') do
235
235
  assert_equal(m, :m)
236
236
  end
237
237
 
238
+ assert('raise when superclass is not a class') do
239
+ module FirstModule; end
240
+ assert_raise(TypeError, 'should raise TypeError') do
241
+ class FirstClass < FirstModule; end
242
+ end
243
+
244
+ class SecondClass; end
245
+ assert_raise(TypeError, 'should raise TypeError') do
246
+ class SecondClass < false; end
247
+ end
248
+
249
+ class ThirdClass; end
250
+ assert_raise(TypeError, 'should raise TypeError') do
251
+ class ThirdClass < ThirdClass; end
252
+ end
253
+ end
254
+
238
255
  assert('Class#inherited') do
239
256
  class Foo
240
257
  @@subclass_name = nil
@@ -260,25 +277,40 @@ assert('Class#inherited') do
260
277
  end
261
278
 
262
279
  assert('singleton tests') do
280
+ module FooMod
281
+ def run_foo_mod
282
+ 100
283
+ end
284
+ end
285
+
263
286
  bar = String.new
264
287
 
265
288
  baz = class << bar
289
+ extend FooMod
266
290
  def self.run_baz
267
291
  200
268
292
  end
269
293
  end
270
294
 
295
+ assert_false baz.singleton_methods.include? :run_foo_mod
271
296
  assert_false baz.singleton_methods.include? :run_baz
272
297
 
298
+ assert_raise(NoMethodError, 'should raise NoMethodError') do
299
+ baz.run_foo_mod
300
+ end
273
301
  assert_raise(NoMethodError, 'should raise NoMethodError') do
274
302
  baz.run_baz
275
303
  end
276
304
 
305
+ assert_raise(NoMethodError, 'should raise NoMethodError') do
306
+ bar.run_foo_mod
307
+ end
277
308
  assert_raise(NoMethodError, 'should raise NoMethodError') do
278
309
  bar.run_baz
279
310
  end
280
311
 
281
312
  baz = class << bar
313
+ extend FooMod
282
314
  def self.run_baz
283
315
  300
284
316
  end
@@ -286,9 +318,44 @@ assert('singleton tests') do
286
318
  end
287
319
 
288
320
  assert_true baz.singleton_methods.include? :run_baz
321
+ assert_true baz.singleton_methods.include? :run_foo_mod
322
+ assert_equal 100, baz.run_foo_mod
289
323
  assert_equal 300, baz.run_baz
290
324
 
325
+ assert_raise(NoMethodError, 'should raise NoMethodError') do
326
+ bar.run_foo_mod
327
+ end
291
328
  assert_raise(NoMethodError, 'should raise NoMethodError') do
292
329
  bar.run_baz
293
330
  end
331
+
332
+ fv = false
333
+ class << fv
334
+ def self.run_false
335
+ 5
336
+ end
337
+ end
338
+
339
+ nv = nil
340
+ class << nv
341
+ def self.run_nil
342
+ 6
343
+ end
344
+ end
345
+
346
+ tv = true
347
+ class << tv
348
+ def self.run_nil
349
+ 7
350
+ end
351
+ end
352
+
353
+ assert_raise(TypeError, 'should raise TypeError') do
354
+ num = 1.0
355
+ class << num
356
+ def self.run_nil
357
+ 7
358
+ end
359
+ end
360
+ end
294
361
  end