rice 4.0.4 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -0
  3. data/CONTRIBUTORS.md +2 -0
  4. data/Rakefile +1 -1
  5. data/include/rice/rice.hpp +2851 -1955
  6. data/include/rice/stl.hpp +1654 -287
  7. data/lib/mkmf-rice.rb +5 -2
  8. data/lib/version.rb +1 -1
  9. data/rice/Arg.hpp +6 -6
  10. data/rice/Arg.ipp +8 -9
  11. data/rice/Constructor.hpp +2 -2
  12. data/rice/Data_Object.ipp +69 -15
  13. data/rice/Data_Object_defn.hpp +1 -15
  14. data/rice/Data_Type.ipp +56 -86
  15. data/rice/Data_Type_defn.hpp +14 -17
  16. data/rice/Director.hpp +0 -1
  17. data/rice/Enum.ipp +31 -22
  18. data/rice/Exception.ipp +2 -3
  19. data/rice/Exception_defn.hpp +5 -5
  20. data/rice/HandlerRegistration.hpp +15 -0
  21. data/rice/Return.hpp +5 -4
  22. data/rice/Return.ipp +8 -3
  23. data/rice/detail/ExceptionHandler.hpp +8 -0
  24. data/rice/detail/ExceptionHandler.ipp +28 -0
  25. data/rice/detail/{Exception_Handler_defn.hpp → ExceptionHandler_defn.hpp} +17 -21
  26. data/rice/detail/HandlerRegistry.hpp +51 -0
  27. data/rice/detail/HandlerRegistry.ipp +20 -0
  28. data/rice/detail/InstanceRegistry.hpp +34 -0
  29. data/rice/detail/InstanceRegistry.ipp +50 -0
  30. data/rice/detail/MethodInfo.ipp +1 -1
  31. data/rice/detail/NativeAttribute.hpp +26 -15
  32. data/rice/detail/NativeAttribute.ipp +76 -47
  33. data/rice/detail/NativeFunction.hpp +64 -14
  34. data/rice/detail/NativeFunction.ipp +138 -86
  35. data/rice/detail/NativeIterator.hpp +49 -0
  36. data/rice/detail/NativeIterator.ipp +102 -0
  37. data/rice/detail/NativeRegistry.hpp +31 -0
  38. data/rice/detail/{method_data.ipp → NativeRegistry.ipp} +20 -16
  39. data/rice/detail/Registries.hpp +26 -0
  40. data/rice/detail/Registries.ipp +23 -0
  41. data/rice/detail/RubyFunction.hpp +6 -11
  42. data/rice/detail/RubyFunction.ipp +10 -22
  43. data/rice/detail/Type.hpp +1 -1
  44. data/rice/detail/Type.ipp +2 -2
  45. data/rice/detail/TypeRegistry.hpp +8 -11
  46. data/rice/detail/TypeRegistry.ipp +3 -28
  47. data/rice/detail/Wrapper.hpp +0 -2
  48. data/rice/detail/Wrapper.ipp +74 -24
  49. data/rice/detail/cpp_protect.hpp +93 -0
  50. data/rice/detail/default_allocation_func.ipp +1 -1
  51. data/rice/detail/from_ruby.ipp +206 -2
  52. data/rice/detail/to_ruby.ipp +39 -5
  53. data/rice/detail/to_ruby_defn.hpp +1 -1
  54. data/rice/forward_declares.ipp +6 -0
  55. data/rice/global_function.hpp +0 -4
  56. data/rice/global_function.ipp +0 -6
  57. data/rice/rice.hpp +29 -24
  58. data/rice/stl.hpp +6 -1
  59. data/sample/callbacks/extconf.rb +0 -1
  60. data/sample/enum/extconf.rb +0 -1
  61. data/sample/inheritance/extconf.rb +0 -1
  62. data/sample/map/extconf.rb +0 -1
  63. data/test/embed_ruby.cpp +6 -15
  64. data/test/ext/t1/extconf.rb +0 -1
  65. data/test/ext/t2/extconf.rb +0 -1
  66. data/test/extconf.rb +0 -1
  67. data/test/test_Array.cpp +20 -24
  68. data/test/test_Attribute.cpp +6 -6
  69. data/test/test_Class.cpp +8 -47
  70. data/test/test_Constructor.cpp +0 -2
  71. data/test/test_Data_Object.cpp +25 -11
  72. data/test/test_Data_Type.cpp +124 -28
  73. data/test/test_Director.cpp +12 -13
  74. data/test/test_Enum.cpp +65 -26
  75. data/test/test_Inheritance.cpp +9 -9
  76. data/test/test_Iterator.cpp +134 -5
  77. data/test/test_Keep_Alive.cpp +7 -7
  78. data/test/test_Keep_Alive_No_Wrapper.cpp +80 -0
  79. data/test/test_Memory_Management.cpp +1 -1
  80. data/test/test_Module.cpp +25 -62
  81. data/test/test_Object.cpp +75 -3
  82. data/test/test_Ownership.cpp +12 -13
  83. data/test/test_Self.cpp +12 -13
  84. data/test/test_Stl_Map.cpp +696 -0
  85. data/test/test_Stl_Optional.cpp +3 -3
  86. data/test/test_Stl_Pair.cpp +38 -2
  87. data/test/test_Stl_Reference_Wrapper.cpp +102 -0
  88. data/test/test_Stl_SmartPointer.cpp +49 -9
  89. data/test/test_Stl_String.cpp +5 -2
  90. data/test/test_Stl_Unordered_Map.cpp +697 -0
  91. data/test/test_Stl_Variant.cpp +346 -0
  92. data/test/test_Stl_Vector.cpp +200 -41
  93. data/test/test_Struct.cpp +3 -3
  94. data/test/test_To_From_Ruby.cpp +8 -2
  95. data/test/test_Tracking.cpp +239 -0
  96. data/test/unittest.hpp +21 -4
  97. metadata +24 -13
  98. data/rice/detail/Exception_Handler.hpp +0 -8
  99. data/rice/detail/Exception_Handler.ipp +0 -28
  100. data/rice/detail/Iterator.hpp +0 -23
  101. data/rice/detail/Iterator.ipp +0 -47
  102. data/rice/detail/function_traits.hpp +0 -124
  103. data/rice/detail/method_data.hpp +0 -29
  104. data/rice/detail/rice_traits.hpp +0 -116
  105. data/rice/ruby_try_catch.hpp +0 -86
