rice 2.1.3 → 4.0.2

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 (246) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +121 -0
  3. data/CONTRIBUTORS.md +19 -0
  4. data/COPYING +2 -2
  5. data/Gemfile +3 -0
  6. data/README.md +45 -1028
  7. data/Rakefile +95 -12
  8. data/include/rice/rice.hpp +7766 -0
  9. data/include/rice/stl.hpp +1113 -0
  10. data/lib/mkmf-rice.rb +127 -0
  11. data/lib/version.rb +3 -0
  12. data/rice/Address_Registration_Guard.ipp +75 -32
  13. data/rice/Address_Registration_Guard_defn.hpp +60 -56
  14. data/rice/Arg.hpp +80 -4
  15. data/rice/Arg.ipp +51 -0
  16. data/rice/Constructor.hpp +30 -376
  17. data/rice/Data_Object.ipp +234 -107
  18. data/rice/Data_Object_defn.hpp +77 -117
  19. data/rice/Data_Type.hpp +1 -2
  20. data/rice/Data_Type.ipp +251 -295
  21. data/rice/Data_Type_defn.hpp +175 -243
  22. data/rice/Director.hpp +14 -9
  23. data/rice/Enum.hpp +54 -104
  24. data/rice/Enum.ipp +104 -230
  25. data/rice/Exception.hpp +2 -8
  26. data/rice/Exception.ipp +65 -0
  27. data/rice/Exception_defn.hpp +46 -47
  28. data/rice/Identifier.hpp +28 -28
  29. data/rice/Identifier.ipp +23 -27
  30. data/rice/Return.hpp +39 -0
  31. data/rice/Return.ipp +33 -0
  32. data/rice/detail/Exception_Handler.ipp +22 -62
  33. data/rice/detail/Exception_Handler_defn.hpp +76 -91
  34. data/rice/detail/Iterator.hpp +18 -88
  35. data/rice/detail/Iterator.ipp +47 -0
  36. data/rice/detail/Jump_Tag.hpp +21 -0
  37. data/rice/detail/MethodInfo.hpp +44 -0
  38. data/rice/detail/MethodInfo.ipp +78 -0
  39. data/rice/detail/NativeAttribute.hpp +53 -0
  40. data/rice/detail/NativeAttribute.ipp +83 -0
  41. data/rice/detail/NativeFunction.hpp +69 -0
  42. data/rice/detail/NativeFunction.ipp +248 -0
  43. data/rice/detail/RubyFunction.hpp +39 -0
  44. data/rice/detail/RubyFunction.ipp +92 -0
  45. data/rice/detail/Type.hpp +29 -0
  46. data/rice/detail/Type.ipp +138 -0
  47. data/rice/detail/TypeRegistry.hpp +50 -0
  48. data/rice/detail/TypeRegistry.ipp +106 -0
  49. data/rice/detail/Wrapper.hpp +51 -0
  50. data/rice/detail/Wrapper.ipp +151 -0
  51. data/rice/detail/default_allocation_func.hpp +8 -19
  52. data/rice/detail/default_allocation_func.ipp +9 -8
  53. data/rice/detail/from_ruby.hpp +2 -37
  54. data/rice/detail/from_ruby.ipp +1020 -46
  55. data/rice/detail/from_ruby_defn.hpp +38 -0
  56. data/rice/detail/function_traits.hpp +124 -0
  57. data/rice/detail/method_data.hpp +23 -15
  58. data/rice/detail/method_data.ipp +53 -0
  59. data/rice/detail/rice_traits.hpp +116 -0
  60. data/rice/detail/ruby.hpp +9 -50
  61. data/rice/detail/to_ruby.hpp +3 -17
  62. data/rice/detail/to_ruby.ipp +409 -31
  63. data/rice/detail/to_ruby_defn.hpp +48 -0
  64. data/rice/forward_declares.ipp +82 -0
  65. data/rice/global_function.hpp +16 -20
  66. data/rice/global_function.ipp +8 -17
  67. data/rice/rice.hpp +59 -0
  68. data/rice/ruby_mark.hpp +5 -3
  69. data/rice/ruby_try_catch.hpp +4 -4
  70. data/rice/stl.hpp +11 -0
  71. data/sample/callbacks/extconf.rb +6 -0
  72. data/sample/callbacks/sample_callbacks.cpp +35 -0
  73. data/sample/callbacks/test.rb +28 -0
  74. data/sample/enum/extconf.rb +3 -0
  75. data/sample/enum/sample_enum.cpp +3 -17
  76. data/sample/enum/test.rb +2 -2
  77. data/sample/inheritance/animals.cpp +8 -24
  78. data/sample/inheritance/extconf.rb +3 -0
  79. data/sample/inheritance/test.rb +1 -1
  80. data/sample/map/extconf.rb +3 -0
  81. data/sample/map/map.cpp +10 -18
  82. data/sample/map/test.rb +1 -1
  83. data/test/embed_ruby.cpp +34 -0
  84. data/test/embed_ruby.hpp +4 -0
  85. data/test/ext/t1/extconf.rb +3 -0
  86. data/test/ext/t1/t1.cpp +1 -3
  87. data/test/ext/t2/extconf.rb +3 -0
  88. data/test/ext/t2/t2.cpp +1 -1
  89. data/test/extconf.rb +23 -0
  90. data/test/ruby/test_callbacks_sample.rb +28 -0
  91. data/test/ruby/test_multiple_extensions.rb +18 -0
  92. data/test/ruby/test_multiple_extensions_same_class.rb +14 -0
  93. data/test/ruby/test_multiple_extensions_with_inheritance.rb +20 -0
  94. data/test/test_Address_Registration_Guard.cpp +25 -11
  95. data/test/test_Array.cpp +131 -74
  96. data/test/test_Attribute.cpp +147 -0
  97. data/test/test_Builtin_Object.cpp +36 -15
  98. data/test/test_Class.cpp +151 -276
  99. data/test/test_Constructor.cpp +10 -9
  100. data/test/test_Data_Object.cpp +135 -193
  101. data/test/test_Data_Type.cpp +323 -252
  102. data/test/test_Director.cpp +56 -42
  103. data/test/test_Enum.cpp +230 -104
  104. data/test/test_Exception.cpp +7 -7
  105. data/test/test_Hash.cpp +33 -31
  106. data/test/test_Identifier.cpp +6 -6
  107. data/test/test_Inheritance.cpp +221 -0
  108. data/test/test_Iterator.cpp +161 -0
  109. data/test/test_Jump_Tag.cpp +1 -1
  110. data/test/test_Keep_Alive.cpp +161 -0
  111. data/test/test_Memory_Management.cpp +4 -5
  112. data/test/test_Module.cpp +169 -111
  113. data/test/test_Object.cpp +51 -19
  114. data/test/test_Ownership.cpp +275 -0
  115. data/test/test_Self.cpp +205 -0
  116. data/test/test_Stl_Optional.cpp +90 -0
  117. data/test/test_Stl_Pair.cpp +144 -0
  118. data/test/test_Stl_SmartPointer.cpp +200 -0
  119. data/test/test_Stl_String.cpp +74 -0
  120. data/test/test_Stl_Vector.cpp +652 -0
  121. data/test/test_String.cpp +3 -3
  122. data/test/test_Struct.cpp +31 -40
  123. data/test/test_Symbol.cpp +3 -3
  124. data/test/test_To_From_Ruby.cpp +283 -218
  125. data/test/test_global_functions.cpp +41 -20
  126. data/test/unittest.cpp +34 -8
  127. data/test/unittest.hpp +0 -4
  128. metadata +121 -136
  129. data/Doxyfile +0 -2268
  130. data/Makefile.am +0 -26
  131. data/Makefile.in +0 -923
  132. data/README.mingw +0 -8
  133. data/aclocal.m4 +0 -1088
  134. data/bootstrap +0 -8
  135. data/check_stdcxx_11.ac +0 -103
  136. data/config.guess +0 -1421
  137. data/config.sub +0 -1807
  138. data/configure +0 -7367
  139. data/configure.ac +0 -55
  140. data/depcomp +0 -791
  141. data/doxygen.ac +0 -314
  142. data/doxygen.am +0 -186
  143. data/extconf.rb +0 -69
  144. data/install-sh +0 -501
  145. data/missing +0 -215
  146. data/post-autoconf.rb +0 -22
  147. data/post-automake.rb +0 -28
  148. data/rice/Address_Registration_Guard.cpp +0 -22
  149. data/rice/Arg_impl.hpp +0 -129
  150. data/rice/Arg_operators.cpp +0 -21
  151. data/rice/Arg_operators.hpp +0 -19
  152. data/rice/Array.hpp +0 -214
  153. data/rice/Array.ipp +0 -256
  154. data/rice/Builtin_Object.hpp +0 -8
  155. data/rice/Builtin_Object.ipp +0 -50
  156. data/rice/Builtin_Object_defn.hpp +0 -50
  157. data/rice/Class.cpp +0 -57
  158. data/rice/Class.hpp +0 -8
  159. data/rice/Class.ipp +0 -6
  160. data/rice/Class_defn.hpp +0 -83
  161. data/rice/Data_Type.cpp +0 -54
  162. data/rice/Data_Type_fwd.hpp +0 -12
  163. data/rice/Director.cpp +0 -13
  164. data/rice/Exception.cpp +0 -59
  165. data/rice/Exception_Base.hpp +0 -8
  166. data/rice/Exception_Base.ipp +0 -13
  167. data/rice/Exception_Base_defn.hpp +0 -27
  168. data/rice/Hash.hpp +0 -227
  169. data/rice/Hash.ipp +0 -329
  170. data/rice/Identifier.cpp +0 -8
  171. data/rice/Jump_Tag.hpp +0 -24
  172. data/rice/Makefile.am +0 -125
  173. data/rice/Makefile.in +0 -888
  174. data/rice/Module.cpp +0 -84
  175. data/rice/Module.hpp +0 -8
  176. data/rice/Module.ipp +0 -6
  177. data/rice/Module_defn.hpp +0 -88
  178. data/rice/Module_impl.hpp +0 -281
  179. data/rice/Module_impl.ipp +0 -345
  180. data/rice/Object.cpp +0 -169
  181. data/rice/Object.hpp +0 -8
  182. data/rice/Object.ipp +0 -19
  183. data/rice/Object_defn.hpp +0 -191
  184. data/rice/Require_Guard.hpp +0 -21
  185. data/rice/String.cpp +0 -94
  186. data/rice/String.hpp +0 -91
  187. data/rice/Struct.cpp +0 -117
  188. data/rice/Struct.hpp +0 -162
  189. data/rice/Struct.ipp +0 -26
  190. data/rice/Symbol.cpp +0 -25
  191. data/rice/Symbol.hpp +0 -66
  192. data/rice/Symbol.ipp +0 -44
  193. data/rice/config.hpp +0 -47
  194. data/rice/config.hpp.in +0 -46
  195. data/rice/detail/Arguments.hpp +0 -118
  196. data/rice/detail/Auto_Function_Wrapper.hpp +0 -898
  197. data/rice/detail/Auto_Function_Wrapper.ipp +0 -3694
  198. data/rice/detail/Auto_Member_Function_Wrapper.hpp +0 -897
  199. data/rice/detail/Auto_Member_Function_Wrapper.ipp +0 -2774
  200. data/rice/detail/Caster.hpp +0 -103
  201. data/rice/detail/Not_Copyable.hpp +0 -25
  202. data/rice/detail/Wrapped_Function.hpp +0 -33
  203. data/rice/detail/cfp.hpp +0 -24
  204. data/rice/detail/cfp.ipp +0 -51
  205. data/rice/detail/check_ruby_type.cpp +0 -27
  206. data/rice/detail/check_ruby_type.hpp +0 -23
  207. data/rice/detail/creation_funcs.hpp +0 -37
  208. data/rice/detail/creation_funcs.ipp +0 -36
  209. data/rice/detail/define_method_and_auto_wrap.hpp +0 -31
  210. data/rice/detail/define_method_and_auto_wrap.ipp +0 -30
  211. data/rice/detail/demangle.cpp +0 -56
  212. data/rice/detail/demangle.hpp +0 -19
  213. data/rice/detail/env.hpp +0 -11
  214. data/rice/detail/method_data.cpp +0 -86
  215. data/rice/detail/node.hpp +0 -13
  216. data/rice/detail/object_call.hpp +0 -69
  217. data/rice/detail/object_call.ipp +0 -131
  218. data/rice/detail/protect.cpp +0 -29
  219. data/rice/detail/protect.hpp +0 -34
  220. data/rice/detail/ruby_version_code.hpp +0 -6
  221. data/rice/detail/ruby_version_code.hpp.in +0 -6
  222. data/rice/detail/st.hpp +0 -22
  223. data/rice/detail/traits.hpp +0 -43
  224. data/rice/detail/win32.hpp +0 -16
  225. data/rice/detail/wrap_function.hpp +0 -341
  226. data/rice/detail/wrap_function.ipp +0 -514
  227. data/rice/protect.hpp +0 -92
  228. data/rice/protect.ipp +0 -1134
  229. data/rice/rubypp.rb +0 -97
  230. data/rice/to_from_ruby.hpp +0 -8
  231. data/rice/to_from_ruby.ipp +0 -294
  232. data/rice/to_from_ruby_defn.hpp +0 -70
  233. data/ruby.ac +0 -135
  234. data/ruby/Makefile.am +0 -1
  235. data/ruby/Makefile.in +0 -628
  236. data/ruby/lib/Makefile.am +0 -3
  237. data/ruby/lib/Makefile.in +0 -506
  238. data/ruby/lib/mkmf-rice.rb.in +0 -217
  239. data/ruby/lib/version.rb +0 -3
  240. data/sample/Makefile.am +0 -47
  241. data/sample/Makefile.in +0 -489
  242. data/test/Makefile.am +0 -72
  243. data/test/Makefile.in +0 -1213
  244. data/test/ext/Makefile.am +0 -41
  245. data/test/ext/Makefile.in +0 -483
  246. data/test/test_rice.rb +0 -41
