rice 4.2.1 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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