@@ -3,7 +3,6 @@
3
3
  #include <rice/rice.hpp>
4
4
 
5
5
  #include <vector>
6
- #include <iostream>
7
6
 
8
7
  using namespace Rice;
9
8
 
@@ -107,7 +106,7 @@ TESTCASE(exposes_worker_as_instantiatable_class)
107
106
  .define_method("get_number", &Worker::getNumber);
108
107
 
109
108
  Module m = define_module("Testing");
110
- Object result = m.instance_eval("worker = Worker.new; worker.get_number");
109
+ Object result = m.module_eval("worker = Worker.new; worker.get_number");
111
110
 
112
111
  ASSERT_EQUAL(12, detail::From_Ruby<int>().convert(result.value()));
113
112
  }
@@ -122,7 +121,7 @@ TESTCASE(can_call_virtual_methods_on_base_class)
122
121
 
123
122
  Module m = define_module("Testing");
124
123
 
125
- Object result = m.instance_eval("worker = Worker.new; worker.do_something(4)");
124
+ Object result = m.module_eval("worker = Worker.new; worker.do_something(4)");
126
125
 
127
126
  ASSERT_EQUAL(16, detail::From_Ruby<int>().convert(result.value()));
128
127
  }
@@ -135,9 +134,9 @@ TESTCASE(super_calls_pass_execution_up_the_inheritance_chain)
135
134
  .define_method("do_something", &WorkerDirector::default_doSomething);
136
135
 
137
136
  Module m = define_module("Testing");
138
- m.instance_eval("class RubyWorker < Worker; def do_something(num); super * num; end; end");
137
+ m.module_eval("class RubyWorker < Worker; def do_something(num); super * num; end; end");
139
138
 
140
- Object result = m.instance_eval("worker = RubyWorker.new; worker.do_something(10)");
139
+ Object result = m.module_eval("worker = RubyWorker.new; worker.do_something(10)");
141
140
 
142
141
  ASSERT_EQUAL(400, detail::From_Ruby<int>().convert(result.value()));
143
142
  }
@@ -150,11 +149,11 @@ TESTCASE(super_calls_on_pure_virtual_raise_error)
150
149
  .define_method("process", &WorkerDirector::default_process);
151
150
 
152
151
  Module m = define_module("Testing");
153
- m.instance_eval("class RubyWorker < Worker; def process(num); super; end; end");
152
+ m.module_eval("class RubyWorker < Worker; def process(num); super; end; end");
154
153
 