@@ -0,0 +1,147 @@
1
+ #include <assert.h>
2
+
3
+ #include "unittest.hpp"
4
+ #include "embed_ruby.hpp"
5
+ #include <rice/rice.hpp>
6
+ #include <rice/stl.hpp>
7
+
8
+ using namespace Rice;
9
+
10
+ TESTSUITE(Attribute);
11
+
12
+ SETUP(Attribute)
13
+ {
14
+ embed_ruby();
15
+ }
16
+
17
+ namespace
18
+ {
19
+ class SomeClass
20
+ {
21
+ };
22
+
23
+ struct DataStruct
24
+ {
25
+ static inline float staticFloat = 1.0;
26
+ static inline const std::string staticString = "Static string";
27
+ static inline SomeClass someClassStatic;
28
+
29
+ std::string readWriteString = "Read Write";
30
+ int writeInt = 0;
31
+ const char* readChars = "Read some chars!";
32
+ SomeClass someClass;
33
+
34
+ std::string inspect()
35
+ {
36
+ return "";
37
+ }
38
+ };
39
+
40
+ bool globalBool = true;
41
+ const DataStruct* globalStruct = new DataStruct();
42
+
43
+ } // namespace
44
+
45
+ TESTCASE(attributes)
46
+ {
47
+ Class c = define_class<DataStruct>("DataStruct")
48
+ .define_constructor(Constructor<DataStruct>())
49
+ .define_method("inspect", &DataStruct::inspect)
50
+ .define_attr("read_chars", &DataStruct::readChars, Rice::AttrAccess::Read)
51
+ .define_attr("write_int", &DataStruct::writeInt, Rice::AttrAccess::Write)
52
+ .define_attr("read_write_string", &DataStruct::readWriteString);
53
+
54
+ Object o = c.call("new");
55
+ DataStruct* dataStruct = detail::From_Ruby<DataStruct*>().convert(o);
56
+
57
+ // Test readonly attribute
58
+ Object result = o.call("read_chars");
59
+ ASSERT_EQUAL("Read some chars!", detail::From_Ruby<char*>().convert(result));
60
+ ASSERT_EXCEPTION_CHECK(
61
+ Exception,
62
+ o.call("read_char=", "some text"),
63
+ ASSERT_EQUAL("undefined method `read_char=' for :DataStruct", ex.what())
64
+ );
65
+
66
+ // Test writeonly attribute
67
+ result = o.call("write_int=", 5);
68
+ ASSERT_EQUAL(5, detail::From_Ruby<int>().convert(result.value()));
69
+ ASSERT_EQUAL(5, dataStruct->writeInt);
70
+ ASSERT_EXCEPTION_CHECK(
71
+ Exception,
72
+ o.call("write_int", 3),
73
+ ASSERT_EQUAL("undefined method `write_int' for :DataStruct", ex.what())
74
+ );
75
+
76
+ // Test readwrite attribute
77
+ result = o.call("read_write_string=", "Set a string");
78
+ ASSERT_EQUAL("Set a string", detail::From_Ruby<std::string>().convert(result.value()));
79
+ ASSERT_EQUAL("Set a string", dataStruct->readWriteString);
80
+
81
+ result = o.call("read_write_string");
82
+ ASSERT_EQUAL("Set a string", detail::From_Ruby<std::string>().convert(result.value()));
83
+ }
84
+
85
+ TESTCASE(static_attributes)
86
+ {
87
+ Class c = define_class<DataStruct>("DataStruct")
88
+ .define_constructor(Constructor<DataStruct>())
89
+ .define_singleton_attr("static_float", &DataStruct::staticFloat, Rice::AttrAccess::ReadWrite)
90
+ .define_singleton_attr("static_string", &DataStruct::staticString, Rice::AttrAccess::Read);
91
+
92
+ // Test readwrite attribute
93
+ Object result = c.call("static_float=", 7.0);
94
+ ASSERT_EQUAL(7.0, detail::From_Ruby<float>().convert(result.value()));
95
+ ASSERT_EQUAL(7.0, DataStruct::staticFloat);
96
+ result = c.call("static_float");
97
+ ASSERT_EQUAL(7.0, detail::From_Ruby<float>().convert(result.value()));
98
+
99
+ result = c.call("static_string");
100
+ ASSERT_EQUAL("Static string", detail::From_Ruby<std::string>().convert(result.value()));
101
+ ASSERT_EXCEPTION_CHECK(
102
+ Exception,
103
+ c.call("static_string=", true),
104
+ ASSERT_EQUAL("undefined method `static_string=' for DataStruct:Class", ex.what())
105
+ );
106
+ }
107
+
108
+ TESTCASE(global_attributes)
109
+ {
110
+ Class c = define_class<DataStruct>("DataStruct")
111
+ .define_constructor(Constructor<DataStruct>())
112
+ .define_singleton_attr("global_bool", &globalBool, Rice::AttrAccess::ReadWrite)
113
+ .define_singleton_attr("global_struct", &globalStruct, Rice::AttrAccess::Read);
114
+
115
+ Object result = c.call("global_bool=", false);
116
+ ASSERT_EQUAL(Qfalse, result.value());
117
+ ASSERT_EQUAL(false, globalBool);
118
+ result = c.call("global_bool");
119
+ ASSERT_EQUAL(Qfalse, result.value());
120
+
121
+ result = c.call("global_struct");
122
+ DataStruct* aStruct = detail::From_Ruby<DataStruct*>().convert(result.value());
123
+ ASSERT_EQUAL(aStruct, globalStruct);
124
+ }
125
+
126
+ TESTCASE(not_defined)
127
+ {
128
+ Data_Type<DataStruct> c = define_class<DataStruct>("DataStruct");
129
+
130
+ #ifdef _MSC_VER
131
+ const char* message = "Type is not defined with Rice: class `anonymous namespace'::SomeClass";
132
+ #else
133
+ const char* message = "Type is not defined with Rice: (anonymous namespace)::SomeClass";
134
+ #endif
135
+
136
+ ASSERT_EXCEPTION_CHECK(
137
+ std::invalid_argument,
138
+ c.define_singleton_attr("some_class_static", &DataStruct::someClassStatic),
139
+ ASSERT_EQUAL(message, ex.what())
140
+ );
141
+
142
+ ASSERT_EXCEPTION_CHECK(
143
+ std::invalid_argument,
144
+ c.define_attr("some_class", &DataStruct::someClass),
145
+ ASSERT_EQUAL(message, ex.what())
146
+ );
147
+ }
@@ -1,6 +1,6 @@
1
1
  #include "unittest.hpp"
