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