155
154
  ASSERT_EXCEPTION_CHECK(
156
155
  Exception,
157
- m.instance_eval("worker = RubyWorker.new; worker.process(10)"),
156
+ m.module_eval("worker = RubyWorker.new; worker.process(10)"),
158
157
  ASSERT_EQUAL(
159
158
  Object(rb_eNotImpError),
160
159
  Object(CLASS_OF(ex.value()))
@@ -176,7 +175,7 @@ TESTCASE(polymorphic_calls_head_down_the_call_chain)
176
175
 
177
176
  Module m = define_module("Testing");
178
177
 
179
- m.instance_eval(
178
+ m.module_eval(
180
179
  "class EchoWorker < Worker; def process(num); num + 2; end; end;"
181
180
  "class DoubleWorker < Worker; def process(num); num * 2; end; end;"
182
181
  "$handler = Handler.new;"
@@ -184,7 +183,7 @@ TESTCASE(polymorphic_calls_head_down_the_call_chain)
184
183
  "$handler.add_worker(DoubleWorker.new);"
185
184
  );
186
185
 
187
- Object result = m.instance_eval("$handler.process_workers(5)");
186
+ Object result = m.module_eval("$handler.process_workers(5)");
188
187
 
189
188
  // Hit's EchoWorker, so 5 + 2, then passes that to DoubleWorker, so 7 * 2 = 14
190
189
  ASSERT_EQUAL(14, detail::From_Ruby<int>().convert(result.value()));
@@ -257,7 +256,7 @@ TESTCASE(mix_of_polymorphic_calls_and_inheritance_dont_cause_infinite_loops)
257
256
 
258
257
  Module m = define_module("Testing");
259
258
 
260
- Object result = m.instance_eval(
259
+ Object result = m.module_eval(
261
260
  "class MySelf < CallsSelf; def do_it_impl(num); num * 10; end; end;"
262
261
  "c = MySelf.new; c.do_it(10)"
263
262
  );
@@ -276,7 +275,7 @@ TESTCASE(director_class_super_classes_get_type_bound)
276
275
  .define_method("do_it_impl", &CallsSelfDirector::default_doItImpl)
277
276
  .define_method("do_it", &CallsSelf::doIt);
278
277
 
279
- Object result = m.instance_eval(R"(cs = Testing::get_calls_self
278
+ Object result = m.module_eval(R"(cs = Testing::get_calls_self
280
279
  cs.do_it(3))");
281
280
  ASSERT_EQUAL(36, detail::From_Ruby<int>().convert(result.value()));
282
281
  }
@@ -292,7 +291,7 @@ TESTCASE(director_allows_abstract_types_used_as_parameters_pointers)
292
291
  .define_method("do_it_impl", &CallsSelfDirector::default_doItImpl)
293
292
  .define_method("do_it", &CallsSelf::doIt);
294
293
 
295
- Object result = m.instance_eval(
294
+ Object result = m.module_eval(
296
295
  "class MySelf < CallsSelf; def do_it_impl(num); num * 10; end; end;"
297
296
  "c = MySelf.new;"
298
297
  "Testing::do_it_on_pointer(c, 5)"
@@ -312,7 +311,7 @@ TESTCASE(director_allows_abstract_types_used_as_parameters_reference)
312
311
  .define_method("do_it_impl", &CallsSelfDirector::default_doItImpl)
313
312
  .define_method("do_it", &CallsSelf::doIt);
314
313
 
315
- Object result = m.instance_eval(
314
+ Object result = m.module_eval(
316
315
  "class MySelf < CallsSelf; def do_it_impl(num); num * 10; end; end;"
317
316
  "c = MySelf.new;"
318
317
  "Testing::do_it_on_ref(c, 3)"
data/test/test_Enum.cpp CHANGED
@@ -70,7 +70,8 @@ TESTCASE(each)
70
70
  std::string code = R"(a = []
71
71
  Color.each { |x| a << x }
72
72
  a)";
73
- Array a = m.instance_eval(code);
73
+
74
+ Array a = m.module_eval(code);
74
75
  ASSERT_EQUAL(3u, a.size());
75
76
 
76
77
  Data_Object<Color> enum_0(a[0]);
@@ -83,6 +84,44 @@ TESTCASE(each)
83
84
  ASSERT_EQUAL(GREEN, *enum_2);
84
85
  }
85
86
 
87
+ TESTCASE(each_return)
88
+ {
89
+ Module m = define_module("Testing");
90
+
91
+ Enum<Color> colorEnum = define_color_enum();
92
+
93
+ std::string code = R"(Color.each {|x|})";
94
+ Object colorEnum2 = m.module_eval(code);
95
+ ASSERT_EQUAL(colorEnum2, Enum<Color>().klass());
96
+ }
97
+
98
+ TESTCASE(to_enum)
99
+ {
100
+ Module m = define_module("Testing");
101
+
102
+ Enum<Color> colorEnum = define_color_enum();
103
+
104
+ std::string code = R"(a = []
105
+ Color.each.with_index {|x, i| a << x }
106
+ a)";
107
+
108
+ Array a = m.module_eval(code);
109
+ ASSERT_EQUAL(3u, a.size());
110
+
111
+ Data_Object<Color> enum_0(a[0]);
112
+ ASSERT_EQUAL(RED, *enum_0);
113
+
114
+ Data_Object<Color> enum_1(a[1]);
115
+ ASSERT_EQUAL(BLACK, *enum_1);
116
+
117
+ Data_Object<Color> enum_2(a[2]);
118
+ ASSERT_EQUAL(GREEN, *enum_2);
119
+
120
+ code = R"(Color.each)";
121
+ Object enumerator = m.module_eval(code);
122
+ ASSERT(enumerator.is_instance_of(rb_cEnumerator));
123
+ }
124
+
86
125
  TESTCASE(each_seasons)
87
126
  {
88
127
  Module m = define_module("Testing");
@@ -92,7 +131,7 @@ TESTCASE(each_seasons)
92
131
  Season.each { |x| a << x }
93
132
  a)";
94
133
 
95
- Array a = m.instance_eval(code);
134
+ Array a = m.module_eval(code);
96
135
  ASSERT_EQUAL(4u, a.size());
97
136
 
98
137
  Data_Object<Season> enum_0(a[0]);
@@ -113,9 +152,9 @@ TESTCASE(to_s)
113
152
  Module m = define_module("Testing");
114
153
 
115
154
  Enum<Color> colorEnum = define_color_enum();
116
- ASSERT_EQUAL(String("RED"), String(m.instance_eval("Color::RED.to_s")));
117
- ASSERT_EQUAL(String("BLACK"), String(m.instance_eval("Color::BLACK.to_s")));
118
- ASSERT_EQUAL(String("GREEN"), String(m.instance_eval("Color::GREEN.to_s")));
155
+ ASSERT_EQUAL(String("RED"), String(m.module_eval("Color::RED.to_s")));
156
+ ASSERT_EQUAL(String("BLACK"), String(m.module_eval("Color::BLACK.to_s")));
157
+ ASSERT_EQUAL(String("GREEN"), String(m.module_eval("Color::GREEN.to_s")));
119
158
  }
120
159
 
121
160
  TESTCASE(to_i)
@@ -123,9 +162,9 @@ TESTCASE(to_i)
123
162
  Module m = define_module("Testing");
124
163
 
125
164
  Enum<Color> colorEnum = define_color_enum();
126
- ASSERT_EQUAL(detail::to_ruby(int(RED)), m.instance_eval("Color::RED.to_i").value());
127
- ASSERT_EQUAL(detail::to_ruby(int(BLACK)), m.instance_eval("Color::BLACK.to_i").value());
128
- ASSERT_EQUAL(detail::to_ruby(int(GREEN)), m.instance_eval("Color::GREEN.to_i").value());
165
+ ASSERT_EQUAL(detail::to_ruby(int(RED)), m.module_eval("Color::RED.to_i").value());
166
+ ASSERT_EQUAL(detail::to_ruby(int(BLACK)), m.module_eval("Color::BLACK.to_i").value());
167
+ ASSERT_EQUAL(detail::to_ruby(int(GREEN)), m.module_eval("Color::GREEN.to_i").value());
129
168
  }
130
169
 
131
170
  TESTCASE(inspect)
@@ -133,9 +172,9 @@ TESTCASE(inspect)
133
172
  Module m = define_module("Testing");
134
173
 
135
174
  Enum<Color> colorEnum = define_color_enum();
136
- ASSERT_EQUAL(String("#<Color::RED>"), String(m.instance_eval("Color::RED.inspect")));
137
- ASSERT_EQUAL(String("#<Color::BLACK>"), String(m.instance_eval("Color::BLACK.inspect")));
138
- ASSERT_EQUAL(String("#<Color::GREEN>"), String(m.instance_eval("Color::GREEN.inspect")));
175
+ ASSERT_EQUAL(String("#<Color::RED>"), String(m.module_eval("Color::RED.inspect")));
176
+ ASSERT_EQUAL(String("#<Color::BLACK>"), String(m.module_eval("Color::BLACK.inspect")));
177
+ ASSERT_EQUAL(String("#<Color::GREEN>"), String(m.module_eval("Color::GREEN.inspect")));
139
178
  }
140
179
 
141
180
  TESTCASE(compare)
@@ -143,9 +182,9 @@ TESTCASE(compare)
143
182
  Module m = define_module("Testing");
144
183
 
145
184
  Enum<Color> colorEnum = define_color_enum();
146
- ASSERT_EQUAL(detail::to_ruby(-1), m.instance_eval("Color::RED <=> Color::BLACK").value());
147
- ASSERT_EQUAL(detail::to_ruby(1), m.instance_eval("Color::GREEN <=> Color::RED").value());
148
- ASSERT_EQUAL(detail::to_ruby(0), m.instance_eval("Color::BLACK <=> Color::BLACK").value());
185
+ ASSERT_EQUAL(detail::to_ruby(-1), m.module_eval("Color::RED <=> Color::BLACK").value());
186
+ ASSERT_EQUAL(detail::to_ruby(1), m.module_eval("Color::GREEN <=> Color::RED").value());
187
+ ASSERT_EQUAL(detail::to_ruby(0), m.module_eval("Color::BLACK <=> Color::BLACK").value());
149
188
  }
150
189
 
151
190
  TESTCASE(eql)
@@ -153,8 +192,8 @@ TESTCASE(eql)
153
192
  Module m = define_module("Testing");
154
193
 
155
194
  Enum<Color> colorEnum = define_color_enum();
156
- ASSERT_EQUAL(detail::to_ruby(false), m.instance_eval("Color::RED == Color::BLACK").value());
157
- ASSERT_EQUAL(detail::to_ruby(true), m.instance_eval("Color::GREEN == Color::GREEN").value());
195
+ ASSERT_EQUAL(detail::to_ruby(false), m.module_eval("Color::RED == Color::BLACK").value());
196
+ ASSERT_EQUAL(detail::to_ruby(true), m.module_eval("Color::GREEN == Color::GREEN").value());
158
197
  }