2
- #include "rice/Builtin_Object.hpp"
3
- #include "rice/Class.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
4
 
5
5
  using namespace Rice;
6
6
 
@@ -8,7 +8,7 @@ TESTSUITE(Builtin_Object);
8
8
 
9
9
  SETUP(Builtin_Object)
10
10
  {
11
- ruby_init();
11
+ embed_ruby();
12
12
  }
13
13
 
14
14
  TESTCASE(construct_with_object)
@@ -34,6 +34,39 @@ TESTCASE(copy_construct)
34
34
  ASSERT_EQUAL(rb_cObject, CLASS_OF(b2.value()));
35
35
  }
36
36
 
37
+ TESTCASE(copy_assign)
38
+ {
39
+ Class c(rb_cObject);
40
+ Builtin_Object<T_OBJECT> b1(c.call("new"));
41
+ Builtin_Object<T_OBJECT> b2(c.call("new"));
42
+
43
+ b2 = b1;
44
+
45
+ ASSERT_EQUAL(b2.value(), b1.value());
46
+ }
47
+
48
+ TESTCASE(move_constructor)
49
+ {
50
+ Class c(rb_cObject);
51
+ Builtin_Object<T_OBJECT> b1(c.call("new"));
52
+ Builtin_Object<T_OBJECT> b2(std::move(b1));
53
+
54
+ ASSERT_NOT_EQUAL(b2.value(), b1.value());
55
+ ASSERT_EQUAL(b1.value(), Qnil);
56
+ }
57
+
58
+ TESTCASE(move_assign)
59
+ {
60
+ Class c(rb_cObject);
61
+ Builtin_Object<T_OBJECT> b1(c.call("new"));
62
+ Builtin_Object<T_OBJECT> b2(c.call("new"));
63
+
64
+ b2 = std::move(b1);
65
+
66
+ ASSERT_NOT_EQUAL(b2.value(), b1.value());
67
+ ASSERT_EQUAL(b1.value(), Qnil);
68
+ }
69
+
37
70
  TESTCASE(dereference)
