ctkAbstractPythonManagerTest.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Qt includes
  2. #include <QTemporaryFile>
  3. #include <QTextStream>
  4. // CTK includes
  5. #include "ctkAbstractPythonManager.h"
  6. #include "ctkTest.h"
  7. // PythonQt includes
  8. #include <PythonQt.h>
  9. // STD includes
  10. #include <cstdlib>
  11. #include <iostream>
  12. //-----------------------------------------------------------------------------
  13. #if QT_VERSION < 0x040700
  14. Q_DECLARE_METATYPE(QVariant)
  15. #endif
  16. //-----------------------------------------------------------------------------
  17. class ctkAbstractPythonManagerTester: public QObject
  18. {
  19. Q_OBJECT
  20. private:
  21. ctkAbstractPythonManager PythonManager;
  22. private Q_SLOTS:
  23. void testDefaults();
  24. void testIsPythonInitialized();
  25. void testSetInitializationFlags();
  26. void testSetSystemExitExceptionHandlerEnabled();
  27. void testPythonErrorOccured();
  28. void testPythonErrorOccured_data();
  29. void testInitialize();
  30. void testMainContext();
  31. void testAddObjectToPythonMain();
  32. //void testRegisterPythonQtDecorator(); // TODO
  33. //void testRegisterClassForPythonQt(); // TODO
  34. void testExecuteString();
  35. void testExecuteString_data();
  36. void testExecuteFile();
  37. void testExecuteFile_data();
  38. //void testPythonAttributes(); // TODO
  39. };
  40. // ----------------------------------------------------------------------------
  41. void ctkAbstractPythonManagerTester::testDefaults()
  42. {
  43. QCOMPARE(this->PythonManager.pythonErrorOccured(), false);
  44. this->PythonManager.resetErrorFlag();
  45. this->PythonManager.registerPythonQtDecorator(0);
  46. this->PythonManager.registerClassForPythonQt(0);
  47. this->PythonManager.registerCPPClassForPythonQt(0);
  48. this->PythonManager.addWrapperFactory(0);
  49. }
  50. // ----------------------------------------------------------------------------
  51. void ctkAbstractPythonManagerTester::testIsPythonInitialized()
  52. {
  53. QCOMPARE(this->PythonManager.isPythonInitialized(), false);
  54. }
  55. // ----------------------------------------------------------------------------
  56. void ctkAbstractPythonManagerTester::testSetInitializationFlags()
  57. {
  58. QCOMPARE(this->PythonManager.initializationFlags(), PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
  59. int flagsToSetPreInit = PythonQt::RedirectStdOut;
  60. int expectedFlagsPreInit = PythonQt::RedirectStdOut;
  61. this->PythonManager.setInitializationFlags(flagsToSetPreInit);
  62. QCOMPARE(this->PythonManager.initializationFlags(), expectedFlagsPreInit);
  63. this->PythonManager.mainContext();
  64. int flagsToSetPostInit = 0;
  65. int expectedFlagsPostInit = PythonQt::RedirectStdOut;
  66. this->PythonManager.setInitializationFlags(flagsToSetPostInit);
  67. QCOMPARE(this->PythonManager.initializationFlags(), expectedFlagsPostInit);
  68. QCOMPARE(this->PythonManager.isPythonInitialized(), true);
  69. }
  70. // ----------------------------------------------------------------------------
  71. void ctkAbstractPythonManagerTester::testSetSystemExitExceptionHandlerEnabled()
  72. {
  73. QCOMPARE(this->PythonManager.systemExitExceptionHandlerEnabled(), false);
  74. this->PythonManager.setSystemExitExceptionHandlerEnabled(true);
  75. QCOMPARE(this->PythonManager.systemExitExceptionHandlerEnabled(), true);
  76. }
  77. // ----------------------------------------------------------------------------
  78. void ctkAbstractPythonManagerTester::testInitialize()
  79. {
  80. QVERIFY(this->PythonManager.initialize());
  81. this->testDefaults();
  82. }
  83. // ----------------------------------------------------------------------------
  84. void ctkAbstractPythonManagerTester::testMainContext()
  85. {
  86. QVERIFY(this->PythonManager.mainContext());
  87. this->testDefaults();
  88. }
  89. // ----------------------------------------------------------------------------
  90. void ctkAbstractPythonManagerTester::testPythonErrorOccured()
  91. {
  92. QFETCH(QString, pythonCode);
  93. QFETCH(bool, errorOccured);
  94. this->PythonManager.executeString(pythonCode);
  95. QCOMPARE(this->PythonManager.pythonErrorOccured(), errorOccured);
  96. if(errorOccured)
  97. {
  98. this->PythonManager.resetErrorFlag();
  99. }
  100. }
  101. // ----------------------------------------------------------------------------
  102. void ctkAbstractPythonManagerTester::testPythonErrorOccured_data()
  103. {
  104. QTest::addColumn<QString>("pythonCode");
  105. QTest::addColumn<bool>("errorOccured");
  106. QTest::newRow("0") << QString("2 + 2") << false;
  107. QTest::newRow("1") << QString("raise Exception('This exception is expected')") << true;
  108. }
  109. // ----------------------------------------------------------------------------
  110. void ctkAbstractPythonManagerTester::testAddObjectToPythonMain()
  111. {
  112. QObject * object = new QObject(this);
  113. object->setProperty("happy", true);
  114. this->PythonManager.addObjectToPythonMain("testAddObjectToPythonMain", object);
  115. QVariant returnValue = this->PythonManager.executeString("testAddObjectToPythonMain.happy",
  116. ctkAbstractPythonManager::EvalInput);
  117. this->PythonManager.resetErrorFlag();
  118. QCOMPARE(returnValue, QVariant(true));
  119. }
  120. // ----------------------------------------------------------------------------
  121. void ctkAbstractPythonManagerTester::testExecuteString()
  122. {
  123. QFETCH(QString, stringToExecute);
  124. QFETCH(int, executeStringMode);
  125. QFETCH(bool, errorOccured);
  126. QFETCH(QVariant, expectedReturnValue);
  127. QFETCH(QString, expectedVariableName);
  128. QFETCH(QVariant, expectedVariableValue);
  129. QVariant returnValue = this->PythonManager.executeString(
  130. stringToExecute,
  131. static_cast<ctkAbstractPythonManager::ExecuteStringMode>(executeStringMode));
  132. QCOMPARE(this->PythonManager.pythonErrorOccured(), errorOccured);
  133. if (errorOccured)
  134. {
  135. this->PythonManager.resetErrorFlag();
  136. return;
  137. }
  138. QCOMPARE(returnValue, expectedReturnValue);
  139. QCOMPARE(this->PythonManager.getVariable(expectedVariableName), expectedVariableValue);
  140. }
  141. // ----------------------------------------------------------------------------
  142. void ctkAbstractPythonManagerTester::testExecuteString_data()
  143. {
  144. QTest::addColumn<QString>("stringToExecute");
  145. QTest::addColumn<int>("executeStringMode");
  146. QTest::addColumn<bool>("errorOccured");
  147. QTest::addColumn<QVariant>("expectedReturnValue");
  148. QTest::addColumn<QString>("expectedVariableName");
  149. QTest::addColumn<QVariant>("expectedVariableValue");
  150. QTest::newRow("0") << QString("a = 6542")
  151. << static_cast<int>(ctkAbstractPythonManager::FileInput)
  152. << false
  153. << QVariant() << QString("a") << QVariant(6542);
  154. QTest::newRow("1") << QString("6543")
  155. << static_cast<int>(ctkAbstractPythonManager::FileInput)
  156. << false
  157. << QVariant() << QString("a") << QVariant(6542);
  158. QTest::newRow("2") << QString("b = 6544")
  159. << static_cast<int>(ctkAbstractPythonManager::EvalInput)
  160. << true
  161. << QVariant() << QString("b") << QVariant();
  162. QTest::newRow("3") << QString("7")
  163. << static_cast<int>(ctkAbstractPythonManager::EvalInput)
  164. << false
  165. << QVariant(7) << QString("b") << QVariant();
  166. QTest::newRow("4") << QString("sys.getrecursionlimit()")
  167. << static_cast<int>(ctkAbstractPythonManager::FileInput)
  168. << false
  169. << QVariant() << QString() << QVariant();
  170. // This assume the default 'recursionlimit' has not been changed
  171. QTest::newRow("5") << QString("sys.getrecursionlimit()")
  172. << static_cast<int>(ctkAbstractPythonManager::EvalInput)
  173. << false
  174. << QVariant(1000) << QString() << QVariant();
  175. }
  176. // ----------------------------------------------------------------------------
  177. void ctkAbstractPythonManagerTester::testExecuteFile()
  178. {
  179. QFETCH(QString, stringToExecute);
  180. QFETCH(bool, pythonErrorExpected);
  181. QTemporaryFile pythonFile("testExecuteFile-XXXXXX.py");
  182. QVERIFY(pythonFile.open());
  183. QTextStream out(&pythonFile);
  184. out << stringToExecute;
  185. pythonFile.close();
  186. this->PythonManager.executeFile(pythonFile.fileName());
  187. QCOMPARE(this->PythonManager.pythonErrorOccured(), pythonErrorExpected);
  188. }
  189. // ----------------------------------------------------------------------------
  190. void ctkAbstractPythonManagerTester::testExecuteFile_data()
  191. {
  192. QTest::addColumn<QString>("stringToExecute");
  193. QTest::addColumn<bool>("pythonErrorExpected");
  194. QTest::newRow("0-emptyfile") << QString("")
  195. << false;
  196. QTest::newRow("1-helloworld") << QString("print 'Hello world'")
  197. << false;
  198. QTest::newRow("2-syntaxerror") << QString("print '") // SyntaxError
  199. << true;
  200. QTest::newRow("3-check __file__ attribute") << QString("print 'This file is: %s' % __file__")
  201. << false;
  202. }
  203. // ----------------------------------------------------------------------------
  204. CTK_TEST_MAIN(ctkAbstractPythonManagerTest)
  205. #include "moc_ctkAbstractPythonManagerTest.cpp"