159
198
 
160
199
  TESTCASE(compare_equal)
@@ -244,9 +283,9 @@ TESTCASE(nested_enums)
244
283
 
245
284
  Module m = define_module("Testing");
246
285
 
247
- ASSERT_EQUAL(detail::to_ruby(int(0)), m.instance_eval("Inner::Props::VALUE1.to_i").value());
248
- ASSERT_EQUAL(detail::to_ruby(int(1)), m.instance_eval("Inner::Props::VALUE2.to_i").value());
249
- ASSERT_EQUAL(detail::to_ruby(int(2)), m.instance_eval("Inner::Props::VALUE3.to_i").value());
286
+ ASSERT_EQUAL(detail::to_ruby(int(0)), m.module_eval("Inner::Props::VALUE1.to_i").value());
287
+ ASSERT_EQUAL(detail::to_ruby(int(1)), m.module_eval("Inner::Props::VALUE2.to_i").value());
288
+ ASSERT_EQUAL(detail::to_ruby(int(2)), m.module_eval("Inner::Props::VALUE3.to_i").value());
250
289
  }
251
290
 
252
291
  namespace
@@ -272,19 +311,19 @@ TESTCASE(using_enums)
272
311
 
273
312
  Module m = define_module("Testing");
274
313
 
275
- Object result = m.instance_eval("Color.my_favorite_color");
314
+ Object result = m.module_eval("Color.my_favorite_color");
276
315
  ASSERT_EQUAL(RED, detail::From_Ruby<Color>().convert(result.value()));