38
71
  {
39
72
  Class c(rb_cObject);
@@ -57,15 +90,3 @@ TESTCASE(get)
57
90
  Builtin_Object<T_OBJECT> b(o);
58
91
  ASSERT_EQUAL(ROBJECT(o.value()), b.get());
59
92
  }
60
-
61
- TESTCASE(swap)
62
- {
63
- Class c(rb_cObject);
64
- Object o1(c.call("new"));
65
- Builtin_Object<T_OBJECT> b1(o1);
66
- Object o2(c.call("new"));
67
- Builtin_Object<T_OBJECT> b2(o2);
68
- b1.swap(b2);
69
- ASSERT_EQUAL(b1.value(), o2.value());
70
- ASSERT_EQUAL(b2.value(), o1.value());
71
- }
data/test/test_Class.cpp CHANGED
@@ -1,21 +1,15 @@
1
1
  #include "unittest.hpp"
2
- #include "rice/Class.hpp"
3
- #include "rice/Constructor.hpp"
4
- #include "rice/protect.hpp"
5
- #include "rice/Exception.hpp"
6
- #include "rice/Array.hpp"
7
- #include "rice/String.hpp"
8
- #include "rice/Symbol.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
9
4
  #include <iostream>
10
5
 
11
6
  using namespace Rice;
