rice 4.2.1 → 4.3.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.
@@ -74,6 +74,15 @@ namespace
74
74
  return instance_;
75
75
  }
76
76
 
77
+ std::shared_ptr<MyClass>& share_ref()
78
+ {
79
+ if (!instance_)
80
+ {
81
+ instance_ = std::make_shared<MyClass>();
82
+ }
83
+ return instance_;
84
+ }
85
+
77
86
  public:
78
87
  static inline std::shared_ptr<MyClass> instance_;
79
88
  };
@@ -104,7 +113,8 @@ SETUP(SmartPointer)
104
113
  define_class<Factory>("Factory").
105
114
  define_constructor(Constructor<Factory>()).
106
115
  define_method("transfer", &Factory::transfer).
107
- define_method("share", &Factory::share);
116
+ define_method("share", &Factory::share).
117
+ define_method("share_ref", &Factory::share_ref);
108
118
 
109
119
  define_global_function("extract_flag_unique_ptr_ref", &extractFlagUniquePtrRef);
110
120
  define_global_function("extract_flag_shared_ptr", &extractFlagSharedPtr);
@@ -152,8 +162,13 @@ TESTCASE(ShareOwnership)
152
162
  my_class.set_flag(i)
153
163
  end)";
154
164
 
165
+
166
+ ASSERT_EQUAL(0, Factory::instance_.use_count());
155
167
  m.module_eval(code);
168
+
169
+ ASSERT_EQUAL(11, Factory::instance_.use_count());
156
170
  rb_gc_start();
171
+ ASSERT_EQUAL(1, Factory::instance_.use_count());
157
172
 
158
173
  ASSERT_EQUAL(1, MyClass::constructorCalls);
159
174
  ASSERT_EQUAL(0, MyClass::copyConstructorCalls);
@@ -162,6 +177,34 @@ TESTCASE(ShareOwnership)
162
177
  ASSERT_EQUAL(9, Factory::instance_->flag);
163
178
  }
164
179
 
180
+
181
+ TESTCASE(ShareOwnership2)
182
+ {
183
+ MyClass::reset();
184
+
185
+ Module m = define_module("TestingModule");
186
+
187
+ // Create ruby objects that point to the same instance of MyClass
188
+ std::string code = R"(factory = Factory.new
189
+ 10.times do |i|
190
+ my_class = factory.share
191
+ my_class.set_flag(i)
192
+ end)";
193
+
194
+ Factory factory;
195
+ std::shared_ptr<MyClass> myClass = factory.share();
196
+ ASSERT_EQUAL(2, Factory::instance_.use_count());
197
+
198
+ // Call some ruby code
199
+ Data_Object<Factory> wrapper(factory);
200
+ ASSERT_EQUAL(2, Factory::instance_.use_count());
201
+ wrapper.instance_eval("self.share_ref.set_flag(1)");
202
+
203
+ ASSERT_EQUAL(3, Factory::instance_.use_count());
204
+ rb_gc_start();
205
+ ASSERT_EQUAL(2, Factory::instance_.use_count());
206
+ }
207
+
165
208
  TESTCASE(UniquePtrRefParameter)