277
316
 
278
- result = m.instance_eval("Color.is_my_favorite_color(Color::RED)");
317
+ result = m.module_eval("Color.is_my_favorite_color(Color::RED)");
279
318
  ASSERT_EQUAL(Qtrue, result.value());
280
319
 
281
- result = m.instance_eval("Color.is_my_favorite_color(Color::BLACK)");
320
+ result = m.module_eval("Color.is_my_favorite_color(Color::BLACK)");
282
321
  ASSERT_EQUAL(Qfalse, result.value());
283
322
 
284
- result = m.instance_eval("Color::RED.is_my_favorite_color");
323
+ result = m.module_eval("Color::RED.is_my_favorite_color");
285
324
  ASSERT_EQUAL(Qtrue, result.value());
286
325
 
287
- result = m.instance_eval("Color::BLACK.is_my_favorite_color");
326
+ result = m.module_eval("Color::BLACK.is_my_favorite_color");
288
327
  ASSERT_EQUAL(Qfalse, result.value());
289
328
  }
290
329
 
@@ -301,7 +340,7 @@ TESTCASE(default_argument)
301
340
  define_global_function("default_color", &defaultColor, Arg("aColor") = Color::BLACK);
302
341
 
303
342
  Module m = define_module("Testing");
304
- Object result = m.instance_eval("default_color");
343
+ Object result = m.module_eval("default_color");
305
344
  ASSERT_EQUAL(Color::BLACK, detail::From_Ruby<Color>().convert(result.value()));
306
345
  }
307
346
 
@@ -338,4 +377,4 @@ TESTCASE(not_defined)
338
377
  define_global_function("undefined_return", &undefinedReturn),
339
378
  ASSERT_EQUAL(message, ex.what())
340
379
  );
341
- }
380
+ }
@@ -94,7 +94,7 @@ TESTCASE(return_base_pointer)
94
94
 
95
95
  Module m = define_module("Testing");
96
96
 
97
- Object notification = m.instance_eval("make_notification(NotificationType::Email)");
97
+ Object notification = m.module_eval("make_notification(NotificationType::Email)");
98
98
  String temp = notification.class_of().name();
99
99
  std::string temp2 = detail::From_Ruby<std::string>().convert(temp);
100
100
 
@@ -103,7 +103,7 @@ TESTCASE(return_base_pointer)
103
103
  ASSERT(!rb_obj_is_kind_of(notification, rcPushNotification));
104
104
  ASSERT(rb_obj_is_instance_of(notification, rcEmailNotification));
105
105
 
106
- notification = m.instance_eval("make_notification(NotificationType::Push)");
106
+ notification = m.module_eval("make_notification(NotificationType::Push)");
107
107
  ASSERT(rb_obj_is_kind_of(notification, rcNotification));
108
108
  ASSERT(!rb_obj_is_kind_of(notification, rcEmailNotification));
109
109
  ASSERT(rb_obj_is_kind_of(notification, rcPushNotification));
@@ -123,11 +123,11 @@ TESTCASE(base_pointer_method_call)
123
123
 
124
124
  Module m = define_module("Testing");
125
125
 