12
- using namespace std;
13
7
 
14
8
  TESTSUITE(Class);
15
9
 
16
10
  SETUP(Class)
17
11
  {
18
- ruby_init();
12
+ embed_ruby();
19
13
  }
20
14
 
21
15
  TESTCASE(construct)
@@ -32,10 +26,7 @@ TESTCASE(undef_creation_funcs)
32
26
  ASSERT_EXCEPTION_CHECK(
33
27
  Exception,
34
28
  c.call("new"),
35
- ASSERT_EQUAL(
36
- Object(rb_eTypeError), // TODO: 1.6.x?
37
- Object(CLASS_OF(ex.value()))
38
- )
29
+ ASSERT_EQUAL(rb_eTypeError, ex.class_of())
39
30
  );
40
31
  }
41
32
 
@@ -59,7 +50,7 @@ TESTCASE(include_module)
59
50
  TESTCASE(const_set_get_by_id)
60
51
  {
61
52
  Class c(anonymous_class());
62
- Object v = to_ruby(42);
53
+ Object v = detail::to_ruby(42);
63
54
  Class & c2(c.const_set(rb_intern("FOO"), v));
64
55
  ASSERT_EQUAL(&c, &c2);
65
56
  ASSERT_EQUAL(v, c.const_get(rb_intern("FOO")));
@@ -68,7 +59,7 @@ TESTCASE(const_set_get_by_id)
68
59
  TESTCASE(const_set_get_by_identifier)
69
60
  {
70
61
  Class c(anonymous_class());
71
- Object v = to_ruby(42);
62
+ Object v = detail::to_ruby(42);
72
63
  Class & c2(c.const_set(Identifier("FOO"), v));
73
64
  ASSERT_EQUAL(&c, &c2);
74
65
  ASSERT_EQUAL(v, c.const_get(Identifier("FOO")));
@@ -77,7 +68,7 @@ TESTCASE(const_set_get_by_identifier)
77
68
  TESTCASE(const_set_get_by_string)
78
69
  {
79
70
  Class c(anonymous_class());
80
- Object v = to_ruby(42);
71
+ Object v = detail::to_ruby(42);
81
72
  Class & c2(c.const_set("FOO", v));
82
73
  ASSERT_EQUAL(&c, &c2);
83
74
  ASSERT_EQUAL(v, c.const_get("FOO"));
@@ -85,257 +76,111 @@ TESTCASE(const_set_get_by_string)
85
76
 
86
77
  namespace
87
78
  {
79
+ bool some_function()
80
+ {
81
+ return true;
82
+ }
88
83
 
89
- bool define_method_simple_ok;
90
-
91
- void define_method_simple_helper()
92
- {
93
- define_method_simple_ok = true;
84
+ Object some_method(Object self)
85
+ {
86
+ return self;
87
+ }
94
88
  }
95
89
 
96
- } // namespace
97
-
98
- TESTCASE(define_method_simple)
90
+ TESTCASE(methods)
99
91
  {
100
92
  Class c(anonymous_class());
101
- c.define_method("foo", &define_method_simple_helper);
93
+ c.define_function("some_function", &some_function);
94
+ c.define_method("some_method", &some_method);
95
+
102
96
  Object o = c.call("new");
103
- define_method_simple_ok = false;
104
- o.call("foo");
105
- ASSERT(define_method_simple_ok);
106
- }
97
+ Object result = o.call("some_function");
98
+ ASSERT_EQUAL(Qtrue, result.value());
107
99
 
108
- TESTCASE(define_singleton_method_simple)
109
- {
110
- Class c(anonymous_class());
111
- c.define_singleton_method("foo", &define_method_simple_helper);
112
- define_method_simple_ok = false;
113
- Object o = c.call("foo");
114
- ASSERT(define_method_simple_ok);
100
+ result = o.call("some_method");
101
+ ASSERT_EQUAL(o, result);
115
102
  }
116
103
 
117
- TESTCASE(define_module_function_simple)
104
+ TESTCASE(method_lambdas)
118
105
  {
119
- // module_function only works with Module, not Class
120
106
  Class c(anonymous_class());
121
- ASSERT_EXCEPTION_CHECK(
122
- std::runtime_error,
123
- c.define_module_function("foo", &define_method_simple_helper),
124
- );
125
- }
126
-
127
- namespace
128
- {
129
- class RefTest
107
+ c.define_function("some_function", []()
108
+ {
109
+ return some_function();
110
+ });
111
+ c.define_method("some_method", [](VALUE self)
130
112
  {
131
- public:
132
- RefTest() { }
133
-
134
- static std::string& getReference() {
135
- static std::string foo = "foo";
136
- return foo;
137
- }
138
- };
139
- }
140
-
141
- TESTCASE(define_singleton_method_returning_reference)
142
- {
143
- Class c = define_class<RefTest>("RefTest")
144
- .define_constructor(Constructor<RefTest>())
145
- .define_singleton_method("get_reference", &RefTest::getReference);
146
-
147
- Module m(anonymous_module());
148
-
149
- Object result = m.instance_eval("RefTest.get_reference");
150
- ASSERT_EQUAL(result, String("foo"));
151
- }
152
-
153
- namespace
154
- {
155
-
156
- int define_method_int_result;
157
-
158
- class IntHelper {
159
- public:
160
- IntHelper() { }
161
-
162
- void define_method_int_helper(int i)
163
- {
164
- define_method_int_result = i;
165
- }
166
- };
167
-
168
- } // namespace
169
-
170
- TESTCASE(define_method_int)
171
- {
172
- Class c =
173
- define_class<IntHelper>("IntHelper")
174
- .define_constructor(Constructor<IntHelper>())
175
- .define_method("foo", &IntHelper::define_method_int_helper);
176
-
177
- Object o = c.call("new");
178
- define_method_int_result = 0;
179
- o.call("foo", 42);
180
- ASSERT_EQUAL(42, define_method_int_result);
181
- }
182
-
183
- TESTCASE(define_method_int_passed_two_args)
184
- {
185
- Class c =
186
- define_class<IntHelper>("IntHelper")
187
- .define_constructor(Constructor<IntHelper>())
188
- .define_method("foo", &IntHelper::define_method_int_helper);
113
+ return some_method(self);
114
+ });
189
115
 
190
116
  Object o = c.call("new");
117
+ Object result = o.call("some_function");
118
+ ASSERT_EQUAL(Qtrue, result.value());
191
119
 
192
- ASSERT_EXCEPTION_CHECK(
193
- Exception,
194
- o.call("foo", 1, 2),
195
- ASSERT_EQUAL(
196
- Object(rb_eArgError),
197
- Object(CLASS_OF(ex.value()))
198
- )
199
- );
120
+ result = o.call("some_method");
121
+ ASSERT_EQUAL(o, result);
200
122
  }
201
123
 
202
- TESTCASE(define_method_int_passed_no_args)
124
+ TESTCASE(singleton_methods)
203
125
  {
204
- Class c =
205
- define_class<IntHelper>("IntHelper")
206
- .define_constructor(Constructor<IntHelper>())
207
- .define_method("foo", &IntHelper::define_method_int_helper);
208
-
209
- Object o = c.call("new");
126
+ Class c(anonymous_class());
127
+ c.define_singleton_method("some_method", &some_method);
210
128
 
211
- ASSERT_EXCEPTION_CHECK(
212
- Exception,
213
- o.call("foo"),
214
- ASSERT_EQUAL(
215
- Object(rb_eArgError),
216
- Object(CLASS_OF(ex.value()))
217
- )
218
- );
129
+ Object result = c.call("some_method");
130
+ ASSERT_EQUAL(c, result);
219
131
  }
220
132
 
221
-
222
- namespace
223
- {
224
-
225
- struct Foo
226
- {
227
- int x;
228
- };
229
-
230
- int define_method_int_foo_result_i;
231
- Foo * define_method_int_foo_result_x;
232
-
233
- void define_method_int_foo_helper(int i, Foo * x)
133
+ TESTCASE(singleton_method_lambdas)
234
134
  {
235
- define_method_int_foo_result_i = i;
236
- define_method_int_foo_result_x = x;
237
- }
238
-
239
- } // namespace
135
+ Class c(anonymous_class());
136
+ c.define_singleton_method("some_method", [](VALUE self)
137
+ {
138
+ return some_method(self);
139
+ });
240
140
 
241
- template<>
242
- Foo * from_ruby<Foo *>(Object x)
243
- {
244
- Foo * retval;
245
- Data_Get_Struct(x.value(), Foo, retval);
246
- return retval;
141
+ Object result = c.call("some_method");
142
+ ASSERT_EQUAL(c, result);
247
143
  }
248
144
 
249
- TESTCASE(define_method_int_foo)
145
+ TESTCASE(module_function)
250
146
  {
147
+ // module_function only works with Module, not Class
251
148
  Class c(anonymous_class());
252
- c.define_method("foo", &define_method_int_foo_helper);
253
- Object o = c.call("new");
254
- define_method_int_result = 0;
255
- Foo * foo = new Foo;
256
- foo->x = 1024;
257
- VALUE f = Data_Wrap_Struct(rb_cObject, 0, Default_Free_Function<Foo>::free, foo);
258
- o.call("foo", 42, Object(f));
259
- ASSERT_EQUAL(42, define_method_int_foo_result_i);
260
- ASSERT_EQUAL(foo, define_method_int_foo_result_x);
149
+ ASSERT_EXCEPTION_CHECK(
150
+ std::runtime_error,
151
+ c.define_module_function("some_function", &some_function),
152
+ ASSERT_EQUAL("can only define module functions for modules", ex.what())
153
+ );
261
154
  }
262
155
 
263
156
  namespace
264
157
  {
158
+ class Silly_Exception
159
+ : public std::exception
160
+ {
161
+ };
265
162
 
266
- class Silly_Exception
267
- : public std::exception
268
- {
269
- };
270
-
271
- void handle_silly_exception(Silly_Exception const & ex)
272
- {
273
- throw Exception(rb_eRuntimeError, "SILLY");
274
- }
275
-
276
- void throw_silly_exception()
277
- {
278
- throw Silly_Exception();
279
- }
163
+ void handle_silly_exception(Silly_Exception const & ex)
164
+ {
165
+ throw Exception(rb_eRuntimeError, "SILLY");
166
+ }
280
167
 
168
+ void throw_silly_exception()
169
+ {
170
+ throw Silly_Exception();
171
+ }
281
172
  }
282
173
 
283
174
  TESTCASE(add_handler)
284
175
  {
285
176
  Class c(rb_cObject);
286
- c.add_handler<Silly_Exception>(handle_silly_exception);
287
- c.define_method("foo", throw_silly_exception);
288
- Object exc = protect(rb_eval_string, "begin; foo; rescue Exception; $!; end");
177
+ c.add_handler<Silly_Exception>(handle_silly_exception)
178
+ .define_function("foo", throw_silly_exception);
179
+
180
+ Object exc = detail::protect(rb_eval_string, "begin; foo; rescue Exception; $!; end");
289
181
  ASSERT_EQUAL(rb_eRuntimeError, CLASS_OF(exc));
290
182
  Exception ex(exc);
291
- ASSERT_EQUAL(String("SILLY"), String(ex.message()));
292
- }
293
-
294
- namespace
295
- {
296
-
297
- class Container
298
- {
299
- public:
300
- Container(int * array, size_t length)
301
- : array_(array)
302
- , length_(length)
303
- {
304
- }
305
-
306
- // Custom names to make sure we call the function pointers rather than
307
- // expectable default names.
308
- int * beginFoo() { return array_; }
309
- int * endBar() { return array_ + length_; }
310
-
311
- private:
312
- int * array_;
313
- size_t length_;
314
- };
315
-
316
- } // namespace
317
-
318
- template<>
319
- Container * from_ruby<Container *>(Object x)
320
- {
321
- Container * retval;
322
- Data_Get_Struct(x.value(), Container, retval);
323
- return retval;
324
- }
325
-
326
- TESTCASE(define_iterator)
327
- {
328
- int array[] = { 1, 2, 3 };
329
- Class c(anonymous_class());
330
- c.define_iterator(&Container::beginFoo, &Container::endBar);
331
- Container * container = new Container(array, 3);
332
- Object wrapped_container = Data_Wrap_Struct(
333
- c, 0, Default_Free_Function<Container>::free, container);
334
- Array a = wrapped_container.instance_eval("a = []; each() { |x| a << x }; a");
335
- ASSERT_EQUAL(3u, a.size());
336
- ASSERT_EQUAL(to_ruby(1), Object(a[0]));
337
- ASSERT_EQUAL(to_ruby(2), Object(a[1]));
338
- ASSERT_EQUAL(to_ruby(3), Object(a[2]));
183
+ ASSERT_EQUAL("SILLY", ex.what());
339
184
  }
340
185
 
341
186
  TESTCASE(define_class)
@@ -346,10 +191,10 @@ TESTCASE(define_class)
346
191
  object.remove_const("Foo");
347
192
  }
348
193
 
349
- Class c = define_class("Foo");
194
+ Class c = define_class("Foo1");
350
195
 
351
196
  ASSERT(c.is_a(rb_cClass));
352
- ASSERT_EQUAL(c, object.const_get("Foo"));
197
+ ASSERT_EQUAL(c, object.const_get("Foo1"));
353
198
  }
