rice 4.0.4 → 4.2.0

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 (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
  }