test/test_Stl_Vector.cpp in rice-4.0.4 vs test/test_Stl_Vector.cpp in rice-4.1.0

- old
+ new

@@ -1,7 +1,6 @@ #include <complex> -#include <memory> #include "unittest.hpp" #include "embed_ruby.hpp" #include <rice/rice.hpp> #include <rice/stl.hpp> @@ -29,11 +28,11 @@ }; } Class makeVectorClass() { - Class c= define_class<MyClass>("MyClass"). + Class c = define_class<MyClass>("MyClass"). define_constructor(Constructor<MyClass>()). define_method("stringVector", &MyClass::stringVector); return c; } @@ -42,19 +41,19 @@ { Module m = define_module("Testing"); Class c = define_vector<std::vector<std::string>>("StringVector"); - Object vec = m.instance_eval("$vector = StringVector.new"); + Object vec = m.module_eval("$vector = StringVector.new"); Object result = vec.call("size"); ASSERT_EQUAL(0, detail::From_Ruby<int32_t>().convert(result)); - m.instance_eval("$vector << 'one' << 'two' << 'two' << 'three'"); + m.module_eval("$vector << 'one' << 'two' << 'two' << 'three'"); result = vec.call("size"); ASSERT_EQUAL(4, detail::From_Ruby<int32_t>().convert(result)); - m.instance_eval("$vector.append('four')"); + m.module_eval("$vector.append('four')"); result = vec.call("size"); ASSERT_EQUAL(5, detail::From_Ruby<int32_t>().convert(result)); result = vec.call("first"); ASSERT_EQUAL("one", detail::From_Ruby<std::string>().convert(result)); @@ -67,14 +66,14 @@ { Module m = define_module("Testing"); Class c = define_vector<std::vector<std::string>>("StringVector"); - Object vec = m.instance_eval("$vector = StringVector.new"); + Object vec = m.module_eval("$vector = StringVector.new"); ASSERT_EXCEPTION_CHECK( Exception, - m.instance_eval("$vector << 1"), + m.module_eval("$vector << 1"), ASSERT_EQUAL("wrong argument type Integer (expected String)", ex.what())); } TESTCASE(Empty) { @@ -259,28 +258,10 @@ vecCopy.push_back(33.3); ASSERT_NOT_EQUAL(vec.size(), vecCopy.size()); } -TESTCASE(Iterate) -{ - Module m = define_module("Testing"); - Class c = define_vector<std::vector<double>>("DoubleVector"); - - std::string code = R"(vector = DoubleVector.new - vector << 5.0 << 6.0 << 7.0 - updated = vector.map do |value| - value * 2.0 - end)"; - - Array result = m.instance_eval(code); - ASSERT_EQUAL(3, result.size()); - ASSERT_EQUAL(10.0, detail::From_Ruby<double>().convert(result[0].value())); - ASSERT_EQUAL(12.0, detail::From_Ruby<double>().convert(result[1].value())); - ASSERT_EQUAL(14.0, detail::From_Ruby<double>().convert(result[2].value())); -} - namespace { class NotComparable { public: @@ -306,11 +287,11 @@ Object result = vec.call("delete", NotComparable(1)); ASSERT_EQUAL(Qnil, result.value()); result = vec.call("length"); - ASSERT_EQUAL(3, detail::From_Ruby<size_t>().convert(result)); + ASSERT_EQUAL(3u, detail::From_Ruby<size_t>().convert(result)); result = vec.call("include?", NotComparable(2)); ASSERT_EQUAL(Qfalse, result.value()); result = vec.call("index", NotComparable(3)); @@ -435,17 +416,17 @@ ASSERT_EQUAL("[Comparable(1), Comparable(2), Comparable(3)]", detail::From_Ruby<std::string>().convert(result)); } namespace { - std::vector<std::complex<uint32_t>> returnComplexVector() + std::vector<std::complex<double>> returnComplexVector() { - std::complex<uint32_t> complex1(1, 1); - std::complex<uint32_t> complex2(2, 2); - std::complex<uint32_t> complex3(3, 3); + std::complex<double> complex1(1, 1); + std::complex<double> complex2(2, 2); + std::complex<double> complex3(3, 3); - std::vector<std::complex<uint32_t>> result; + std::vector<std::complex<double>> result; result.push_back(complex1); result.push_back(complex2); result.push_back(complex3); return result; } @@ -459,19 +440,31 @@ TESTCASE(AutoRegisterReturn) { define_global_function("return_complex_vector", &returnComplexVector); Module m = define_module("Testing"); - Object vec = m.instance_eval("return_complex_vector"); - ASSERT_EQUAL("Rice::Std::Vector__complex__unsignedInt___allocator__complex__unsignedInt______", vec.class_name().str()); + Object vec = m.module_eval("return_complex_vector"); + ASSERT_EQUAL("Rice::Std::Vector__complex__double___allocator__complex__double______", vec.class_name().str()); std::string code = R"(vector = return_complex_vector complex = vector.last complex == Complex(3, 3))"; - Object result = m.instance_eval(code); + Object result = m.module_eval(code); ASSERT_EQUAL(Qtrue, result.value()); + + // Now register this same vector + define_vector<std::vector<std::complex<double>>>("ComplexVector"); + code = R"(vector = ComplexVector.new)"; + result = m.module_eval(code); + ASSERT(result.is_instance_of(vec.class_of())); + + // Now register it again in the module + define_vector_under<std::vector<std::complex<double>>>(m, "ComplexVector2"); + code = R"(vector = Testing::ComplexVector2.new)"; + result = m.module_eval(code); + ASSERT(result.is_instance_of(vec.class_of())); } TESTCASE(AutoRegisterParameter) { define_global_function("pass_complex_vector", &passComplexVector); @@ -480,11 +473,11 @@ vector << Complex(4.0, 4.0) vector << Complex(5.0, 5.0) pass_complex_vector(vector))"; Module m = define_module("Testing"); - Object vec = m.instance_eval(code); + Object vec = m.module_eval(code); Object result = vec.call("size"); ASSERT_EQUAL("Rice::Std::Vector__complex__double___allocator__complex__double______", vec.class_name().str()); ASSERT_EQUAL(2, detail::From_Ruby<int32_t>().convert(result)); @@ -505,21 +498,42 @@ { define_vector<std::vector<std::string>>("StringVector"); define_global_function("default_vector", &defaultVector, Arg("strings") = std::vector<std::string> { "one", "two", "three" }); Module m = define_module("Testing"); - Object result = m.instance_eval("default_vector"); + Object result = m.module_eval("default_vector"); std::vector<std::string> actual = detail::From_Ruby<std::vector<std::string>>().convert(result); std::vector<std::string> expected{ "one", "two", "three" }; ASSERT_EQUAL(expected.size(), actual.size()); ASSERT_EQUAL(expected[0], actual[0]); ASSERT_EQUAL(expected[1], actual[1]); ASSERT_EQUAL(expected[2], actual[2]); } +TESTCASE(ToArray) +{ + Module m = define_module("Testing"); + + Class c = define_vector<std::vector<std::string>>("StringVector"). + define_constructor(Constructor<std::vector<std::string>>()); + + std::string code = R"(vector = StringVector.new + vector << "abc" + vector << "def" + vector << "ghi" + vector.to_a)"; + + Array array = m.module_eval(code); + ASSERT_EQUAL(3u, array.size()); + + ASSERT_EQUAL("abc", detail::From_Ruby<std::string>().convert(array[0].value())); + ASSERT_EQUAL("def", detail::From_Ruby<std::string>().convert(array[1].value())); + ASSERT_EQUAL("ghi", detail::From_Ruby<std::string>().convert(array[2].value())); +} + namespace { std::vector<int> ints; std::vector<float> floats; std::vector<std::string> strings; @@ -551,11 +565,11 @@ define_global_function("array_to_vector", &arrayToVector); Module m = define_module("Testing"); std::string code = "array_to_vector([7, 9, 1_000_000], [49.0, 78.0, 999.0], %w[one two three])"; - m.instance_eval(code); + m.module_eval(code); ASSERT_EQUAL(3, ints.size()); ASSERT_EQUAL(7, ints[0]); ASSERT_EQUAL(9, ints[1]); ASSERT_EQUAL(1'000'000, ints[2]); @@ -576,11 +590,11 @@ define_global_function("array_to_vector_refs", &arrayToVectorRefs); Module m = define_module("Testing"); std::string code = "array_to_vector_refs([8, 10, 1_000_001], [50.0, 79.0, 1_000.0], %w[eleven twelve thirteen])"; - m.instance_eval(code); + m.module_eval(code); ASSERT_EQUAL(3, ints.size()); ASSERT_EQUAL(8, ints[0]); ASSERT_EQUAL(10, ints[1]); ASSERT_EQUAL(1'000'001, ints[2]); @@ -601,11 +615,11 @@ define_global_function("array_to_vector_pointers", &arrayToVectorPointers); Module m = define_module("Testing"); std::string code = "array_to_vector_pointers([9, 11, 1_000_002], [51.0, 80.0, 1_001.0], %w[fourteen fifteen sixteen])"; - m.instance_eval(code); + m.module_eval(code); ASSERT_EQUAL(3, ints.size()); ASSERT_EQUAL(9, ints[0]); ASSERT_EQUAL(11, ints[1]); ASSERT_EQUAL(1'000'002, ints[2]); @@ -629,11 +643,11 @@ std::string code = "array_to_vector([7, 9, 1_000_000], [49.0, 78.0, 999.0], [50.0, 79.0, 1000.0])"; ASSERT_EXCEPTION_CHECK( Exception, - m.instance_eval(code), + m.module_eval(code), ASSERT_EQUAL("wrong argument type Float (expected String)", ex.what()) ); } TESTCASE(ArrayToVectorMixedTypes) @@ -644,9 +658,154 @@ std::string code = "array_to_vector([7, 'nine', true], [49.0, 78.0, 999.0], %w[one two three])"; ASSERT_EXCEPTION_CHECK( Exception, - m.instance_eval(code), + m.module_eval(code), ASSERT_EQUAL("no implicit conversion of String into Integer", ex.what()) ); +} + +namespace +{ + class Factory + { + public: + std::vector<std::string>* returnPointer() + { + return &this->instance_; + } + + std::vector<std::string>& returnReference() + { + return this->instance_; + } + + std::vector<std::string> returnValue() + { + return this->instance_; + } + + public: + static inline std::vector<std::string> instance_{ "one", "two", "three" }; + }; + + std::ostream& operator<<(std::ostream& stream, const std::vector<std::string>& vector) + { + stream << "Vector"; + return stream; + } +} + +void createFactoryClass() +{ + define_class<Factory>("Factory"). + define_constructor(Constructor<Factory>()). + define_method("pointer", &Factory::returnPointer). + define_method("reference", &Factory::returnReference). + define_method("value", &Factory::returnValue); +} + +TESTCASE(Returns) +{ + createFactoryClass(); + Module m = define_module("TestingModule"); + Object factory = m.module_eval("Factory.new"); + + std::vector<std::string> expected{ "one", "two", "three" }; + + Data_Object<std::vector<std::string>> vec1 = factory.call("pointer"); + ASSERT_EQUAL(expected, *vec1); + + Data_Object<std::vector<std::string>> vec2 = factory.call("reference"); + ASSERT_EQUAL(expected, *vec2); + + Data_Object<std::vector<std::string>> vec3 = factory.call("value"); + ASSERT_EQUAL(expected, *vec3); +} + +TESTCASE(Iterate) +{ + Module m = define_module("Testing"); + Class c = define_vector<std::vector<double>>("DoubleVector"); + + std::string code = R"(vector = DoubleVector.new + vector << 5.0 << 6.0 << 7.0 + updated = vector.map do |value| + value * 2.0 + end)"; + + Array result = m.module_eval(code); + ASSERT_EQUAL(3, result.size()); + ASSERT_EQUAL(10.0, detail::From_Ruby<double>().convert(result[0].value())); + ASSERT_EQUAL(12.0, detail::From_Ruby<double>().convert(result[1].value())); + ASSERT_EQUAL(14.0, detail::From_Ruby<double>().convert(result[2].value())); +} + +TESTCASE(ToEnumPointer) +{ + createFactoryClass(); + Module m = define_module("TestingModule"); + + std::string code = R"(factory = Factory.new + vector = factory.pointer + updated = vector.each.map do |value| + value + "_updated" + end)"; + + Array result = m.module_eval(code); + + ASSERT_EQUAL(3, result.size()); + ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value())); + ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[1].value())); + ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[2].value())); +} + +TESTCASE(ToEnumReference) +{ + createFactoryClass(); + Module m = define_module("TestingModule"); + + std::string code = R"(factory = Factory.new + vector = factory.reference + updated = vector.each.map do |value| + value + "_updated" + end)"; + + Array result = m.module_eval(code); + + ASSERT_EQUAL(3, result.size()); + ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value())); + ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[1].value())); + ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[2].value())); +} + +TESTCASE(ToEnumValue) +{ + createFactoryClass(); + Module m = define_module("TestingModule"); + + std::string code = R"(factory = Factory.new + vector = factory.value + updated = vector.each.map do |value| + value + "_updated" + end)"; + + Array result = m.module_eval(code); + + ASSERT_EQUAL(3, result.size()); + ASSERT_EQUAL("one_updated", detail::From_Ruby<std::string>().convert(result[0].value())); + ASSERT_EQUAL("two_updated", detail::From_Ruby<std::string>().convert(result[1].value())); + ASSERT_EQUAL("three_updated", detail::From_Ruby<std::string>().convert(result[2].value())); +} + +TESTCASE(ToEnumSize) +{ + createFactoryClass(); + Module m = define_module("TestingModule"); + Object factory = m.module_eval("Factory.new"); + Object vector = factory.call("pointer"); + Object enumerable = vector.call("each"); + Object result = enumerable.call("size"); + + ASSERT_EQUAL(3, detail::From_Ruby<int>().convert(result)); }