354
199
 
355
200
  TESTCASE(define_class_under)
@@ -387,35 +232,13 @@ TESTCASE(module_define_class)
387
232
  math.remove_const("Foo");
388
233
  }
389
234
 
390
- Class c = math.define_class("Foo");
235
+ Class c = define_class_under(math, "Foo");
391
236
 
392
237
  ASSERT(c.is_a(rb_cClass));
393
238
  ASSERT_EQUAL(c, math.const_get("Foo"));
394
239
  ASSERT(!object.const_defined("Foo"));
395
240
  }
396
241
 
397
- namespace {
398
- class BaseClass {
399
- public:
400
- BaseClass() { }
401
- };
402
- }
403
-
404
- TESTCASE(subclassing)
405
- {
406
- Module m = define_module("Testing");
407
- define_class_under<BaseClass>(m, "BaseClass").
408
- define_constructor(Constructor<BaseClass>());
409
-
410
- // Not sure how to make this a true failure case. If the subclassing
411
- // doesn't work, Ruby will throw an error:
412
- //
413
- // in `new': wrong instance allocation
414
- //
415
- m.instance_eval("class NewClass < Testing::BaseClass; end;");
416
- m.instance_eval("n = NewClass.new");
417
- }
418
-
419
242
  namespace
420
243
  {
421
244
  int defaults_method_one_arg1;
@@ -440,7 +263,7 @@ TESTCASE(define_method_default_arguments)
440
263
  .define_constructor(Constructor<DefaultArgs>())
441
264
  .define_method("with_defaults",
442
265
  &DefaultArgs::defaults_method_one,
443
- (Arg("arg1"), Arg("arg2") = 3, Arg("arg3") = true));
266
+ Arg("arg1"), Arg("arg2") = 3, Arg("arg3") = true);
444
267
 