166
209
  {
167
210
  MyClass::reset();
@@ -237,4 +280,4 @@ TESTCASE(SharedPtrRefDefaultParameter)
237
280
  Object result = m.module_eval(code);
238
281
  // The default value kicks in and ignores any previous pointer
239
282
  ASSERT_EQUAL(0, detail::From_Ruby<int>().convert(result));
240
- }
283
+ }
@@ -0,0 +1,88 @@
1
+ #include "unittest.hpp"
2
+ #include "embed_ruby.hpp"
3
+ #include <rice/rice.hpp>
4
+ #include <ruby/encoding.h>
5
+ #include <rice/stl.hpp>
6
+
7
+ #include <optional>
8
+
9
+ using namespace Rice;
10
+
11
+ TESTSUITE(StlStringView);
12
+
13
+ SETUP(StlStringView)
14
+ {
15
+ embed_ruby();
16
+ }
17
+
18
+ TESTCASE(std_string_view_to_ruby)
19
+ {
20
+ ASSERT(rb_equal(String("").value(), detail::to_ruby(std::string_view(""))));
21
+ ASSERT(rb_equal(String("foo").value(), detail::to_ruby(std::string_view("foo"))));
22
+ }
23
+
24
+ TESTCASE(std_string_view_to_ruby_encoding)
25
+ {
26
+ VALUE value = detail::to_ruby(std::string_view("Some String"));
27
+ String string(value);
28
+ Object encoding = string.call("encoding");
29
+ String encodingName = encoding.call("name");
30
+ std::string_view result = detail::From_Ruby<std::string_view>().convert(encodingName);
31
+ if(result != "ASCII-8BIT" && result != "US-ASCII" && result != "UTF-8") {
32
+ FAIL("Encoding incorrect", "ASCII-8BIT, US-ASCII, or UTF-8 (Windows)", result);
33
+ }
34
+ }
35
+
36
+ TESTCASE(std_string_view_to_ruby_encoding_utf8)
37
+ {
38
+ rb_encoding* defaultEncoding = rb_default_external_encoding();
39
+
40
+ VALUE utf8Encoding = rb_enc_from_encoding(rb_utf8_encoding());
41
+ rb_enc_set_default_external(utf8Encoding);
42
+
43
+ VALUE value = detail::to_ruby(std::string_view("Some String"));
44
+ Object object(value);
45
+ Object encoding = object.call("encoding");
46
+ Object encodingName = encoding.call("name");
47
+ ASSERT_EQUAL("UTF-8", detail::From_Ruby<std::string_view>().convert(encodingName));
48
+
49
+ rb_enc_set_default_external(rb_enc_from_encoding(defaultEncoding));
50
+ }
51
+
52
+ TESTCASE(std_string_view_from_ruby)
53
+ {
54
+ ASSERT_EQUAL(std::string_view(""), detail::From_Ruby<std::string_view>().convert(rb_str_new2("")));
55
+ ASSERT_EQUAL(std::string_view("foo"), detail::From_Ruby<std::string_view>().convert(rb_str_new2("foo")));
56
+
57
+ ASSERT_EXCEPTION_CHECK(
58
+ Exception,
59
+ detail::From_Ruby<std::string_view>().convert(rb_float_new(15.512)),
60
+ ASSERT_EQUAL("wrong argument type Float (expected String)", ex.what())
61
+ );
62
+ }
63
+
64
+ TESTCASE(std_string_view_to_ruby_with_binary)
65
+ {
66
+ Rice::String got = detail::to_ruby(std::string_view("\000test", 5));
67
+
68
+ ASSERT_EQUAL(String(std::string_view("\000test", 5)), got);
69
+ ASSERT_EQUAL(5ul, got.length());
70
+ }
71
+
72
+ TESTCASE(std_string_view_from_ruby_with_binary)
73
+ {
74
+ std::string_view got = detail::From_Ruby<std::string_view>().convert(rb_str_new("\000test", 5));
75
+ ASSERT_EQUAL(5ul, got.length());
76
+ ASSERT_EQUAL(std::string_view("\000test", 5), got);
77
+ }
78
+
79
+ TESTCASE(std_string_view_from_ruby_refefence)
80
+ {
81
+ VALUE value = rb_str_new("test", 4);
82
+ std::string_view view = detail::From_Ruby<std::string_view>().convert(value);
83
+ ASSERT_EQUAL("test", view);
84
+
85
+ String string(value);
86
+ string.instance_eval("self[1] = 'a'");
87
+ //ASSERT_EQUAL("tast", view);
88
+ }
@@ -80,7 +80,7 @@ TESTCASE(Empty)
80
80
  Module m = define_module("Testing");
81
81
 
82
82
  Class c = define_unordered_map<std::unordered_map<std::string, std::int32_t>>("IntUnorderedMap");
83
- Object unordered_map = c.call("new");
83
+ Data_Object<std::unordered_map<std::string, std::int32_t>> unordered_map = c.call("new");
84
84
 
85
85
  Object result = unordered_map.call("size");
86
86
  ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(result));
@@ -94,7 +94,7 @@ TESTCASE(Include)
94
94
  Module m = define_module("Testing");
95
95
 
96
96
  Class c = define_unordered_map<std::unordered_map<std::string, std::int32_t>>("IntUnorderedMap");
97
- Object unordered_map = c.call("new");
97
+ Data_Object<std::unordered_map<std::string, std::int32_t>> unordered_map = c.call("new");
98
98
  unordered_map.call("[]=", "one", 1);
99
99
  unordered_map.call("[]=", "two", 2);
100
100
 
@@ -113,7 +113,7 @@ TESTCASE(Value)
113
113
  Module m = define_module("Testing");
114
114
 
115
115
  Class c = define_unordered_map<std::unordered_map<std::string, std::int32_t>>("IntUnorderedMap");
116
- Object unordered_map = c.call("new");
116
+ Data_Object<std::unordered_map<std::string, std::int32_t>> unordered_map = c.call("new");
117
117
  unordered_map.call("[]=", "one", 1);
118
118
  unordered_map.call("[]=", "two", 2);
119
119
 
@@ -129,16 +129,16 @@ TESTCASE(ToString)
129
129
  Module m = define_module("Testing");
130
130
 
131
131
  Class c = define_unordered_map<std::unordered_map<std::string, std::int32_t>>("IntUnorderedMap");
132
- Object unordered_map = c.call("new");
132
+ Data_Object<std::unordered_map<std::string, std::int32_t>> unordered_map = c.call("new");
133
133
  unordered_map.call("[]=", "one", 1);
