1 // Copyright (C) 2019 EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "ConversionTest.hxx"
22 void ConversionTest::setUp()
27 void ConversionTest::tearDown()
32 void ConversionTest::cleanUp(){}
34 void ConversionTest::basicTest()
36 CPPUNIT_ASSERT(42==py2cpp::fromPyPtr<int>(py2cpp::toPyPtr(42)));
37 CPPUNIT_ASSERT(4.2==py2cpp::fromPyPtr<double>(py2cpp::toPyPtr(4.2)));
38 CPPUNIT_ASSERT(py2cpp::fromPyPtr<bool>(py2cpp::toPyPtr(true)));
39 CPPUNIT_ASSERT(!py2cpp::fromPyPtr<bool>(py2cpp::toPyPtr(false)));
41 toto = py2cpp::fromPyPtr<std::string>(py2cpp::toPyPtr(std::string("toto")));
42 CPPUNIT_ASSERT(toto == "toto");
44 auto v = std::make_tuple(4, 4.2);
45 py2cpp::PyPtr obj = py2cpp::toPyPtr(v);
50 std::tuple<int&, double&> tup(i, d);
51 py2cpp::fromPyPtr(obj, tup);
52 CPPUNIT_ASSERT(4==std::get<0>(tup));
53 CPPUNIT_ASSERT(4.2==std::get<1>(tup));
56 py2cpp::pyResult(i2, d2) = obj;
57 CPPUNIT_ASSERT(4==i2);
58 CPPUNIT_ASSERT(4.2==d2);
59 py2cpp::pyResult(i2) = py2cpp::toPyPtr(42);
60 CPPUNIT_ASSERT(42 == i2);
61 py2cpp::PyPtr copy(obj);
63 py2cpp::pyResult(i2, d2) = copy;
64 CPPUNIT_ASSERT(4==i2);
65 CPPUNIT_ASSERT(4.2==d2);
69 py2cpp::pyResult(i2, d2) = copy2;
70 CPPUNIT_ASSERT(4==i2);
71 CPPUNIT_ASSERT(4.2==d2);
74 void ConversionTest::functionTest()
79 py2cpp::PyFunction fn;
81 CPPUNIT_ASSERT(fn.load("TestPy2cpp", "f1"));
83 py2cpp::pyResult(i, d) = fn(5, 4.8);
85 CPPUNIT_ASSERT(6.7==d);
86 CPPUNIT_ASSERT(0==py2cpp::getLastPyError().size());
88 fn.load("TestPy2cpp", "f2");
90 py2cpp::pyResult(str) = fn();
91 CPPUNIT_ASSERT(str=="Hello world!");
92 CPPUNIT_ASSERT(0==py2cpp::getLastPyError().size());
94 fn.load("TestPy2cpp", "f3");
96 py2cpp::pyResult(d, str) = fn(7, 2, "Toto");
97 CPPUNIT_ASSERT(3.5 == d);
98 CPPUNIT_ASSERT(str == "Toto is here!");
99 CPPUNIT_ASSERT(0==py2cpp::getLastPyError().size());
101 CPPUNIT_ASSERT(!fn.load("nonexistent","nonexistent"));
103 CPPUNIT_ASSERT(0 < py2cpp::getLastPyError().size());
106 void ConversionTest::vectorTest()
108 std::vector<double> v = {1.1, 2.2, 3.3, 4.4};
109 py2cpp::PyPtr obj = py2cpp::toPyPtr(v);
110 py2cpp::fromPyPtr(obj, v);
112 std::vector<double> result;
113 py2cpp::PyFunction fn;
114 fn.load("TestPy2cpp", "add1ToList");
115 py2cpp::pyResult(result) = fn(v);
117 CPPUNIT_ASSERT(std::vector<double>({2.1, 3.2, 4.3, 5.4}) == result);
120 void ConversionTest::listTest()
122 std::list<double> v = {1.1, 2.2, 3.3, 4.4};
123 py2cpp::PyPtr obj = py2cpp::toPyPtr(v);
124 py2cpp::fromPyPtr(obj, v);
126 std::list<double> result;
127 py2cpp::PyFunction fn;
128 fn.load("TestPy2cpp", "add1ToList");
129 py2cpp::pyResult(result) = fn(v);
131 CPPUNIT_ASSERT(std::list<double>({2.1, 3.2, 4.3, 5.4}) == result);
134 void ConversionTest::pyobjTest()
136 py2cpp::PyFunction objcall;
137 objcall.load("TestPy2cpp","MyClass");
138 CPPUNIT_ASSERT(objcall);
139 py2cpp::PyPtr obj = objcall(std::list<std::string>({"Toto", "Titi", "Zaza"}),
140 std::vector<double>({5.5, 2.7, 1.8, 9.2}));
141 py2cpp::PyFunction objFn1, objFn2, objFn3;
142 objFn1.load(obj, "namesTogether");
143 objFn2.load(obj, "valuesSum");
144 objFn3.load(obj, "addVal");
145 std::string strResult;
147 py2cpp::pyResult(strResult) = objFn1();
148 py2cpp::pyResult(dbResult) = objFn2();
149 CPPUNIT_ASSERT(strResult == "Toto-Titi-Zaza");
150 CPPUNIT_ASSERT(19.2 == dbResult);
153 py2cpp::pyResult(dbResult) = objFn2();
154 CPPUNIT_ASSERT(23.2 == dbResult);
156 py2cpp::PyFunction myObjectSize;
157 myObjectSize.load("TestPy2cpp", "myObjectSize");
159 py2cpp::pyResult(i) = myObjectSize(obj);
160 CPPUNIT_ASSERT(7==i);
161 CPPUNIT_ASSERT(obj.getAttr("names").repr() == "['Toto', 'Titi', 'Zaza']");
162 CPPUNIT_ASSERT(obj.getAttr("values").repr() == "[6.5, 3.7, 2.8, 10.2]");
164 objFn1.load("TestPy2cpp","newobj");
165 py2cpp::PyPtr newobj;
166 py2cpp::pyResult(newobj, i) = objFn1(obj, std::vector<int>({1,2,3}));
167 CPPUNIT_ASSERT(6==i);
168 CPPUNIT_ASSERT(newobj.getAttr("names").repr() == "['Toto', 'Titi', 'Zaza']");
169 CPPUNIT_ASSERT(newobj.getAttr("values").repr() == "[1, 2, 3]");
172 void ConversionTest::pyErrorTest()
176 py2cpp::PyFunction fn;
177 fn.load("TestPy2cpp", "f3");
181 CPPUNIT_FAIL("Expected exception 'py2cpp::ExecutionException'!");
183 catch (const py2cpp::ExecutionException& err)
186 CPPUNIT_ASSERT(str.find("ZeroDivisionError:") != std::string::npos) ;
191 py2cpp::pyResult(d, str) = fn(7, 0, "problem");
192 CPPUNIT_FAIL("Expected exception 'py2cpp::ExecutionException'!");
194 catch (const py2cpp::ExecutionException& err)
197 CPPUNIT_ASSERT(str.find("ZeroDivisionError:") != std::string::npos) ;
201 void ConversionTest::castErrorTest()
207 std::vector<double> vd;
208 std::vector<std::string> vs;
209 std::map<std::string, std::vector<double> > msvd;
210 py2cpp::ConversionCheck check;
213 obj = py2cpp::toPyPtr(42);
214 check = py2cpp::fromPyPtr(obj, d);
215 CPPUNIT_ASSERT(check);
216 check = py2cpp::fromPyPtr(obj, vi);
217 CPPUNIT_ASSERT(check.getMessage() ==
218 "Cannot convert the python object <42> to c++ type std::vector.\n");
219 check = py2cpp::fromPyPtr(obj, str);
220 CPPUNIT_ASSERT(check.getMessage() ==
221 "Cannot convert the python object <42> to c++ type std::string.\n");
222 check = py2cpp::fromPyPtr(obj, msvd);
223 CPPUNIT_ASSERT(check.getMessage() ==
224 "Cannot convert the python object <42> to c++ type std::map.\n");
226 obj = py2cpp::toPyPtr(std::vector<int>({1,2,3,4,5,6}));
227 check = py2cpp::fromPyPtr(obj, i);
228 CPPUNIT_ASSERT(check.getMessage() ==
229 "Cannot convert the python object <[1, 2, 3, 4, 5, 6]> to c++ type int.\n");
230 check = py2cpp::fromPyPtr(obj, d);
231 CPPUNIT_ASSERT(check.getMessage() ==
232 "Cannot convert the python object <[1, 2, 3, 4, 5, 6]> to c++ type double.\n");
233 check = py2cpp::fromPyPtr(obj, vi);
234 CPPUNIT_ASSERT(check);
235 check = py2cpp::fromPyPtr(obj, vd);
236 CPPUNIT_ASSERT(check);
237 check = py2cpp::fromPyPtr(obj, str);
238 CPPUNIT_ASSERT(check.getMessage() ==
239 "Cannot convert the python object <[1, 2, 3, 4, 5, 6]> to c++ type std::string.\n"
242 check = py2cpp::fromPyPtr(obj, vs);
243 CPPUNIT_ASSERT(check.getMessage() ==
244 "Cannot convert the python object <1> to c++ type std::string.\n"
245 "Cannot convert the python object <[1, 2, 3, 4, 5, 6]> to c++ type std::vector.\n"
247 check = py2cpp::fromPyPtr(obj, msvd);
248 CPPUNIT_ASSERT(check.getMessage() ==
249 "Cannot convert the python object <[1, 2, 3, 4, 5, 6]> to c++ type std::map.\n");
251 std::map<int, double> mid({ {1, 1.1},{2, 2.2},{3, 3.3},{4, 4.4},{5, 5.5}});
252 obj = py2cpp::toPyPtr(mid);
253 check = py2cpp::fromPyPtr(obj, i);
254 // Cannot check the message because the string representation of the python
255 // dictionary may change.
256 CPPUNIT_ASSERT(!check);
257 check = py2cpp::fromPyPtr(obj, vd);
258 CPPUNIT_ASSERT(!check);
259 check = py2cpp::fromPyPtr(obj, msvd);
260 CPPUNIT_ASSERT(!check);
262 std::map<std::string, double> msd({ {"1", 1.1},{"2", 2.2},{"3", 3.3},
263 {"4", 4.4},{"5", 5.5}});
264 obj = py2cpp::toPyPtr(msd);
265 check = py2cpp::fromPyPtr(obj, msvd);
266 CPPUNIT_ASSERT(!check);
268 std::map<std::string, std::vector<std::string> > msvs ;
269 msvs["a"] = std::vector<std::string>({"azer", "aqwx"});
270 msvs["b"] = std::vector<std::string>({"bn,", "bvcxw"});
271 obj = py2cpp::toPyPtr(msvs);
272 check = py2cpp::fromPyPtr(obj, msvd);
273 CPPUNIT_ASSERT(!check);
276 CPPUNIT_TEST_SUITE_REGISTRATION( ConversionTest );
277 #include "TestMain.cxx"