445
268
  Object o = c.call("new");
446
269
  o.call("with_defaults", 2);
@@ -462,35 +285,87 @@ TESTCASE(define_method_default_arguments)
462
285
  ASSERT(!defaults_method_one_arg3);
463
286
  }
464
287
 
465
- /*
466
- namespace {
467
- float with_reference_defaults_x;
468
- std::string with_reference_defaults_str;
288
+ TESTCASE(invalid_comma_operator)
289
+ {
290
+ Class c = define_class<DefaultArgs>("DefaultArgs")
291
+ .define_constructor(Constructor<DefaultArgs>());
469
292
 
470
- class DefaultArgsRefs
293
+ ASSERT_EXCEPTION_CHECK(
294
+ std::runtime_error,
295
+ c.define_method("with_defaults", &DefaultArgs::defaults_method_one, (Arg("arg1"), Arg("arg2") = 3, Arg("arg3") = true)),
296
+ ASSERT_EQUAL("The Arg class no longer supports the comma operator, please remove the surounding parentheses", ex.what())
297
+ );
298
+ }
299
+
300
+ namespace
301
+ {
302
+ int func1 = 0;
303
+ int func2 = 0;
304
+
305
+ int function1(int aValue)
471
306
  {
472
- public:
473
- void with_reference_defaults(float x, std::string const& str = std::string("testing"))
474
- {
475
- with_reference_defaults_x = x;
476
- with_reference_defaults_str = str;
477
- }
478
- };
307
+ func1 = aValue;
308
+ return func1;
309
+ }
479
310
 
311
+ int function2(int aValue)
312
+ {
313
+ func2 = aValue;
314
+ return func2;
315
+ }
480
316
  }
481
317
 
482
- TESTCASE(define_method_works_with_reference_const_default_values)
318
+ TESTCASE(same_function_signature)
483
319
  {
484
- Class c = define_class<DefaultArgsRefs>("DefaultArgsRefs")
485
- .define_constructor(Constructor<DefaultArgsRefs>())
486
- .define_method("bar",
487
- &DefaultArgsRefs::with_reference_defaults,
488
- (Arg("x"), Arg("str") = std::string("testing")));
320
+ Class c = define_class("FunctionSignatures")
321
+ .define_singleton_function("function1", &function1)
322
+ .define_singleton_function("function2", &function2);
489
323
 
490
- Object o = c.call("new");
491
- o.call("bar", 3);
324
+ c.call("function1", 5);
325
+ ASSERT_EQUAL(5, func1);
326
+
327
+ c.call("function2", 6);
328
+ ASSERT_EQUAL(6, func2);
329
+ }
330
+
331
+ namespace
332
+ {
333
+ VALUE someValue;
334
+
335
+ void value_parameter(VALUE value)
336
+ {
337
+ someValue = value;
338
+ }
339
+
340
+ VALUE value_return()
341
+ {
342
+ return rb_ary_new_from_args(3, Qnil, Qtrue, Qfalse);
343
+ }
344
+ }
345
+
346
+ TESTCASE(value_parameter)
347
+ {
348
+ define_global_function("value_parameter", &value_parameter, Arg("value").isValue());
349
+
350
+ Module m = define_module("TestingModule");
351
+
352
+ std::string code = R"($object = Object.new)";
353
+ Object object = m.instance_eval(code);
354
+
355
+ code = R"(value_parameter($object))";
356
+ m.instance_eval(code);
357
+
358
+ ASSERT_EQUAL(someValue, object.value());
359
+ }
360
+
361
+ TESTCASE(value_return)
362
+ {
363
+ define_global_function("value_return", &value_return, Return().isValue());
364
+
365
+ Module m = define_module("TestingModule");
366
+
367
+ VALUE value = m.instance_eval("value_return");
368
+ detail::protect(rb_check_type, value, (int)T_ARRAY);
492
369
 
493
- ASSERT_EQUAL(3, with_reference_defaults_x);
494
- ASSERT_EQUAL("testing", with_reference_defaults_str);
370
+ ASSERT_EQUAL(3, Array(value).size());
495
371
  }
496
- */