Browse Source

Merge branch 'initialize-method-for-pythonqt-flags'

* initialize-method-for-pythonqt-flags:
  Provide mechanism to set PythonQt initialization flags.
  Facilitate maintenance of the code by converting ctkAbstractPythonManagerTest1 to use ctkTest
Jean-Christophe Fillion-Robin 13 years ago
parent
commit
edf82958ad

+ 9 - 2
Libs/Scripting/Python/Core/Testing/Cpp/CMakeLists.txt

@@ -1,7 +1,7 @@
 set(KIT ${PROJECT_NAME})
 
 create_test_sourcelist(Tests ${KIT}CppTests.cpp
-  ctkAbstractPythonManagerTest1.cpp
+  ctkAbstractPythonManagerTest.cpp
   #EXTRA_INCLUDE TestingMacros.h
   )
 
@@ -10,6 +10,13 @@ REMOVE (TestsToRun ${KIT}CppTests.cpp)
 
 set(LIBRARY_NAME ${PROJECT_NAME})
 
+include_directories(${CMAKE_SOURCE_DIR}/Libs/Testing
+                    ${CMAKE_CURRENT_BINARY_DIR})
+
+QT4_GENERATE_MOCS(
+  ctkAbstractPythonManagerTest.cpp
+  )
+
 add_executable(${KIT}CppTests ${Tests})
 target_link_libraries(${KIT}CppTests ${LIBRARY_NAME} ${CTK_BASE_LIBRARIES})
 
@@ -17,4 +24,4 @@ target_link_libraries(${KIT}CppTests ${LIBRARY_NAME} ${CTK_BASE_LIBRARIES})
 # Add Tests
 #
 
-SIMPLE_TEST( ctkAbstractPythonManagerTest1 )
+SIMPLE_TEST( ctkAbstractPythonManagerTest )

+ 156 - 0
Libs/Scripting/Python/Core/Testing/Cpp/ctkAbstractPythonManagerTest.cpp