134
134
  unordered_map.call("[]=", "two", 2);
135
135
 
136
- Object result = unordered_map.call("to_s");
137
- ASSERT_EQUAL("{two => 2, one => 1}", detail::From_Ruby<std::string>().convert(result));
136
+ ASSERT_EQUAL(1, unordered_map->operator[]("one"));
137
+ ASSERT_EQUAL(2, unordered_map->operator[]("two"));
138
138
 
139
139
  unordered_map.call("clear");
140
140
 
141
- result = unordered_map.call("to_s");
141
+ Object result = unordered_map.call("to_s");
142
142
  ASSERT_EQUAL("{}", detail::From_Ruby<std::string>().convert(result));
143
143
  }
144
144
 
@@ -147,7 +147,7 @@ TESTCASE(Update)
147
147
  Module m = define_module("Testing");
148
148
 
149
149
  Class c = define_unordered_map<std::unordered_map<std::string, std::string>>("StringUnorderedMap");
150
- Object unordered_map = c.call("new");
150
+ Data_Object<std::unordered_map<std::string, std::string>> unordered_map = c.call("new");
151
151
  unordered_map.call("[]=", "one", "original 1");
152
152
  unordered_map.call("[]=", "two", "original 2");
153
153
 
@@ -169,7 +169,7 @@ TESTCASE(Modify)
169
169
  Module m = define_module("Testing");
170
170
 
171
171
  Class c = define_unordered_map<std::unordered_map<std::string, int64_t>>("Int64UnorderedMap");
172
- Object unordered_map = c.call("new");
172
+ Data_Object<std::unordered_map<std::string, std::int64_t>> unordered_map = c.call("new");
173
173
 
174
174
  Object result = unordered_map.call("[]=", "one", 3232323232);
175
175
 
@@ -183,12 +183,12 @@ TESTCASE(Modify)
183
183
  ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(result));
184
184
  }
185
185
 
186
- TESTCASE(keysAndValues)
186
+ TESTCASE(KeysAndValues)
187
187
  {
188
188
  Module m = define_module("Testing");
189
189
 
190
190
  Class c = define_unordered_map<std::unordered_map<std::string, int32_t>>("Int32UnorderedMap");
191
- Object unordered_map = c.call("new");
191
+ Data_Object<std::unordered_map<std::string, std::int32_t>> unordered_map = c.call("new");
192
192
 
193
193
  unordered_map.call("[]=", "one", 1);
194
194
  unordered_map.call("[]=", "two", 2);
@@ -196,19 +196,19 @@ TESTCASE(keysAndValues)
196
196
 
197
197
  // Keys returns a std::vector
198
198
  Data_Object<std::vector<std::string>> keys = unordered_map.call("keys");
199
- //std::vector<std::string> expected_keys{ {"one", "three", "two"} };
199
+ std::sort(keys->begin(), keys->end());
200
200
  ASSERT_EQUAL(3u, keys->size());
201
- //ASSERT_EQUAL(expected_keys[0], keys->operator[](0));
202
- //ASSERT_EQUAL(expected_keys[1], keys->operator[](1));
203
- //ASSERT_EQUAL(expected_keys[2], keys->operator[](2));
201
+ ASSERT_EQUAL("one", keys->operator[](0));
202
+ ASSERT_EQUAL("three", keys->operator[](1));
203
+ ASSERT_EQUAL("two", keys->operator[](2));
204
204
 
205
- // Keys returns a std::vector
205
+ // Values returns a std::vector
206
206
  Data_Object<std::vector<std::int32_t>> values = unordered_map.call("values");
207
- //std::vector<std::int32_t> expected_values{ {1, 3, 2} };
207
+ std::sort(values->begin(), values->end());
208
208
  ASSERT_EQUAL(3u, values->size());
209
- //ASSERT_EQUAL(expected_values[0], values->operator[](0));
210
- //ASSERT_EQUAL(expected_values[1], values->operator[](1));
211
- //ASSERT_EQUAL(expected_values[2], values->operator[](2));
209
+ ASSERT_EQUAL(1, values->operator[](0));
210
+ ASSERT_EQUAL(2, values->operator[](1));
211
+ ASSERT_EQUAL(3, values->operator[](2));
212
212
  }
213
213
 
214
214
  TESTCASE(Copy)
@@ -245,15 +245,16 @@ TESTCASE(Iterate)
245
245
 
246
246
  result = Hash.new
247
247
  unordered_map.each do |pair|
248
- result[pair.first] = 2 * pair.second
249
- end
248
+ result[pair.first] = 2 * pair.second
249
+ end
250
250
  result)";
251
251
 
252
252
  Hash result = m.module_eval(code);
253
253
  ASSERT_EQUAL(3u, result.size());
