1 // Copyright (C) 2006-2024 CEA, EDF
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
24 #include "Py2yacsTest.hxx"
25 #include "py2yacs.hxx"
27 #include "Executor.hxx"
28 #include "PythonCppUtils.hxx"
30 #include "RuntimeSALOME.hxx"
31 #include "PythonPorts.hxx"
32 #include "InputPort.hxx"
33 //#include "parsers.hxx"
35 void Py2yacsTest::setUp()
37 YACS::ENGINE::RuntimeSALOME::setRuntime();
38 //YACS::ENGINE::getRuntime()->init();
41 void Py2yacsTest::tearDown()
43 //YACS::ENGINE::getRuntime()->fini();
47 void verifyCorrectPycode(const char * code_py, const char * function_name,
48 int nbInputPorts, const char** input_ports,
49 int nbOutputPorts, const char** output_ports)
51 std::cerr << std::endl;
52 std::cerr << "-----------------------------------------------" << std::endl;
53 std::cerr << code_py << std::endl;
54 std::cerr << "-----------------------------------------------" << std::endl;
55 std::cerr << "Function :" << function_name << std::endl;
61 catch(Py2yacsException& e)
63 CPPUNIT_FAIL(e.what());
65 catch(std::exception& e)
67 CPPUNIT_FAIL(e.what());
71 CPPUNIT_FAIL("Unknown exception");
73 YACS::ENGINE::Proc* p = parser.createProc(function_name);
74 CPPUNIT_ASSERT( p != NULL);
75 YACS::ENGINE::Node* n = p->getChildByShortName("default_name");
76 CPPUNIT_ASSERT( n != NULL);
77 CPPUNIT_ASSERT( n->getNumberOfInputPorts() == nbInputPorts);
78 for(int i = 0; i < nbInputPorts; i++)
79 CPPUNIT_ASSERT( n->getInputPort(input_ports[i]) != NULL);
80 CPPUNIT_ASSERT( n->getNumberOfOutputPorts() == nbOutputPorts);
81 for(int i = 0; i < nbOutputPorts; i++)
82 CPPUNIT_ASSERT( n->getOutputPort(output_ports[i]) != NULL);
87 void verifyWrongPycode(const char* code_py, const char* function_name,
88 const char* error_message)
94 YACS::ENGINE::Proc* p = parser.createProc(function_name);
95 CPPUNIT_FAIL("Exception expected and no exception occured.");
97 catch(Py2yacsException& e)
99 std::string what = e.what();
100 std::cerr << std::endl;
101 std::cerr << "-----------------------------------------------" << std::endl;
102 std::cerr << code_py << std::endl;
103 std::cerr << "-----------------------------------------------" << std::endl;
104 std::cerr << "Function :" << function_name << std::endl;
105 std::cerr << "==========EXCEPTION TEXT=======================" << std::endl;
106 std::cerr << what << std::endl;
107 std::cerr << "===============================================" << std::endl;
108 CPPUNIT_ASSERT(what.find(error_message) != std::string::npos);
110 catch(std::exception& e)
112 CPPUNIT_FAIL(e.what());
117 void verifyWrongParser(const char* parser_module, const char* parser_function,
118 const char* error_message)
120 const char* code_py = "def f():\n"
122 Py2yacs parser(parser_module, parser_function);
125 parser.load(code_py);
126 CPPUNIT_FAIL("Exception expected and no exception occured.");
128 catch(Py2yacsException& e)
130 std::string what = e.what();
131 std::cerr << std::endl;
132 std::cerr << "==========EXCEPTION TEXT=======================" << std::endl;
133 std::cerr << what << std::endl;
134 std::cerr << "===============================================" << std::endl;
135 CPPUNIT_ASSERT(what.find(error_message) != std::string::npos);
137 catch(std::exception& e)
139 CPPUNIT_FAIL(e.what());
143 void Py2yacsTest::t1()
145 const char * code_py = "def f1(a, b, c):\n"
148 const char* input_ports[] = {"a", "b", "c"};
149 const char* output_ports[] = {"y"};
150 verifyCorrectPycode(code_py, "f1", 3, input_ports, 1, output_ports);
153 void Py2yacsTest::t2()
155 const char * code_py = "def f1(a, b, c):\n"
160 const char* input_ports[] = {"a", "b", "c"};
161 const char* output_ports[] = {"x", "y", "z"};
162 verifyCorrectPycode(code_py, "f1", 3, input_ports, 3, output_ports);
165 void Py2yacsTest::t3()
167 const char * code_py = "def f1(a, b, c):\n"
171 const char* input_ports[] = {"a", "b", "c"};
172 const char** output_ports;
173 verifyCorrectPycode(code_py, "f1", 3, input_ports, 0, output_ports);
176 void Py2yacsTest::t4()
178 const char * code_py = "def f1():\n"
181 const char* input_ports[] = {"a", "b", "c"};
182 const char** output_ports;
183 verifyCorrectPycode(code_py, "f1", 0, input_ports, 0, output_ports);
186 void Py2yacsTest::t5()
188 const char * code_py = "def f1(a):\n"
200 const char* input_ports[] = {"v"};
201 const char* output_ports[] = {"ret"};
202 verifyCorrectPycode(code_py, "f2", 1, input_ports, 1, output_ports);
205 void Py2yacsTest::no_multiple_returns()
207 const char * code_py = "def f(a):\n"
213 verifyWrongPycode(code_py, "f", "multiple returns.");
216 void Py2yacsTest::unaccepted_statement()
218 const char * code_py = "def f(a):\n"
221 verifyWrongPycode(code_py, "f", "not accepted statement");
224 /* // This is now accepted
225 void Py2yacsTest::unaccepted_statement2()
227 const char * code_py = "def f(a):\n"
229 "if __name__ == '__main__':"
231 verifyWrongPycode(code_py, "f", "not accepted statement");
234 void Py2yacsTest::unaccepted_return()
236 const char * code_py = "def f(a):\n"
238 verifyWrongPycode(code_py, "f", "invalid type returned");
241 void Py2yacsTest::unaccepted_return2()
243 const char * code_py = "def f1(a):\n"
247 verifyWrongPycode(code_py, "f2", "invalid type returned");
250 void Py2yacsTest::syntaxError()
252 const char * code_py = "bla bla bla\n"
254 verifyWrongPycode(code_py, "f2", "invalid syntax");
257 void Py2yacsTest::badFunctionName()
259 const char * code_py = "def f1(a):\n"
265 verifyWrongPycode(code_py, "nonexistant", "Function not found:");
268 void Py2yacsTest::schemaExec()
270 const char * code_py = "def f(a):\n"
276 parser.load(code_py);
278 catch(Py2yacsException& e)
280 CPPUNIT_FAIL(e.what());
284 CPPUNIT_FAIL("Unknown exception");
286 YACS::ENGINE::Proc* p = parser.createProc("f");
287 CPPUNIT_ASSERT( p != NULL);
288 YACS::ENGINE::Node* n = p->getChildByShortName("default_name");
289 CPPUNIT_ASSERT( n != NULL);
290 CPPUNIT_ASSERT( n->getInputPort("a") != NULL);
291 CPPUNIT_ASSERT( n->getOutputPort("x") != NULL);
293 n->getInputPort("a")->edInit(42.);
294 YACS::ENGINE::Executor executor;
296 // verify the output port value
297 YACS::ENGINE::OutputPyPort* var = dynamic_cast<YACS::ENGINE::OutputPyPort*>(n->getOutputPort("x"));
300 PyObject* pyVal = var->get();
303 CPPUNIT_ASSERT(pyVal);
304 x = PyFloat_AsDouble(pyVal);
305 CPPUNIT_ASSERT( PyErr_Occurred()==nullptr );// check pyVal is interpretable as float
307 CPPUNIT_ASSERT_DOUBLES_EQUAL(42., x, 1.E-12);
308 p->shutdown(10); // kill all the containers
311 // Test the behaviour when there is an error in the python parser
312 void Py2yacsTest::parserErrors()
314 verifyWrongParser("bad_parsers", "p1", "0 positional arguments");
315 verifyWrongParser("bad_parsers", "p2", "'str' object has no attribute 'name'");
316 verifyWrongParser("bad_parsers", "p3", "should be a python list");
317 verifyWrongParser("bad_parsers", "p4", "unsupported operand type");
318 verifyWrongParser("bad_parsers", "f", "Cannot find the parsing function");
319 verifyWrongParser("err_py2yacs_invalid", "get_properties", "invalid syntax");
320 verifyWrongParser("no_file", "f", "Failed to load");
321 verifyWrongParser("bad_parsers", "p5", "is not a string");
322 verifyWrongParser("bad_parsers", "p6", "is not a string");
323 verifyWrongParser("bad_parsers", "p7", "is not a string");
324 verifyWrongParser("bad_parsers", "p8", "Attribute 'name' should be a string.");
325 verifyWrongParser("bad_parsers", "p9", "Not a python list");
326 verifyWrongParser("bad_parsers", "p10", "is not a string");
329 void Py2yacsTest::globalVerification()
331 std::ifstream file_stream("exemple_py2yacs.py");
335 std::stringstream buffer;
336 buffer << file_stream.rdbuf();
338 parser.load(buffer.str());
339 std::list<FunctionProperties>::const_iterator it_fp;
340 const std::list<FunctionProperties>& functions = parser.getFunctionProperties();
341 for(it_fp=functions.begin();it_fp!=functions.end();it_fp++)
343 std::cerr << "Function :" << it_fp->_name << std::endl;
344 std::list<std::string>::const_iterator it;
345 std::cerr << "Input ports :" ;
346 for(it=it_fp->_input_ports.begin();it!=it_fp->_input_ports.end();it++)
347 std::cerr << *it << ",";
348 std::cerr << std::endl;
349 std::cerr << "Output ports :" ;
350 for(it=it_fp->_output_ports.begin();it!=it_fp->_output_ports.end();it++)
351 std::cerr << *it << ",";
352 std::cerr << std::endl;
353 std::cerr << "Imports :" ;
354 for(it=it_fp->_imports.begin();it!=it_fp->_imports.end();it++)
355 std::cerr << *it << ",";
356 std::cerr << std::endl;
357 std::cerr << "Errors :" ;
358 for(it=it_fp->_errors.begin();it!=it_fp->_errors.end();it++)
359 std::cerr << *it << std::endl;
360 std::cerr << std::endl;
361 std::cerr << "-----------------------------------------" << std::endl;