126
- Object message = m.instance_eval(R"EOS(notification = EmailNotification.new
126
+ Object message = m.module_eval(R"EOS(notification = EmailNotification.new
127
127
  notification.message)EOS");
128
128
  ASSERT_EQUAL("Email", detail::From_Ruby<std::string>().convert(message));
129
129
 
130
- message = m.instance_eval(R"EOS(notification = PushNotification.new
130
+ message = m.module_eval(R"EOS(notification = PushNotification.new
131
131
  notification.message)EOS");
132
132
  ASSERT_EQUAL("Push", detail::From_Ruby<std::string>().convert(message));
133
133
  }
@@ -146,11 +146,11 @@ TESTCASE(base_pointer_function_argument)
146
146
  define_global_function("process_notification", &processNotification);
147
147
 
148
148
  Module m = define_module("Testing");
149
- Object message = m.instance_eval(R"EOS(notification = EmailNotification.new
149
+ Object message = m.module_eval(R"EOS(notification = EmailNotification.new
150
150
  process_notification(notification))EOS");
151
151
  ASSERT_EQUAL("Email", detail::From_Ruby<std::string>().convert(message));
152
152
 
153
- message = m.instance_eval(R"EOS(notification = PushNotification.new
153
+ message = m.module_eval(R"EOS(notification = PushNotification.new
154
154
  process_notification(notification))EOS");
155
155
  ASSERT_EQUAL("Push", detail::From_Ruby<std::string>().convert(message));
156
156
  }
@@ -170,11 +170,11 @@ TESTCASE(module_base_pointer_method_call)
170
170
 
171
171
  Module m = define_module("Testing");
172
172
 
173
- Object message = m.instance_eval(R"EOS(notification = Inheritance::EmailNotification.new
173
+ Object message = m.module_eval(R"EOS(notification = Inheritance::EmailNotification.new
174
174
  notification.message)EOS");
175
175
  ASSERT_EQUAL("Email", detail::From_Ruby<std::string>().convert(message));
176
176
 
177
- message = m.instance_eval(R"EOS(notification = Inheritance::PushNotification.new
177
+ message = m.module_eval(R"EOS(notification = Inheritance::PushNotification.new
178
178
  notification.message)EOS");
179
179
  ASSERT_EQUAL("Push", detail::From_Ruby<std::string>().convert(message));
180
180
  }
@@ -214,7 +214,7 @@ TESTCASE(base_pointer_constructor)
214
214
 
215
215
  Module m = define_module("Testing");
216
216
 
217
- Object result = m.instance_eval(R"EOS(notification = PushNotification.new
217
+ Object result = m.module_eval(R"EOS(notification = PushNotification.new
218
218
  processor = Processor.new(notification)
219
219
  processor.process)EOS");
220
220
  ASSERT_EQUAL("Push", detail::From_Ruby<std::string>().convert(result));
@@ -55,6 +55,11 @@ namespace
55
55
  {
56
56
  struct Data
57
57
  {
58
+ Data(uint32_t value)
59
+ {
60
+ this->index = value;
61
+ }
62
+
58
63
  uint32_t index;
59
64
  };
60
65
 
@@ -76,6 +81,16 @@ namespace
76
81
  return this->data_.end();
77
82
  }
78
83
 
84
+ std::vector<Data>::const_iterator cbegin() const
85
+ {
86
+ return this->data_.cbegin();
87
+ }
88
+
89
+ std::vector<Data>::const_iterator cend() const
90
+ {
91
+ return this->data_.cend();
92
+ }
93
+
79
94
  std::vector<Data> data_;
80
95
  };
81
96
 
@@ -105,6 +120,16 @@ namespace
105
120
  return this->data_.end();
106
121
  }
107
122
 
123
+ std::vector<Data*>::reverse_iterator rbegin()
124
+ {
125
+ return this->data_.rbegin();
126
+ }
127
+
128
+ std::vector<Data*>::reverse_iterator rend()
129
+ {
130
+ return this->data_.rend();
131
+ }
132
+
108
133
  std::vector<Data*> data_;
109
134
  };
110
135
  }
@@ -144,6 +169,29 @@ TESTCASE(iterator_value)
144
169
  ASSERT_EQUAL(Object(detail::to_ruby(3)), a[2]);
145
170
  }
146
171
 
172
+ TESTCASE(const_iterator_value)
173
+ {
174
+ define_class<ContainerValues>("ContainerValues")
175
+ .define_constructor(Constructor<ContainerValues>())
176
+ .define_iterator(&ContainerValues::cbegin, &ContainerValues::cend);
177
+
178
+ Module m = define_module("TestingModule");
179
+
180
+ std::string code = R"(result = []
181
+ container = ContainerValues.new
182
+ container.each do |x|
183
+ result << x
184
+ end
185
+ result)";
186
+
187
+ Array result = m.module_eval(code);
188
+
189
+ ASSERT_EQUAL(3u, result.size());
190
+ ASSERT_EQUAL(Object(detail::to_ruby(1)), result[0]);
191
+ ASSERT_EQUAL(Object(detail::to_ruby(2)), result[1]);
192
+ ASSERT_EQUAL(Object(detail::to_ruby(3)), result[2]);
193
+ }
194
+
147
195
  TESTCASE(iterator_pointer)