254
254
 
255
- std::string result_string = result.to_s().str();
256
- ASSERT_EQUAL(R"({"seven"=>14, "six"=>12, "five"=>10})", result_string);
255
+ ASSERT_EQUAL(10, detail::From_Ruby<int>().convert(result["five"].value()));
256
+ ASSERT_EQUAL(12, detail::From_Ruby<int>().convert(result["six"].value()));
257
+ ASSERT_EQUAL(14, detail::From_Ruby<int>().convert(result["seven"].value()));
257
258
  }
258
259
 
259
260
  TESTCASE(ToEnum)
@@ -268,15 +269,17 @@ TESTCASE(ToEnum)
268
269
 
269
270
  result = Hash.new
270
271
  unordered_map.each.each do |pair|
271
- result[pair.first] = 2 * pair.second
272
- end
272
+ result[pair.first] = 2 * pair.second
273
+ end
273
274
  result)";
274
275
 
275
276
  Hash result = m.module_eval(code);
276
277
  ASSERT_EQUAL(3u, result.size());
277
278
 
278
279
  std::string result_string = result.to_s().str();
279
- ASSERT_EQUAL(R"({"seven"=>14, "six"=>12, "five"=>10})", result_string);
280
+ ASSERT_EQUAL(10, detail::From_Ruby<int>().convert(result["five"].value()));
281
+ ASSERT_EQUAL(12, detail::From_Ruby<int>().convert(result["six"].value()));
282
+ ASSERT_EQUAL(14, detail::From_Ruby<int>().convert(result["seven"].value()));
280
283
  }
281
284
 
282
285
  TESTCASE(ToEnumSize)
@@ -321,7 +324,7 @@ TESTCASE(NotComparable)
321
324
 
322
325
  Class c = define_unordered_map<std::unordered_map<std::string, NotComparable>>("NotComparableUnorderedMap");
323
326
 
324
- Object unordered_map = c.call("new");
327
+ Data_Object<std::unordered_map<std::string, NotComparable>> unordered_map = c.call("new");
325
328
  unordered_map.call("[]=", "one", NotComparable(1));
326
329
  unordered_map.call("[]=", "two", NotComparable(2));
327
330
  unordered_map.call("[]=", "three", NotComparable(3));
@@ -340,7 +343,7 @@ TESTCASE(NotPrintable)
340
343
 
341
344
  Class c = define_unordered_map<std::unordered_map<std::string, NotComparable>>("NotComparableUnorderedMap");
342
345
 
343
- Object unordered_map = c.call("new");
346
+ Data_Object<std::unordered_map<std::string, NotComparable>> unordered_map = c.call("new");
344
347
  unordered_map.call("[]=", "one", NotComparable(1));
345
348
  unordered_map.call("[]=", "two", NotComparable(2));
346
349
  unordered_map.call("[]=", "three", NotComparable(3));
@@ -359,7 +362,7 @@ namespace
359
362
  {
360
363
  };
361
364
 
362
- bool operator==(const Comparable& other)
365
+ bool operator==(const Comparable& other) const
363
366
  {
364
367
  return this->value_ == other.value_;
365
368
  }
@@ -381,7 +384,7 @@ TESTCASE(Comparable)
381
384
 
382
385
  Class c = define_unordered_map<std::unordered_map<std::string, Comparable>>("ComparableUnorderedMap");
383
386
 
384
- Object unordered_map = c.call("new");
387
+ Data_Object<std::unordered_map<std::string, Comparable>> unordered_map = c.call("new");
385
388
 
386
389
  unordered_map.call("[]=", "one", Comparable(1));
387
390
  unordered_map.call("[]=", "two", Comparable(2));
@@ -398,13 +401,14 @@ TESTCASE(Printable)
398
401
 
399
402
  Class c = define_unordered_map<std::unordered_map<std::string, Comparable>>("ComparableUnorderedMap");
400
403
 
401
- Object unordered_map = c.call("new");
404
+ Data_Object<std::unordered_map<std::string, Comparable>> unordered_map = c.call("new");
402
405
  unordered_map.call("[]=", "one", Comparable(1));
403
406
  unordered_map.call("[]=", "two", Comparable(2));
404
407
  unordered_map.call("[]=", "three", Comparable(3));
405
408
 
406
- Object result = unordered_map.call("to_s");
407
- ASSERT_EQUAL("{three => Comparable(3), two => Comparable(2), one => Comparable(1)}", detail::From_Ruby<std::string>().convert(result));
409
+ ASSERT_EQUAL(Comparable(1), unordered_map->operator[]("one"));
410
+ ASSERT_EQUAL(Comparable(2), unordered_map->operator[]("two"));
411
+ ASSERT_EQUAL(Comparable(3), unordered_map->operator[]("three"));
408
412
  }
409
413
 
410
414
  namespace