@@ -0,0 +1,156 @@
+
+// CTK includes
+#include "ctkAbstractPythonManager.h"
+#include "ctkTest.h"
+
+// PythonQt includes
+#include <PythonQt.h>
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+class ctkAbstractPythonManagerTester: public QObject
+{
+  Q_OBJECT
+private:
+  ctkAbstractPythonManager PythonManager;
+
+private Q_SLOTS:
+
+  void testIsPythonInitialized();
+
+  void testSetInitializationFlags();
+
+  void testPythonErrorOccured();
+  void testPythonErrorOccured_data();
+
+  void testMainContext();
+
+  void testAddObjectToPythonMain();
+
+  //void testRegisterPythonQtDecorator(); // TODO
+  //void testRegisterClassForPythonQt(); // TODO
+
+  void testExecuteString();
+  void testExecuteString_data();
+
+  //void testExecuteFile(); // TODO
+
+  //void testPythonAttributes(); // TODO
+};
+
+// ----------------------------------------------------------------------------
+void ctkAbstractPythonManagerTester::testIsPythonInitialized()
+{
+  QCOMPARE(this->PythonManager.isPythonInitialized(), false);
+}
+
+// ----------------------------------------------------------------------------
+void ctkAbstractPythonManagerTester::testSetInitializationFlags()
+{
+  QCOMPARE(this->PythonManager.initializationFlags(), PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
+
+  int flagsToSetPreInit = PythonQt::RedirectStdOut;
+  int expectedFlagsPreInit = PythonQt::RedirectStdOut;
+
+  this->PythonManager.setInitializationFlags(flagsToSetPreInit);
+  QCOMPARE(this->PythonManager.initializationFlags(), expectedFlagsPreInit);
+
+  this->PythonManager.mainContext();
+
+  int flagsToSetPostInit = 0;
+  int expectedFlagsPostInit = PythonQt::RedirectStdOut;
+
+  this->PythonManager.setInitializationFlags(flagsToSetPostInit);
+  QCOMPARE(this->PythonManager.initializationFlags(), expectedFlagsPostInit);
+
+  QCOMPARE(this->PythonManager.isPythonInitialized(), true);
+}
+
+// ----------------------------------------------------------------------------
+void ctkAbstractPythonManagerTester::testMainContext()
+{
+  QVERIFY(this->PythonManager.mainContext());
+}
+
+// ----------------------------------------------------------------------------
+void ctkAbstractPythonManagerTester::testPythonErrorOccured()
+{
+  QFETCH(QString, pythonCode);
+  QFETCH(bool, errorOccured);
+
+  this->PythonManager.executeString(pythonCode);
+
+  QCOMPARE(this->PythonManager.pythonErrorOccured(), errorOccured);
+}
+
+// ----------------------------------------------------------------------------
+void ctkAbstractPythonManagerTester::testPythonErrorOccured_data()
+{
+  QTest::addColumn<QString>("pythonCode");
+  QTest::addColumn<bool>("errorOccured");
+
+  QTest::newRow("0") << QString("2 + 2") << false;
+
+  QTest::newRow("1") << QString("raise Exception('This is exception is expected')") << true;
+}
+
+// ----------------------------------------------------------------------------
+void ctkAbstractPythonManagerTester::testAddObjectToPythonMain()
+{
+  QObject * object = new QObject(this);
+  object->setProperty("happy", true);
+  this->PythonManager.addObjectToPythonMain("testAddObjectToPythonMain", object);
+  QVariant returnValue = this->PythonManager.executeString("testAddObjectToPythonMain.happy",
+                                                           ctkAbstractPythonManager::EvalInput);
+  QCOMPARE(returnValue, QVariant(true));
+}
+
+// ----------------------------------------------------------------------------
+void ctkAbstractPythonManagerTester::testExecuteString()
+{
+  QFETCH(QString, stringToExecute);
+  QFETCH(int, executeStringMode);
+  QFETCH(QVariant, expectedReturnValue);
+  QFETCH(QString, expectedVariableName);
+  QFETCH(QVariant, expectedVariableValue);
+
+  QVariant returnValue = this->PythonManager.executeString(
+        stringToExecute,
+        static_cast<ctkAbstractPythonManager::ExecuteStringMode>(executeStringMode));
+
+  QCOMPARE(returnValue, expectedReturnValue);
+  QCOMPARE(this->PythonManager.getVariable(expectedVariableName), expectedVariableValue);
+}
+
+// ----------------------------------------------------------------------------
+void ctkAbstractPythonManagerTester::testExecuteString_data()
+{
+  QTest::addColumn<QString>("stringToExecute");
+  QTest::addColumn<int>("executeStringMode");
+  QTest::addColumn<QVariant>("expectedReturnValue");
+  QTest::addColumn<QString>("expectedVariableName");
+  QTest::addColumn<QVariant>("expectedVariableValue");
+
+  QTest::newRow("0") << QString("a = 6542")
+                     << static_cast<int>(ctkAbstractPythonManager::FileInput)
+                     << QVariant() << QString("a") << QVariant(6542);
+
+  QTest::newRow("1") << QString("6543")
+                     << static_cast<int>(ctkAbstractPythonManager::FileInput)
+                     << QVariant() << QString("a") << QVariant(6542);
+
+  QTest::newRow("2") << QString("b = 6544")
+                     << static_cast<int>(ctkAbstractPythonManager::EvalInput)
+                     << QVariant() << QString("b") << QVariant();
+
+  QTest::newRow("3") << QString("7")
+                     << static_cast<int>(ctkAbstractPythonManager::EvalInput)
+                     << QVariant(7) << QString("b") << QVariant();
+}
+
+// ----------------------------------------------------------------------------
+CTK_TEST_MAIN(ctkAbstractPythonManagerTest)
+#include "moc_ctkAbstractPythonManagerTest.cpp"

+ 0 - 65
Libs/Scripting/Python/Core/Testing/Cpp/ctkAbstractPythonManagerTest1.cpp

@@ -1,65 +0,0 @@
-
-// CTK includes
-#include "ctkAbstractPythonManager.h"
-
-// PythonQt includes
-#include <PythonQt.h>
-
-// STD includes
-#include <cstdlib>
-#include <iostream>
-
-//-----------------------------------------------------------------------------
-int ctkAbstractPythonManagerTest1(int argc, char * argv [] )
-{
-  Q_UNUSED(argc);
-  Q_UNUSED(argv);
-
-  ctkAbstractPythonManager pythonManager;
-
-  if (pythonManager.isPythonInitialized())
-    {
-    std::cerr << "Line " << __LINE__ << " - Problem with isPythonInitialized()" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  pythonManager.mainContext();
-
-  if (!pythonManager.isPythonInitialized())
-    {
-    std::cerr << "Line " << __LINE__ << " - Problem with isPythonInitialized()" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  pythonManager.executeString("a = 6542");
-  if (pythonManager.getVariable("a").toInt() != 6542)
-    {
-    std::cerr << "Line " << __LINE__ << " - Problem with executeString()" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  // Expected to return an empty value
-  QVariant result = pythonManager.executeString("6542");
-  if (!result.isNull())
-    {
-    std::cerr << "Line " << __LINE__ << " - Problem with executeString()" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  // Expected to fail
-  result = pythonManager.executeString("b = 6542", ctkAbstractPythonManager::EvalInput);
-  if (!result.isNull())
-    {
-    std::cerr << "Line " << __LINE__ << " - Problem with executeString()" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  result = pythonManager.executeString("7", ctkAbstractPythonManager::EvalInput);
-  if (result.toInt() != 7)
-    {
-    std::cerr << "Line " << __LINE__ << " - Problem with executeString()" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  return EXIT_SUCCESS;
-}

+ 25 - 5
Libs/Scripting/Python/Core/ctkAbstractPythonManager.cpp

@@ -51,6 +51,8 @@ public:
   virtual ~ctkAbstractPythonManagerPrivate();
 
   void (*InitFunction)();
+
+  int PythonQtInitializationFlags;
 };
 
 //-----------------------------------------------------------------------------
@@ -61,6 +63,7 @@ ctkAbstractPythonManagerPrivate::ctkAbstractPythonManagerPrivate(ctkAbstractPyth
   q_ptr(&object)
 {
   this->InitFunction = 0;
+  this->PythonQtInitializationFlags = PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut;
 }
 
 //-----------------------------------------------------------------------------
@@ -88,11 +91,30 @@ ctkAbstractPythonManager::~ctkAbstractPythonManager()
 }
 
 //-----------------------------------------------------------------------------
+void ctkAbstractPythonManager::setInitializationFlags(int flags)
+{
+  Q_D(ctkAbstractPythonManager);
+  if (PythonQt::self())
+    {
+    return;
+    }
+  d->PythonQtInitializationFlags = flags;
+}
+
+//-----------------------------------------------------------------------------
+int ctkAbstractPythonManager::initializationFlags()const
+{
+  Q_D(const ctkAbstractPythonManager);
+  return d->PythonQtInitializationFlags;
+}
+
+//-----------------------------------------------------------------------------
 PythonQtObjectPtr ctkAbstractPythonManager::mainContext()
 {
+  Q_D(ctkAbstractPythonManager);
   if (!PythonQt::self())
     {
-    this->initPythonQt();
+    this->initPythonQt(d->PythonQtInitializationFlags);
     }
   if (PythonQt::self())
     {
@@ -102,11 +124,11 @@ PythonQtObjectPtr ctkAbstractPythonManager::mainContext()
 }
 
 //-----------------------------------------------------------------------------
-void ctkAbstractPythonManager::initPythonQt()
+void ctkAbstractPythonManager::initPythonQt(int flags)
 {
   Q_D(ctkAbstractPythonManager);
 
-  PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
+  PythonQt::init(flags);
 
   // Python maps SIGINT (control-c) to its own handler.  We will remap it
   // to the default so that control-c works.
@@ -132,8 +154,6 @@ void ctkAbstractPythonManager::initPythonQt()
     initCode << QString("sys.path.append('%1')").arg(QDir::fromNativeSeparators(path));
     }
 
-  initCode << QString("import site");
-
   _mainContext.evalScript(initCode.join("\n"));
 
   this->preInitialization();

+ 10 - 1
Libs/Scripting/Python/Core/ctkAbstractPythonManager.h

@@ -42,6 +42,15 @@ public:
   ctkAbstractPythonManager(QObject* _parent=NULL);
   virtual ~ctkAbstractPythonManager();
 
+  /// Calling this function after mainContext() has been called at least once is a no-op.
+  /// If not overridden calling this function, the default initialization flags are
+  /// PythonQt::IgnoreSiteModule and PythonQt::RedirectStdOut.
+  /// \sa PythonQt::InitFlags
+  void setInitializationFlags(int flags);
+
+  /// \sa setInitializationFlags
+  int initializationFlags()const;
+
   PythonQtObjectPtr mainContext();
   void addObjectToPythonMain(const QString& name, QObject* obj);
   void registerPythonQtDecorator(QObject* decorator);
@@ -108,7 +117,7 @@ protected Q_SLOTS:
 
 protected:
 
-  void initPythonQt();
+  void initPythonQt(int flags);
 
   virtual QStringList     pythonPaths();