148
196
  {
149
197
  define_class<ContainerPointers>("ContainerPointers")
@@ -153,9 +201,90 @@ TESTCASE(iterator_pointer)
153
201
  ContainerPointers* container = new ContainerPointers();
154
202
  Object wrapper = Data_Object<ContainerPointers>(container);
155
203
 
156
- Array a = wrapper.instance_eval("a = []; each() { |x| a << x }; a");
157
- ASSERT_EQUAL(3u, a.size());
158
- ASSERT_EQUAL(Object(detail::to_ruby(1)), a[0]);
159
- ASSERT_EQUAL(Object(detail::to_ruby(2)), a[1]);
160
- ASSERT_EQUAL(Object(detail::to_ruby(3)), a[2]);
204
+ Module m = define_module("TestingModule");
205
+
206
+ std::string code = R"(result = []
207
+ container = ContainerPointers.new
208
+ container.each do |x|
209
+ result << x
210
+ end
211
+ result)";
212
+
213
+ Array result = m.module_eval(code);
214
+
215
+ ASSERT_EQUAL(3u, result.size());
216
+ ASSERT_EQUAL(Object(detail::to_ruby(1)), result[0]);
217
+ ASSERT_EQUAL(Object(detail::to_ruby(2)), result[1]);
218
+ ASSERT_EQUAL(Object(detail::to_ruby(3)), result[2]);
161
219
  }
220
+
221
+ TESTCASE(two_iterator_pointer)
222
+ {
223
+ define_class<ContainerPointers>("ContainerPointers")
224
+ .define_constructor(Constructor<ContainerPointers>())
225
+ .define_iterator(&ContainerPointers::begin, &ContainerPointers::end)
226
+ .define_iterator(&ContainerPointers::rbegin, &ContainerPointers::rend, "reach");
227
+
228
+ ContainerPointers* container = new ContainerPointers();
229
+ Object wrapper = Data_Object<ContainerPointers>(container);
230
+
231
+ Module m = define_module("TestingModule");
232
+
233
+ std::string code = R"(result = []
234
+ container = ContainerPointers.new
235
+ container.each do |x|
236
+ result << x
237
+ end
238
+ container.reach do |x|
239
+ result << x
240
+ end
241
+ result)";
242
+
243
+ Array result = m.module_eval(code);
244
+
245
+ ASSERT_EQUAL(6u, result.size());
246
+ ASSERT_EQUAL(Object(detail::to_ruby(1)), result[0]);
247
+ ASSERT_EQUAL(Object(detail::to_ruby(2)), result[1]);
248
+ ASSERT_EQUAL(Object(detail::to_ruby(3)), result[2]);
249
+ ASSERT_EQUAL(Object(detail::to_ruby(3)), result[3]);
250
+ ASSERT_EQUAL(Object(detail::to_ruby(2)), result[4]);
251
+ ASSERT_EQUAL(Object(detail::to_ruby(1)), result[5]);
252
+ }
253
+
254
+ TESTCASE(map)
255
+ {
256
+ define_class<ContainerPointers>("ContainerPointers")
257
+ .define_constructor(Constructor<ContainerPointers>())
258
+ .define_iterator(&ContainerPointers::begin, &ContainerPointers::end);
259
+
260
+ Module m = define_module("Testing");
261
+
262
+ std::string code = R"(container = ContainerPointers.new
263
+ container.map do |x|
264
+ x * 2
265
+ end)";
266
+
267
+ Array result = m.module_eval(code);
268
+
269
+ ASSERT_EQUAL(3u, result.size());
270
+ ASSERT_EQUAL(Object(detail::to_ruby(2)), result[0]);
271
+ ASSERT_EQUAL(Object(detail::to_ruby(4)), result[1]);
272
+ ASSERT_EQUAL(Object(detail::to_ruby(6)), result[2]);
273
+ }
274
+
275
+ TESTCASE(to_enum)
276
+ {
277
+ Module m = define_module("TestingModule");
278
+
279
+ std::string code = R"(container = ContainerPointers.new
280
+ container.each.map do |x|
281
+ x * 2
282
+ end)";
283
+
284
+ Array result = m.module_eval(code);
285
+
286
+ ASSERT_EQUAL(3u, result.size());
287
+ ASSERT_EQUAL(Object(detail::to_ruby(2)), result[0]);
288
+ ASSERT_EQUAL(Object(detail::to_ruby(4)), result[1]);
289
+ ASSERT_EQUAL(Object(detail::to_ruby(6)), result[2]);
290
+ }
@@ -16,7 +16,7 @@ namespace
16
16
  };
17
17
 
18
18
  /**
19
- * This class will recieve a new Listener instance
19
+ * This class will receive a new Listener instance
20
20
  * from Ruby
21
21
  */
22
22
  class ListenerContainer
@@ -73,14 +73,14 @@ TESTCASE(test_arg)
73
73
  .define_method("listener_count", &ListenerContainer::listenerCount);
