rice 4.3.3 → 4.6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +86 -26
- data/CMakeLists.txt +31 -0
- data/CMakePresets.json +75 -0
- data/COPYING +3 -2
- data/FindRuby.cmake +437 -0
- data/README.md +7 -2
- data/Rakefile +12 -5
- data/include/rice/rice.hpp +9522 -4426
- data/include/rice/stl.hpp +2831 -1198
- data/lib/make_rice_headers.rb +79 -0
- data/lib/mkmf-rice.rb +40 -94
- data/lib/rice/version.rb +3 -0
- data/lib/rice.rb +1 -0
- data/lib/rubygems/builder.rb +11 -0
- data/lib/rubygems/cmake_builder.rb +113 -0
- data/lib/rubygems_plugin.rb +9 -0
- data/rice/Address_Registration_Guard.hpp +72 -3
- data/rice/Arg.hpp +26 -6
- data/rice/Arg.ipp +35 -2
- data/rice/Buffer.hpp +123 -0
- data/rice/Buffer.ipp +599 -0
- data/rice/Callback.hpp +21 -0
- data/rice/Callback.ipp +13 -0
- data/rice/Constructor.hpp +4 -27
- data/rice/Constructor.ipp +79 -0
- data/rice/Data_Object.hpp +73 -3
- data/rice/Data_Object.ipp +388 -96
- data/rice/Data_Type.hpp +214 -3
- data/rice/Data_Type.ipp +144 -67
- data/rice/Director.hpp +0 -2
- data/rice/Enum.hpp +4 -7
- data/rice/Enum.ipp +102 -55
- data/rice/Exception.hpp +62 -2
- data/rice/Exception.ipp +7 -12
- data/rice/Init.hpp +8 -0
- data/rice/Init.ipp +8 -0
- data/rice/JumpException.hpp +44 -0
- data/rice/JumpException.ipp +48 -0
- data/rice/MemoryView.hpp +11 -0
- data/rice/MemoryView.ipp +3 -0
- data/rice/Return.hpp +7 -27
- data/rice/Return.ipp +13 -13
- data/rice/cpp_api/Array.hpp +209 -0
- data/rice/cpp_api/Array.ipp +304 -0
- data/rice/cpp_api/Builtin_Object.hpp +31 -0
- data/rice/cpp_api/Builtin_Object.ipp +37 -0
- data/rice/cpp_api/Class.hpp +70 -0
- data/rice/cpp_api/Class.ipp +97 -0
- data/rice/cpp_api/Encoding.hpp +32 -0
- data/rice/cpp_api/Encoding.ipp +59 -0
- data/rice/cpp_api/Hash.hpp +194 -0
- data/rice/cpp_api/Hash.ipp +257 -0
- data/rice/{Identifier.hpp → cpp_api/Identifier.hpp} +2 -6
- data/rice/{Identifier.ipp → cpp_api/Identifier.ipp} +4 -2
- data/rice/cpp_api/Module.hpp +72 -0
- data/rice/cpp_api/Module.ipp +101 -0
- data/rice/cpp_api/Object.hpp +272 -0
- data/rice/cpp_api/Object.ipp +235 -0
- data/rice/cpp_api/String.hpp +74 -0
- data/rice/cpp_api/String.ipp +120 -0
- data/rice/cpp_api/Struct.hpp +113 -0
- data/rice/cpp_api/Struct.ipp +92 -0
- data/rice/cpp_api/Symbol.hpp +46 -0
- data/rice/cpp_api/Symbol.ipp +93 -0
- data/rice/cpp_api/shared_methods.hpp +134 -0
- data/rice/detail/DefaultHandler.hpp +12 -0
- data/rice/detail/DefaultHandler.ipp +8 -0
- data/rice/detail/HandlerRegistry.hpp +5 -35
- data/rice/detail/HandlerRegistry.ipp +7 -11
- data/rice/detail/InstanceRegistry.hpp +1 -4
- data/rice/detail/MethodInfo.hpp +12 -10
- data/rice/detail/MethodInfo.ipp +26 -21
- data/rice/detail/Native.hpp +33 -0
- data/rice/detail/Native.ipp +157 -0
- data/rice/detail/NativeAttributeGet.hpp +52 -0
- data/rice/detail/NativeAttributeGet.ipp +57 -0
- data/rice/detail/NativeAttributeSet.hpp +44 -0
- data/rice/detail/NativeAttributeSet.ipp +88 -0
- data/rice/detail/NativeCallbackFFI.hpp +55 -0
- data/rice/detail/NativeCallbackFFI.ipp +151 -0
- data/rice/detail/NativeCallbackSimple.hpp +30 -0
- data/rice/detail/NativeCallbackSimple.ipp +29 -0
- data/rice/detail/NativeFunction.hpp +33 -23
- data/rice/detail/NativeFunction.ipp +309 -70
- data/rice/detail/NativeIterator.hpp +9 -11
- data/rice/detail/NativeIterator.ipp +33 -31
- data/rice/detail/NativeRegistry.hpp +24 -15
- data/rice/detail/NativeRegistry.ipp +23 -48
- data/rice/detail/Proc.hpp +4 -0
- data/rice/detail/Proc.ipp +85 -0
- data/rice/detail/Registries.hpp +0 -7
- data/rice/detail/Registries.ipp +0 -18
- data/rice/detail/RubyFunction.hpp +0 -3
- data/rice/detail/RubyFunction.ipp +4 -8
- data/rice/detail/RubyType.hpp +16 -0
- data/rice/detail/RubyType.ipp +232 -0
- data/rice/detail/Type.hpp +7 -6
- data/rice/detail/Type.ipp +192 -45
- data/rice/detail/TypeRegistry.hpp +15 -7
- data/rice/detail/TypeRegistry.ipp +105 -12
- data/rice/detail/Wrapper.hpp +68 -32
- data/rice/detail/Wrapper.ipp +121 -109
- data/rice/detail/cpp_protect.hpp +5 -6
- data/rice/detail/default_allocation_func.ipp +0 -2
- data/rice/detail/from_ruby.hpp +38 -3
- data/rice/detail/from_ruby.ipp +1321 -492
- data/rice/detail/ruby.hpp +18 -0
- data/rice/detail/to_ruby.hpp +41 -3
- data/rice/detail/to_ruby.ipp +1424 -194
- data/rice/global_function.hpp +0 -4
- data/rice/global_function.ipp +0 -1
- data/rice/libc/file.hpp +11 -0
- data/rice/libc/file.ipp +32 -0
- data/rice/rice.hpp +116 -26
- data/rice/ruby_mark.hpp +4 -3
- data/rice/stl/complex.hpp +6 -0
- data/rice/stl/complex.ipp +93 -0
- data/rice/stl/exception.hpp +11 -0
- data/rice/stl/exception.ipp +29 -0
- data/rice/stl/exception_ptr.hpp +6 -0
- data/rice/stl/exception_ptr.ipp +27 -0
- data/rice/stl/map.hpp +12 -0
- data/rice/stl/map.ipp +469 -0
- data/rice/stl/monostate.hpp +6 -0
- data/rice/stl/monostate.ipp +80 -0
- data/rice/stl/multimap.hpp +14 -0
- data/rice/stl/multimap.ipp +448 -0
- data/rice/stl/optional.hpp +6 -0
- data/rice/stl/optional.ipp +118 -0
- data/rice/stl/pair.hpp +13 -0
- data/rice/stl/pair.ipp +155 -0
- data/rice/stl/reference_wrapper.hpp +6 -0
- data/rice/stl/reference_wrapper.ipp +41 -0
- data/rice/stl/set.hpp +12 -0
- data/rice/stl/set.ipp +495 -0
- data/rice/stl/shared_ptr.hpp +28 -0
- data/rice/stl/shared_ptr.ipp +224 -0
- data/rice/stl/string.hpp +6 -0
- data/rice/stl/string.ipp +158 -0
- data/rice/stl/string_view.hpp +6 -0
- data/rice/stl/string_view.ipp +65 -0
- data/rice/stl/tuple.hpp +6 -0
- data/rice/stl/tuple.ipp +128 -0
- data/rice/stl/type_index.hpp +6 -0
- data/rice/stl/type_index.ipp +30 -0
- data/rice/stl/type_info.hpp +6 -0
- data/rice/stl/type_info.ipp +29 -0
- data/rice/stl/unique_ptr.hpp +22 -0
- data/rice/stl/unique_ptr.ipp +139 -0
- data/rice/stl/unordered_map.hpp +12 -0
- data/rice/stl/unordered_map.ipp +469 -0
- data/rice/stl/variant.hpp +6 -0
- data/rice/stl/variant.ipp +242 -0
- data/rice/stl/vector.hpp +12 -0
- data/rice/stl/vector.ipp +590 -0
- data/rice/stl.hpp +11 -3
- data/rice/traits/attribute_traits.hpp +26 -0
- data/rice/traits/function_traits.hpp +95 -0
- data/rice/traits/method_traits.hpp +47 -0
- data/rice/traits/rice_traits.hpp +160 -0
- data/rice.gemspec +85 -0
- data/test/embed_ruby.cpp +7 -1
- data/test/extconf.rb +2 -0
- data/test/test_Address_Registration_Guard.cpp +5 -0
- data/test/test_Array.cpp +18 -4
- data/test/test_Attribute.cpp +136 -21
- data/test/test_Buffer.cpp +285 -0
- data/test/test_Builtin_Object.cpp +5 -0
- data/test/test_Callback.cpp +230 -0
- data/test/test_Class.cpp +5 -31
- data/test/test_Constructor.cpp +69 -6
- data/test/test_Data_Object.cpp +97 -38
- data/test/test_Data_Type.cpp +470 -65
- data/test/test_Director.cpp +17 -8
- data/test/test_Enum.cpp +155 -40
- data/test/test_Exception.cpp +235 -0
- data/test/test_File.cpp +70 -0
- data/test/test_From_Ruby.cpp +609 -0
- data/test/test_Hash.cpp +5 -0
- data/test/test_Identifier.cpp +5 -0
- data/test/test_Inheritance.cpp +6 -1
- data/test/test_Iterator.cpp +6 -1
- data/test/test_Jump_Exception.cpp +23 -0
- data/test/test_Keep_Alive.cpp +13 -19
- data/test/test_Keep_Alive_No_Wrapper.cpp +5 -1
- data/test/test_Memory_Management.cpp +5 -0
- data/test/test_Module.cpp +128 -67
- data/test/test_Native_Registry.cpp +2 -34
- data/test/test_Object.cpp +5 -0
- data/test/test_Overloads.cpp +806 -0
- data/test/test_Ownership.cpp +160 -54
- data/test/test_Proc.cpp +44 -0
- data/test/test_Self.cpp +9 -4
- data/test/test_Stl_Exception.cpp +109 -0
- data/test/test_Stl_Map.cpp +54 -42
- data/test/test_Stl_Multimap.cpp +693 -0
- data/test/test_Stl_Optional.cpp +5 -0
- data/test/test_Stl_Pair.cpp +14 -9
- data/test/test_Stl_Reference_Wrapper.cpp +9 -2
- data/test/test_Stl_Set.cpp +790 -0
- data/test/test_Stl_SharedPtr.cpp +458 -0
- data/test/test_Stl_String.cpp +5 -0
- data/test/test_Stl_String_View.cpp +5 -0
- data/test/test_Stl_Tuple.cpp +116 -0
- data/test/test_Stl_Type.cpp +147 -0
- data/test/test_Stl_UniquePtr.cpp +202 -0
- data/test/test_Stl_Unordered_Map.cpp +43 -38
- data/test/test_Stl_Variant.cpp +217 -84
- data/test/test_Stl_Vector.cpp +306 -58
- data/test/test_String.cpp +5 -0
- data/test/test_Struct.cpp +5 -0
- data/test/test_Symbol.cpp +5 -0
- data/test/test_Template.cpp +192 -0
- data/test/test_To_Ruby.cpp +524 -0
- data/test/test_Tracking.cpp +1 -0
- data/test/test_Type.cpp +171 -0
- data/test/test_global_functions.cpp +67 -7
- data/test/unittest.cpp +8 -0
- metadata +127 -26
- data/lib/version.rb +0 -3
- data/rice/Address_Registration_Guard_defn.hpp +0 -79
- data/rice/Data_Object_defn.hpp +0 -84
- data/rice/Data_Type_defn.hpp +0 -190
- data/rice/Exception_defn.hpp +0 -68
- data/rice/HandlerRegistration.hpp +0 -15
- data/rice/detail/ExceptionHandler.hpp +0 -8
- data/rice/detail/ExceptionHandler.ipp +0 -28
- data/rice/detail/ExceptionHandler_defn.hpp +0 -77
- data/rice/detail/Jump_Tag.hpp +0 -21
- data/rice/detail/NativeAttribute.hpp +0 -64
- data/rice/detail/NativeAttribute.ipp +0 -112
- data/rice/detail/from_ruby_defn.hpp +0 -38
- data/rice/detail/to_ruby_defn.hpp +0 -48
- data/test/test_Jump_Tag.cpp +0 -17
- data/test/test_Stl_SmartPointer.cpp +0 -283
- data/test/test_To_From_Ruby.cpp +0 -399
data/test/test_Enum.cpp
CHANGED
@@ -9,19 +9,21 @@ using namespace Rice;
|
|
9
9
|
|
10
10
|
TESTSUITE(Enum);
|
11
11
|
|
12
|
+
SETUP(Enum)
|
13
|
+
{
|
14
|
+
embed_ruby();
|
15
|
+
}
|
16
|
+
|
17
|
+
TEARDOWN(Enum)
|
18
|
+
{
|
19
|
+
Rice::detail::Registries::instance.types.clearUnverifiedTypes();
|
20
|
+
rb_gc_start();
|
21
|
+
}
|
22
|
+
|
12
23
|
namespace
|
13
24
|
{
|
14
25
|
enum Color { RED, BLACK, GREEN };
|
15
26
|
|
16
|
-
Enum<Color> define_color_enum()
|
17
|
-
{
|
18
|
-
static Enum<Color> colors = define_enum<Color>("Color")
|
19
|
-
.define_value("RED", RED)
|
20
|
-
.define_value("BLACK", BLACK)
|
21
|
-
.define_value("GREEN", GREEN);
|
22
|
-
return colors;
|
23
|
-
}
|
24
|
-
|
25
27
|
enum class Season { Spring, Summer, Fall, Winter };
|
26
28
|
|
27
29
|
// This is needed to make unittest compile (it uses ostream to report errors)
|
@@ -30,22 +32,26 @@ namespace
|
|
30
32
|
os << static_cast<std::underlying_type_t<Season>>(season);
|
31
33
|
return os;
|
32
34
|
}
|
35
|
+
}
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
return seasons;
|
43
|
-
}
|
37
|
+
Enum<Color> define_color_enum()
|
38
|
+
{
|
39
|
+
static Enum<Color> colors = define_enum<Color>("Color")
|
40
|
+
.define_value("RED", RED)
|
41
|
+
.define_value("BLACK", BLACK)
|
42
|
+
.define_value("GREEN", GREEN);
|
43
|
+
return colors;
|
44
44
|
}
|
45
45
|
|
46
|
-
|
46
|
+
Enum<Season> define_season_enum()
|
47
47
|
{
|
48
|
-
|
48
|
+
static Enum<Season> seasons = define_enum<Season>("Season")
|
49
|
+
.define_value("Spring", Season::Spring)
|
50
|
+
.define_value("Summer", Season::Summer)
|
51
|
+
.define_value("Fall", Season::Fall)
|
52
|
+
.define_value("Winter", Season::Winter);
|
53
|
+
|
54
|
+
return seasons;
|
49
55
|
}
|
50
56
|
|
51
57
|
TESTCASE(copy_construct)
|
@@ -147,6 +153,48 @@ TESTCASE(each_seasons)
|
|
147
153
|
ASSERT_EQUAL(Season::Winter, *enum_3);
|
148
154
|
}
|
149
155
|
|
156
|
+
TESTCASE(bitset_operators)
|
157
|
+
{
|
158
|
+
Module m = define_module("TestingBitsetOperators");
|
159
|
+
|
160
|
+
Enum<Season> rb_cSeason = define_season_enum();
|
161
|
+
|
162
|
+
std::string code = R"(Season::Summer & Season::Winter)";
|
163
|
+
Object value = m.module_eval(code);
|
164
|
+
ASSERT_EQUAL(1, detail::From_Ruby<int>().convert(value));
|
165
|
+
|
166
|
+
code = R"(Season::Spring | Season::Summer)";
|
167
|
+
value = m.module_eval(code);
|
168
|
+
ASSERT_EQUAL(1, detail::From_Ruby<int>().convert(value));
|
169
|
+
|
170
|
+
code = R"(Season::Spring | Season::Summer | Season::Fall)";
|
171
|
+
value = m.module_eval(code);
|
172
|
+
ASSERT_EQUAL(3, detail::From_Ruby<int>().convert(value));
|
173
|
+
|
174
|
+
code = R"(Season::Summer ^ Season::Winter)";
|
175
|
+
value = m.module_eval(code);
|
176
|
+
ASSERT_EQUAL(2, detail::From_Ruby<int>().convert(value));
|
177
|
+
|
178
|
+
code = R"(~Season::Winter)";
|
179
|
+
value = m.module_eval(code);
|
180
|
+
ASSERT_EQUAL(-4, detail::From_Ruby<int>().convert(value));
|
181
|
+
}
|
182
|
+
|
183
|
+
TESTCASE(shift_operators)
|
184
|
+
{
|
185
|
+
Module m = define_module("TestingShiftOperators");
|
186
|
+
|
187
|
+
Enum<Season> rb_cSeason = define_season_enum();
|
188
|
+
|
189
|
+
std::string code = R"(Season::Winter << 1)";
|
190
|
+
Object value = m.module_eval(code);
|
191
|
+
ASSERT_EQUAL(6, detail::From_Ruby<int>().convert(value));
|
192
|
+
|
193
|
+
code = R"(Season::Winter >> 1)";
|
194
|
+
value = m.module_eval(code);
|
195
|
+
ASSERT_EQUAL(1, detail::From_Ruby<int>().convert(value));
|
196
|
+
}
|
197
|
+
|
150
198
|
TESTCASE(to_s)
|
151
199
|
{
|
152
200
|
Module m = define_module("Testing");
|
@@ -157,14 +205,14 @@ TESTCASE(to_s)
|
|
157
205
|
ASSERT_EQUAL(String("GREEN"), String(m.module_eval("Color::GREEN.to_s")));
|
158
206
|
}
|
159
207
|
|
160
|
-
TESTCASE(
|
208
|
+
TESTCASE(to_int)
|
161
209
|
{
|
162
210
|
Module m = define_module("Testing");
|
163
211
|
|
164
212
|
Enum<Color> colorEnum = define_color_enum();
|
165
|
-
ASSERT_EQUAL(detail::to_ruby(int(RED)), m.module_eval("Color::RED.
|
166
|
-
ASSERT_EQUAL(detail::to_ruby(int(BLACK)), m.module_eval("Color::BLACK.
|
167
|
-
ASSERT_EQUAL(detail::to_ruby(int(GREEN)), m.module_eval("Color::GREEN.
|
213
|
+
ASSERT_EQUAL(detail::to_ruby(int(RED)), m.module_eval("Color::RED.to_int").value());
|
214
|
+
ASSERT_EQUAL(detail::to_ruby(int(BLACK)), m.module_eval("Color::BLACK.to_int").value());
|
215
|
+
ASSERT_EQUAL(detail::to_ruby(int(GREEN)), m.module_eval("Color::GREEN.to_int").value());
|
168
216
|
}
|
169
217
|
|
170
218
|
TESTCASE(inspect)
|
@@ -275,7 +323,7 @@ namespace
|
|
275
323
|
TESTCASE(nested_enums)
|
276
324
|
{
|
277
325
|
Data_Type<Inner> inner = define_class<Inner>("Inner");
|
278
|
-
|
326
|
+
define_enum_under<Inner::Props>("Props", inner)
|
279
327
|
.define_value("VALUE1", Inner::VALUE1)
|
280
328
|
.define_value("VALUE2", Inner::VALUE2)
|
281
329
|
.define_value("VALUE3", Inner::VALUE3);
|
@@ -283,9 +331,9 @@ TESTCASE(nested_enums)
|
|
283
331
|
|
284
332
|
Module m = define_module("Testing");
|
285
333
|
|
286
|
-
ASSERT_EQUAL(detail::to_ruby(int(0)), m.module_eval("Inner::Props::VALUE1.
|
287
|
-
ASSERT_EQUAL(detail::to_ruby(int(1)), m.module_eval("Inner::Props::VALUE2.
|
288
|
-
ASSERT_EQUAL(detail::to_ruby(int(2)), m.module_eval("Inner::Props::VALUE3.
|
334
|
+
ASSERT_EQUAL(detail::to_ruby(int(0)), m.module_eval("Inner::Props::VALUE1.to_int").value());
|
335
|
+
ASSERT_EQUAL(detail::to_ruby(int(1)), m.module_eval("Inner::Props::VALUE2.to_int").value());
|
336
|
+
ASSERT_EQUAL(detail::to_ruby(int(2)), m.module_eval("Inner::Props::VALUE3.to_int").value());
|
289
337
|
}
|
290
338
|
|
291
339
|
namespace
|
@@ -295,9 +343,14 @@ namespace
|
|
295
343
|
return RED;
|
296
344
|
}
|
297
345
|
|
298
|
-
bool isMyFavoriteColor(Color
|
346
|
+
bool isMyFavoriteColor(Color color)
|
299
347
|
{
|
300
|
-
return
|
348
|
+
return color == RED;
|
349
|
+
}
|
350
|
+
|
351
|
+
bool myFavoriteColorAsInt(int color)
|
352
|
+
{
|
353
|
+
return color == RED;
|
301
354
|
}
|
302
355
|
}
|
303
356
|
|
@@ -305,9 +358,8 @@ TESTCASE(using_enums)
|
|
305
358
|
{
|
306
359
|
Enum<Color> colorEnum = define_color_enum();
|
307
360
|
colorEnum.define_singleton_function("my_favorite_color", &myFavoriteColor)
|
308
|
-
|
309
|
-
|
310
|
-
.define_method("is_my_favorite_color", &isMyFavoriteColor);
|
361
|
+
.define_singleton_function("is_my_favorite_color", &isMyFavoriteColor)
|
362
|
+
.define_method("is_my_favorite_color", &isMyFavoriteColor);
|
311
363
|
|
312
364
|
Module m = define_module("Testing");
|
313
365
|
|
@@ -327,6 +379,46 @@ TESTCASE(using_enums)
|
|
327
379
|
ASSERT_EQUAL(Qfalse, result.value());
|
328
380
|
}
|
329
381
|
|
382
|
+
TESTCASE(enum_to_int)
|
383
|
+
{
|
384
|
+
Enum<Color> colorEnum = define_color_enum();
|
385
|
+
|
386
|
+
Module m = define_module("Testing");
|
387
|
+
m.define_module_function("my_favorite_color_as_int", &myFavoriteColorAsInt);
|
388
|
+
|
389
|
+
std::string code = R"(my_favorite_color_as_int(Color::RED))";
|
390
|
+
Object result = m.module_eval(code);
|
391
|
+
ASSERT_EQUAL(Qtrue, result.value());
|
392
|
+
|
393
|
+
code = R"(my_favorite_color_as_int(Color::GREEN))";
|
394
|
+
result = m.module_eval(code);
|
395
|
+
ASSERT_EQUAL(Qfalse, result.value());
|
396
|
+
}
|
397
|
+
|
398
|
+
namespace
|
399
|
+
{
|
400
|
+
bool isMyFavoriteSeasonAsInt(int season)
|
401
|
+
{
|
402
|
+
return ((Season)season == Season::Summer);
|
403
|
+
}
|
404
|
+
}
|
405
|
+
|
406
|
+
TESTCASE(enum_class_to_int)
|
407
|
+
{
|
408
|
+
define_season_enum();
|
409
|
+
|
410
|
+
Module m = define_module("Testing");
|
411
|
+
m.define_module_function("is_my_favorite_season_as_int", &isMyFavoriteSeasonAsInt);
|
412
|
+
|
413
|
+
std::string code = R"(is_my_favorite_season_as_int(Season::Spring))";
|
414
|
+
Object result = m.module_eval(code);
|
415
|
+
ASSERT_EQUAL(Qfalse, result.value());
|
416
|
+
|
417
|
+
code = R"(is_my_favorite_season_as_int(Season::Summer))";
|
418
|
+
result = m.module_eval(code);
|
419
|
+
ASSERT_EQUAL(Qtrue, result.value());
|
420
|
+
}
|
421
|
+
|
330
422
|
namespace
|
331
423
|
{
|
332
424
|
Color defaultColor(Color aColor = BLACK)
|
@@ -360,21 +452,44 @@ namespace
|
|
360
452
|
|
361
453
|
TESTCASE(not_defined)
|
362
454
|
{
|
455
|
+
Module m = define_module("TestingEnumNotDefined");
|
456
|
+
|
363
457
|
#ifdef _MSC_VER
|
364
|
-
const char* message = "
|
458
|
+
const char* message = "The following types are not registered with Rice:\n enum `anonymous namespace'::Undefined\n";
|
365
459
|
#else
|
366
|
-
const char* message = "
|
460
|
+
const char* message = "The following types are not registered with Rice:\n (anonymous namespace)::Undefined\n";
|
367
461
|
#endif
|
368
462
|
|
463
|
+
m.define_module_function("undefined_arg", &undefinedArg);
|
464
|
+
|
369
465
|
ASSERT_EXCEPTION_CHECK(
|
370
466
|
std::invalid_argument,
|
371
|
-
|
467
|
+
Rice::detail::Registries::instance.types.validateTypes(),
|
468
|
+
ASSERT_EQUAL(message, ex.what())
|
469
|
+
);
|
470
|
+
|
471
|
+
#ifdef _MSC_VER
|
472
|
+
message = "Type is not registered with Rice: enum `anonymous namespace'::Undefined";
|
473
|
+
#else
|
474
|
+
message = "Type is not registered with Rice: (anonymous namespace)::Undefined";
|
475
|
+
#endif
|
476
|
+
|
477
|
+
m.define_module_function("undefined_return", &undefinedReturn);
|
478
|
+
ASSERT_EXCEPTION_CHECK(
|
479
|
+
Rice::Exception,
|
480
|
+
m.call("undefined_return"),
|
372
481
|
ASSERT_EQUAL(message, ex.what())
|
373
482
|
);
|
374
483
|
|
484
|
+
#ifdef _MSC_VER
|
485
|
+
message = "Type is not defined with Rice: enum `anonymous namespace'::Undefined";
|
486
|
+
#else
|
487
|
+
message = "Type is not defined with Rice: (anonymous namespace)::Undefined";
|
488
|
+
#endif
|
489
|
+
|
375
490
|
ASSERT_EXCEPTION_CHECK(
|
376
|
-
|
377
|
-
|
491
|
+
Rice::Exception,
|
492
|
+
m.call("undefined_arg", 1),
|
378
493
|
ASSERT_EQUAL(message, ex.what())
|
379
494
|
);
|
380
|
-
}
|
495
|
+
}
|
data/test/test_Exception.cpp
CHANGED
@@ -11,6 +11,11 @@ SETUP(Exception)
|
|
11
11
|
embed_ruby();
|
12
12
|
}
|
13
13
|
|
14
|
+
TEARDOWN(Exception)
|
15
|
+
{
|
16
|
+
rb_gc_start();
|
17
|
+
}
|
18
|
+
|
14
19
|
TESTCASE(construct_from_exception_object)
|
15
20
|
{
|
16
21
|
VALUE v = detail::protect(rb_exc_new2, rb_eRuntimeError, "foo");
|
@@ -45,3 +50,233 @@ TESTCASE(what)
|
|
45
50
|
ASSERT_EQUAL(foo, ex.what());
|
46
51
|
}
|
47
52
|
|
53
|
+
namespace
|
54
|
+
{
|
55
|
+
enum class ErrorCode
|
56
|
+
{
|
57
|
+
MEMORY,
|
58
|
+
DISK,
|
59
|
+
CPU
|
60
|
+
};
|
61
|
+
|
62
|
+
class CustomException
|
63
|
+
{
|
64
|
+
public:
|
65
|
+
CustomException(ErrorCode code) : code(code)
|
66
|
+
{
|
67
|
+
}
|
68
|
+
|
69
|
+
const char* what() const noexcept
|
70
|
+
{
|
71
|
+
return "My custom exception occurred!";
|
72
|
+
}
|
73
|
+
|
74
|
+
ErrorCode code;
|
75
|
+
};
|
76
|
+
|
77
|
+
void raiseCustomException(ErrorCode code)
|
78
|
+
{
|
79
|
+
throw CustomException(code);
|
80
|
+
}
|
81
|
+
|
82
|
+
class MyExceptionHandler
|
83
|
+
{
|
84
|
+
public:
|
85
|
+
void operator()()
|
86
|
+
{
|
87
|
+
try
|
88
|
+
{
|
89
|
+
throw;
|
90
|
+
}
|
91
|
+
catch (const CustomException& exception)
|
92
|
+
{
|
93
|
+
Data_Object<CustomException> wrapper(exception, true);
|
94
|
+
rb_exc_raise(wrapper);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
};
|
98
|
+
}
|
99
|
+
|
100
|
+
Enum<ErrorCode> define_error_code_enum()
|
101
|
+
{
|
102
|
+
static Enum<ErrorCode> errorCodes = define_enum<ErrorCode>("ErrorCode")
|
103
|
+
.define_value("MEMORY", ErrorCode::MEMORY)
|
104
|
+
.define_value("DISK", ErrorCode::DISK)
|
105
|
+
.define_value("CPU", ErrorCode::CPU);
|
106
|
+
|
107
|
+
return errorCodes;
|
108
|
+
}
|
109
|
+
|
110
|
+
TESTCASE(default_handler)
|
111
|
+
{
|
112
|
+
define_error_code_enum();
|
113
|
+
Module m = define_module("Testing");
|
114
|
+
m.define_singleton_function("raise_custom_exception", &raiseCustomException);
|
115
|
+
Class MyExceptionClass = define_class_under<CustomException>(rb_cObject, "CustomException", rb_eStandardError).
|
116
|
+
define_method("message", &CustomException::what);
|
117
|
+
|
118
|
+
ASSERT_EXCEPTION_CHECK(
|
119
|
+
Exception,
|
120
|
+
m.call("raise_custom_exception", ErrorCode::MEMORY),
|
121
|
+
ASSERT_EQUAL("Unknown C++ exception thrown", ex.what())
|
122
|
+
);
|
123
|
+
}
|
124
|
+
|
125
|
+
TESTCASE(custom_handler_functor)
|
126
|
+
{
|
127
|
+
define_error_code_enum();
|
128
|
+
Class MyExceptionClass = define_class_under<CustomException>(rb_cObject, "CustomException", rb_eStandardError).
|
129
|
+
define_method("message", &CustomException::what);
|
130
|
+
|
131
|
+
detail::Registries::instance.handlers.set(MyExceptionHandler());
|
132
|
+
|
133
|
+
Module m = define_module("Testing");
|
134
|
+
m.define_singleton_function("raise_custom_exception", &raiseCustomException);
|
135
|
+
|
136
|
+
ASSERT_EXCEPTION_CHECK(
|
137
|
+
Exception,
|
138
|
+
m.call("raise_custom_exception", ErrorCode::DISK),
|
139
|
+
ASSERT_EQUAL("My custom exception occurred!", ex.what())
|
140
|
+
);
|
141
|
+
|
142
|
+
std::string code = R"(begin
|
143
|
+
raise_custom_exception(ErrorCode::DISK)
|
144
|
+
rescue CustomException => exception
|
145
|
+
"Caught in Ruby"
|
146
|
+
end)";
|
147
|
+
|
148
|
+
String string = m.instance_eval(code);
|
149
|
+
ASSERT_EQUAL("Caught in Ruby", string.c_str());
|
150
|
+
}
|
151
|
+
|
152
|
+
TESTCASE(custom_handler_lambda)
|
153
|
+
{
|
154
|
+
define_error_code_enum();
|
155
|
+
Class rb_eCustomException = define_class("CustomException", rb_eStandardError).
|
156
|
+
define_method("message", &CustomException::what);
|
157
|
+
|
158
|
+
auto handler = []()
|
159
|
+
{
|
160
|
+
try
|
161
|
+
{
|
162
|
+
throw;
|
163
|
+
}
|
164
|
+
catch (const CustomException& exception)
|
165
|
+
{
|
166
|
+
Data_Object<CustomException> wrapper(exception);
|
167
|
+
rb_exc_raise(wrapper);
|
168
|
+
}
|
169
|
+
};
|
170
|
+
|
171
|
+
detail::Registries::instance.handlers.set(handler);
|
172
|
+
|
173
|
+
Module m = define_module("Testing");
|
174
|
+
m.define_singleton_function("raise_custom_exception", &raiseCustomException);
|
175
|
+
|
176
|
+
ASSERT_EXCEPTION_CHECK(
|
177
|
+
Exception,
|
178
|
+
m.call("raise_custom_exception", ErrorCode::CPU),
|
179
|
+
ASSERT_EQUAL("My custom exception occurred!", ex.what())
|
180
|
+
);
|
181
|
+
|
182
|
+
std::string code = R"(begin
|
183
|
+
raise_custom_exception(ErrorCode::CPU)
|
184
|
+
rescue CustomException => exception
|
185
|
+
$!
|
186
|
+
end)";
|
187
|
+
|
188
|
+
Object object = m.instance_eval(code);
|
189
|
+
ASSERT_EQUAL(rb_eCustomException.value(), object.class_of().value());
|
190
|
+
}
|
191
|
+
|
192
|
+
TESTCASE(subclasses)
|
193
|
+
{
|
194
|
+
define_error_code_enum();
|
195
|
+
Class rb_eCustomException = define_class("CustomException", rb_eStandardError).
|
196
|
+
define_method("message", &CustomException::what);
|
197
|
+
Class rb_eMemoryException = define_class_under(rb_cObject, "MemoryException", rb_eCustomException);
|
198
|
+
Class rb_eDiskException = define_class_under(rb_cObject, "DiskException", rb_eCustomException);
|
199
|
+
Class rb_eCpuException = define_class_under(rb_cObject, "CpuException", rb_eCustomException);
|
200
|
+
|
201
|
+
auto handler = [&]()
|
202
|
+
{
|
203
|
+
try
|
204
|
+
{
|
205
|
+
throw;
|
206
|
+
}
|
207
|
+
catch (const CustomException& exception)
|
208
|
+
{
|
209
|
+
Class exceptionKlass = rb_eCustomException;
|
210
|
+
|
211
|
+
switch (exception.code)
|
212
|
+
{
|
213
|
+
case ErrorCode::MEMORY:
|
214
|
+
exceptionKlass = rb_eMemoryException;
|
215
|
+
break;
|
216
|
+
case ErrorCode::DISK:
|
217
|
+
exceptionKlass = rb_eDiskException;
|
218
|
+
break;
|
219
|
+
case ErrorCode::CPU:
|
220
|
+
exceptionKlass = rb_eCpuException;
|
221
|
+
break;
|
222
|
+
}
|
223
|
+
|
224
|
+
// Take ownership of the exception object and map it to the right subclass
|
225
|
+
Data_Object<CustomException> wrapper(exception, true, exceptionKlass);
|
226
|
+
rb_exc_raise(wrapper);
|
227
|
+
}
|
228
|
+
};
|
229
|
+
|
230
|
+
detail::Registries::instance.handlers.set(handler);
|
231
|
+
|
232
|
+
Module m = define_module("Testing");
|
233
|
+
m.define_singleton_function("raise_custom_exception", &raiseCustomException);
|
234
|
+
|
235
|
+
std::string code = R"(begin
|
236
|
+
raise_custom_exception(ErrorCode::MEMORY)
|
237
|
+
rescue => e
|
238
|
+
e.class.name
|
239
|
+
end)";
|
240
|
+
|
241
|
+
String result = m.instance_eval(code);
|
242
|
+
ASSERT_EQUAL("MemoryException", result.c_str());
|
243
|
+
|
244
|
+
code = R"(begin
|
245
|
+
raise_custom_exception(ErrorCode::MEMORY)
|
246
|
+
rescue MemoryException => e
|
247
|
+
e.class.name
|
248
|
+
end)";
|
249
|
+
|
250
|
+
result = m.instance_eval(code);
|
251
|
+
ASSERT_EQUAL("MemoryException", result.c_str());
|
252
|
+
|
253
|
+
code = R"(begin
|
254
|
+
raise_custom_exception(ErrorCode::DISK)
|
255
|
+
rescue DiskException => e
|
256
|
+
e.class.name
|
257
|
+
end)";
|
258
|
+
|
259
|
+
result = m.instance_eval(code);
|
260
|
+
ASSERT_EQUAL("DiskException", result.c_str());
|
261
|
+
|
262
|
+
code = R"(begin
|
263
|
+
raise_custom_exception(ErrorCode::CPU)
|
264
|
+
rescue CpuException => e
|
265
|
+
e.class.name
|
266
|
+
end)";
|
267
|
+
|
268
|
+
result = m.instance_eval(code);
|
269
|
+
ASSERT_EQUAL("CpuException", result.c_str());
|
270
|
+
|
271
|
+
code = R"(begin
|
272
|
+
raise_custom_exception(ErrorCode::CPU)
|
273
|
+
rescue RuntimeError => e
|
274
|
+
e.class.name
|
275
|
+
end)";
|
276
|
+
|
277
|
+
ASSERT_EXCEPTION_CHECK(
|
278
|
+
Exception,
|
279
|
+
m.instance_eval(code),
|
280
|
+
ASSERT_EQUAL("My custom exception occurred!", ex.what())
|
281
|
+
);
|
282
|
+
}
|
data/test/test_File.cpp
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#include <cstdio>
|
2
|
+
#include <filesystem>
|
3
|
+
|
4
|
+
#include "unittest.hpp"
|
5
|
+
#include "embed_ruby.hpp"
|
6
|
+
#include <rice/rice.hpp>
|
7
|
+
#include <rice/stl.hpp>
|
8
|
+
|
9
|
+
using namespace Rice;
|
10
|
+
|
11
|
+
TESTSUITE(FILE);
|
12
|
+
|
13
|
+
SETUP(FILE)
|
14
|
+
{
|
15
|
+
embed_ruby();
|
16
|
+
}
|
17
|
+
|
18
|
+
TEARDOWN(FILE)
|
19
|
+
{
|
20
|
+
rb_gc_start();
|
21
|
+
}
|
22
|
+
|
23
|
+
namespace
|
24
|
+
{
|
25
|
+
FILE* openFile()
|
26
|
+
{
|
27
|
+
std::filesystem::path path = __FILE__;
|
28
|
+
FILE* fptr = fopen(path.string().c_str(), "rb");
|
29
|
+
return fptr;
|
30
|
+
}
|
31
|
+
|
32
|
+
std::string readFile(FILE* fptr)
|
33
|
+
{
|
34
|
+
std::ostringstream result;
|
35
|
+
|
36
|
+
char buffer[255];
|
37
|
+
while (fgets(buffer, sizeof(buffer), fptr) != NULL)
|
38
|
+
{
|
39
|
+
result << buffer;
|
40
|
+
}
|
41
|
+
return result.str();
|
42
|
+
}
|
43
|
+
|
44
|
+
bool closeFile(FILE* fptr)
|
45
|
+
{
|
46
|
+
// Ruby override fclose and replaces it with rb_w32_fclose which causes a segementation fault. Oy!
|
47
|
+
#ifndef _MSC_VER
|
48
|
+
fclose(fptr);
|
49
|
+
#endif
|
50
|
+
return true;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
TESTCASE(File)
|
55
|
+
{
|
56
|
+
Module m = define_module("TestingModule");
|
57
|
+
m.define_module_function("open_file", openFile).
|
58
|
+
define_module_function("read_file", readFile).
|
59
|
+
define_module_function("close_file", closeFile);
|
60
|
+
|
61
|
+
Data_Object<FILE> file = m.call("open_file");
|
62
|
+
ASSERT((file.value() != Qnil));
|
63
|
+
ASSERT((file.get() != nullptr));
|
64
|
+
|
65
|
+
String string = m.call("read_file", file);
|
66
|
+
ASSERT((string.length() > 1300));
|
67
|
+
|
68
|
+
Object result = m.call("close_file", file);
|
69
|
+
ASSERT_EQUAL(Qtrue, result.value());
|
70
|
+
}
|