74
74
 
75
75
  Module m = define_module("TestingModule");
76
- Object handler = m.instance_eval("@handler = ListenerContainer.new");
76
+ Object handler = m.module_eval("@handler = ListenerContainer.new");
77
77
 
78
78
  ASSERT_EQUAL(INT2NUM(0), handler.call("listener_count").value());
79
79
 
80
- m.instance_eval(R"EOS(class MyListener < Listener
80
+ m.module_eval(R"EOS(class MyListener < Listener
81
81
  end)EOS");
82
82
 
83
- m.instance_eval("@handler.add_listener(MyListener.new)");
83
+ m.module_eval("@handler.add_listener(MyListener.new)");
84
84
 
85
85
  // Without keep alive, this GC will crash the program because MyListener is no longer in scope
86
86
  rb_gc_start();
@@ -90,7 +90,7 @@ TESTCASE(test_arg)
90
90
 
91
91
  // Without keep alive, this GC will crash the program because MyListener is no longer in scope
92
92
  rb_gc_start();
93
- m.instance_eval("@handler.add_listener(Listener.new)");
93
+ m.module_eval("@handler.add_listener(Listener.new)");
94
94
 
95
95
  ASSERT_EQUAL(INT2NUM(2), handler.call("listener_count").value());
96
96
  ASSERT_EQUAL(INT2NUM(8), handler.call("process").value());
@@ -139,7 +139,7 @@ namespace
139
139
 
140
140
  Object getColumn(Module& m, uint32_t index)
141
141
  {
142
- Object connection = m.instance_eval("Connection.new");
142
+ Object connection = m.module_eval("Connection.new");
143
143
  return connection.call("getColumn", 3);
144
144
  }
145
145
 
@@ -158,4 +158,4 @@ TESTCASE(test_return)
158
158
  rb_gc_start();
159
159
  String name = column.call("name");
160
160
  ASSERT_EQUAL("column_3", name.c_str());
161
- }
161
+ }
@@ -0,0 +1,80 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+ #include <rice/stl.hpp>
5
+
6
+ using namespace Rice;
7
+
8
+ TESTSUITE(Keep_Alive_No_Wrapper);
9
+
10
+ namespace
11
+ {
12
+ class Animal
13
+ {
14
+ public:
15
+ Animal(char const * name) : name_(name) {}
16
+ char const * getName() { return name_; }
17
+ virtual ~Animal() = default;
18
+ private:
19
+ char const * name_;
20
+ };
21
+
22
+ class Zoo
23
+ {
24
+ public:
25
+ Zoo(void)
26
+ {
27
+ pets_.push_back(new Animal("Bear"));
28
+ pets_.push_back(new Animal("Tiger"));
29
+ pets_.push_back(new Animal("Lion"));
30
+ }
31
+
32
+ ~Zoo()
33
+ {
34
+ for(auto pet : pets_)
35
+ {
36
+ delete pet;
37
+ }
38
+ pets_.clear();
39
+ }
40
+
41
+ Object getPets(void) {
42
+ Array pets;
43
+ for(auto p: pets_) {
44
+ pets.push(p);
45
+ }
46
+ return pets;
47
+ }
48
+
49
+ private:
50
+ std::vector<Animal*> pets_;
51
+ };
52
+ }
53
+
54
+ SETUP(Keep_Alive_No_Wrapper)
55
+ {
56
+ embed_ruby();
57
+ }
58
+
59
+ TESTCASE(test_keep_alive_no_wrapper)
60
+ {
61
+ define_class<Animal>("Animal")
62
+ .define_constructor(Constructor<Animal, char const *>())
63
+ .define_method("get_name", &Animal::getName);
64
+
65
+ define_class<Zoo>("Zoo")
66
+ .define_constructor(Constructor<Zoo>())
67
+ .define_method("get_pets", &Zoo::getPets, Return().keepAlive());
68
+
69
+ Module m = define_module("TestingModule");
70
+ Object zoo = m.module_eval("@zoo = Zoo.new");
71
+
72
+ // get_pets returns an Array (builtin type) so Return().keepAlive()
73
+ // shall result in std::runtime_error
74
+ ASSERT_EXCEPTION_CHECK(
75
+ Exception,
76
+ m.module_eval("@zoo.get_pets.each do |pet| puts pet.name; end"),
77
+ ASSERT_EQUAL("When calling the method `get_pets' we could not find the wrapper for the 'Array' return type. You should not use keepAlive() on a Return or Arg that is a builtin Rice type.",
78
+ ex.what())
79
+ );
80
+ }
@@ -44,6 +44,6 @@ TESTCASE(allows_copy_contructors_to_work)
44
44
 
45
45
  Module m = define_module("TestingModule");
46
46
 
47
- Object result = m.instance_eval("return_test_class.tmp");
47
+ Object result = m.module_eval("return_test_class.tmp");
48
48
  ASSERT_EQUAL(8.0, detail::From_Ruby<double>().convert(result.value()));
49
49
  }