aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--PySide/CMakeLists.txt16
-rw-r--r--PySide/QtCore/typesystem_core.xml26
-rw-r--r--PySide/__init__.py1
-rw-r--r--tests/CMakeLists.txt16
-rw-r--r--tests/phonon/basic_playing_test.py60
-rw-r--r--tests/phonon/capabilities_test.py48
-rw-r--r--tests/phonon/tone.oggbin0 -> 4300 bytes
-rw-r--r--tests/qtcore/blocking_signals_test.py107
-rw-r--r--tests/qtcore/child_event_test.py55
-rw-r--r--tests/qtcore/duck_punching_test.py56
-rw-r--r--tests/qtcore/missing_symbols_test.py16
-rwxr-xr-xtests/qtcore/qbitarray_test.py100
-rwxr-xr-xtests/qtcore/qbytearray_buffer_protocol_test.py25
-rwxr-xr-xtests/qtcore/qbytearray_concatenation_operator_test.py52
-rw-r--r--tests/qtcore/qbytearray_operator_test.py61
-rw-r--r--tests/qtcore/qbytearray_test.py43
-rwxr-xr-xtests/qtcore/qcoreapplication_instance_test.py20
-rw-r--r--tests/qtcore/qdatastream_test.py20
-rw-r--r--tests/qtcore/qenum_test.py43
-rw-r--r--tests/qtcore/qevent_test.py24
-rw-r--r--tests/qtcore/qflags_test.py23
-rw-r--r--tests/qtcore/qlocale_test.py26
-rw-r--r--tests/qtcore/qmetaobject_test.py31
-rw-r--r--tests/qtcore/qmodelindex_internalpointer_test.py50
-rw-r--r--tests/qtcore/qobject_children_segfault_test.py29
-rw-r--r--tests/qtcore/qobject_connect_notify_test.py70
-rw-r--r--tests/qtcore/qobject_event_filter_test.py80
-rw-r--r--tests/qtcore/qobject_inherits_test.py43
-rw-r--r--tests/qtcore/qobject_parent_test.py234
-rw-r--r--tests/qtcore/qobject_property_test.py54
-rw-r--r--tests/qtcore/qobject_protected_methods_test.py38
-rw-r--r--tests/qtcore/qobject_test.py49
-rw-r--r--tests/qtcore/qobject_timer_event_test.py44
-rw-r--r--tests/qtcore/qobject_tr_as_instance_test.py55
-rw-r--r--tests/qtcore/qrect_test.py102
-rw-r--r--tests/qtcore/qresource_test.py35
-rw-r--r--tests/qtcore/qsize_test.py26
-rw-r--r--tests/qtcore/qslot_object_test.py47
-rw-r--r--tests/qtcore/qsrand_test.py16
-rwxr-xr-xtests/qtcore/qstring_buffer_protocol_test.py25
-rw-r--r--tests/qtcore/qstring_operator_test.py104
-rw-r--r--tests/qtcore/qstring_qkeysequence_test.py18
-rw-r--r--tests/qtcore/qstring_test.py106
-rw-r--r--tests/qtcore/qstringlist_test.py165
-rw-r--r--tests/qtcore/qtext_codec_test.py20
-rw-r--r--tests/qtcore/qthread_prod_cons_test.py107
-rwxr-xr-xtests/qtcore/qthread_signal_test.py64
-rw-r--r--tests/qtcore/qthread_test.py76
-rw-r--r--tests/qtcore/qtimer_singleshot_test.py49
-rw-r--r--tests/qtcore/qtimer_timeout_test.py57
-rw-r--r--tests/qtcore/qtnamespace_test.py19
-rw-r--r--tests/qtcore/quoteEnUS.txt1
-rw-r--r--tests/qtcore/qurl_test.py91
-rw-r--r--tests/qtcore/qvariant_test.py115
-rw-r--r--tests/qtcore/resources.qrc6
-rw-r--r--tests/qtcore/resources_mc.py39
-rw-r--r--tests/qtcore/resources_mc.pycbin0 -> 896 bytes
-rwxr-xr-xtests/qtcore/static_method_test.py18
-rw-r--r--tests/qtcore/static_protected_methods_test.py30
-rw-r--r--tests/qtcore/thread_signals.py39
-rw-r--r--tests/qtcore/translation_test.py48
-rw-r--r--tests/qtcore/translations/trans_latin.ts11
-rw-r--r--tests/qtcore/translations/trans_russian.ts11
-rwxr-xr-xtests/qtcore/unaryoperator_test.py38
-rw-r--r--tests/qtcore/unicode_test.py33
-rw-r--r--tests/qtgui/float_to_int_implicit_conversion_test.py32
-rw-r--r--tests/qtgui/grandparent_method_test.py23
-rw-r--r--tests/qtgui/missing_symbols_test.py29
-rw-r--r--tests/qtgui/paint_event_test.py71
-rw-r--r--tests/qtgui/parent_method_test.py25
-rwxr-xr-xtests/qtgui/parent_policy_test.py37
-rw-r--r--tests/qtgui/python_properties_test.py19
-rw-r--r--tests/qtgui/qapp_test.py17
-rw-r--r--tests/qtgui/qapplication_exit_segfault_test.py17
-rw-r--r--tests/qtgui/qapplication_singleton_test.py12
-rw-r--r--tests/qtgui/qbrush_test.py24
-rw-r--r--tests/qtgui/qdatastream_gui_operators_test.py19
-rw-r--r--tests/qtgui/qgraphicsitem_test.py35
-rw-r--r--tests/qtgui/qgraphicsscene_test.py152
-rw-r--r--tests/qtgui/qlabel_pixmap_refcount.py46
-rw-r--r--tests/qtgui/qlayout_ref_test.py96
-rw-r--r--tests/qtgui/qlayout_test.py52
-rw-r--r--tests/qtgui/qlcdnumber_test.py16
-rw-r--r--tests/qtgui/qlistwidgetitem_test.py25
-rw-r--r--tests/qtgui/qmainwindow_test.py32
-rw-r--r--tests/qtgui/qmenu_test.py58
-rw-r--r--tests/qtgui/qpainter_test.py31
-rw-r--r--tests/qtgui/qpixmap_test.py16
-rw-r--r--tests/qtgui/qpushbutton_test.py30
-rw-r--r--tests/qtgui/qregion_test.py21
-rw-r--r--tests/qtgui/qshortcut_test.py41
-rw-r--r--tests/qtgui/qstandarditemmodel_test.py26
-rw-r--r--tests/qtgui/qstyle_test.py14
-rw-r--r--tests/qtgui/qtabwidget_test.py21
-rw-r--r--tests/qtgui/qtoolbar_test.py35
-rw-r--r--tests/qtgui/qtoolbox_test.py31
-rw-r--r--tests/qtgui/qvariant_test.py39
-rw-r--r--tests/qtgui/qwidget_setlayout_test.py33
-rw-r--r--tests/qtgui/qwidget_test.py18
-rw-r--r--tests/qtgui/reference_count_test.py71
-rw-r--r--tests/qtgui/timed_app_test.py14
-rw-r--r--tests/qtgui/virtual_protected_inheritance_test.py70
-rw-r--r--tests/qtgui/virtual_pure_override.py48
-rw-r--r--tests/qtgui/x11_symbols.py17
-rw-r--r--tests/qthelp/test_help.py14
-rw-r--r--tests/qtnetwork/http_test.py48
-rw-r--r--tests/qtnetwork/tcpserver_test.py25
-rw-r--r--tests/qtnetwork/udpsocket_test.py54
-rw-r--r--tests/qtscript/test_base.py4
-rwxr-xr-xtests/qtsql/qsqldatabaseandqueries_test.py56
-rw-r--r--tests/qtuitools/test_ui.py14
-rw-r--r--tests/qtwebkit/fox.html6
-rw-r--r--tests/qtwebkit/webpage_test.py54
-rw-r--r--tests/qtwebkit/webview_test.py48
-rwxr-xr-xtests/run_test.sh13
-rw-r--r--tests/signals/args_dont_match.py21
-rw-r--r--tests/signals/invalid_callback_test.py29
-rw-r--r--tests/signals/lambda_test.py53
-rw-r--r--tests/signals/multiple_connections_test.py65
-rw-r--r--tests/signals/pysignal_test.py105
-rw-r--r--tests/signals/qobject_destroyed_test.py23
-rw-r--r--tests/signals/qobject_receivers_test.py48
-rwxr-xr-xtests/signals/qobject_sender_test.py91
-rw-r--r--tests/signals/segfault_proxyparent_test.py73
-rw-r--r--tests/signals/short_circuit_test.py66
-rw-r--r--tests/signals/signal2signal_connect_test.py107
-rw-r--r--tests/signals/signal_connectiontype_support.py28
-rw-r--r--tests/signals/signal_emission_test.py123
-rw-r--r--tests/signals/signal_func_test.py21
-rw-r--r--tests/signals/signal_manager_refcount_test.py23
-rw-r--r--tests/signals/signal_with_primitive_type_test.py29
-rw-r--r--tests/signals/slot_reference_count_test.py54
-rw-r--r--tests/signals/upstream_segfault_test.py64
-rw-r--r--tests/util/color.py12
-rw-r--r--tests/util/helper.py120
-rw-r--r--tests/util/helper.pycbin0 -> 5131 bytes
-rw-r--r--tests/util/module_wrapper/PySide/QtAssistant.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtCore.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtDesigner.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtGui.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtHelp.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtNetwork.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtScript.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtSql.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtSvg.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtTest.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtWebKit.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtXml.py2
-rw-r--r--tests/util/module_wrapper/PySide/QtXmlPatterns.py2
-rw-r--r--tests/util/module_wrapper/PySide/__init__.py0
-rw-r--r--tests/util/module_wrapper/PySide/phonon.py2
-rwxr-xr-xtests/util/processtimer.py49
-rw-r--r--tests/util/pyqt_diff.py35
-rwxr-xr-xtests/util/pyqtcheck.py46
-rwxr-xr-xtests/util/rename_imports.sh13
-rw-r--r--tests/util/test_processtimer.py66
-rw-r--r--tests/util/use_pyqt4.sh3
-rw-r--r--tests/util/use_pyside.sh3
-rw-r--r--tests/util/valgrind-python.supp349
160 files changed, 6616 insertions, 12 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 34019a311..9ea45937e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,3 +63,4 @@ enable_testing()
# project directories
add_subdirectory(${BINDING_NAME})
+add_subdirectory(tests)
diff --git a/PySide/CMakeLists.txt b/PySide/CMakeLists.txt
index aa4b114d6..75ca0fac0 100644
--- a/PySide/CMakeLists.txt
+++ b/PySide/CMakeLists.txt
@@ -12,4 +12,18 @@ COMMENT "Running generator for ${module}..."
)
endmacro(execute_generator)
-add_subdirectory(QtCore)
+# Only add subdirectory if the associated Qt module is found.
+macro(HAS_QT_MODULE var name)
+IF (${var})
+ add_subdirectory(${name})
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_BINARY_DIR}/${name}/${name}.so"
+ "${CMAKE_BINARY_DIR}/PySide/${name}.so")
+else (${var})
+ message(STATUS "${name} NOT found. ${name} support disabled.")
+endif (${var})
+endmacro(HAS_QT_MODULE)
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_SOURCE_DIR}/__init__.py"
+ "${CMAKE_BINARY_DIR}/PySide/__init__.py")
+
+HAS_QT_MODULE(QT_QTCORE_FOUND QtCore)
diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml
index 2c0533ad9..2b3bb89ed 100644
--- a/PySide/QtCore/typesystem_core.xml
+++ b/PySide/QtCore/typesystem_core.xml
@@ -3,7 +3,10 @@
<!-- Rejections due to shiboken bugs -->
<rejection class="QString" function-name="replace"/> <!-- A bug in overload method decisor -->
- <!-- A bug when we have global functions with just one parameter -->
+ <!--
+ Stream manipulators does not fits into python language,
+ so we need to do a lot of inject code to handle them.
+ -->
<rejection class="" function-name="bin" />
<rejection class="" function-name="bom" />
<rejection class="" function-name="center" />
@@ -21,12 +24,6 @@
<rejection class="" function-name="noforcesign" />
<rejection class="" function-name="noshowbase" />
<rejection class="" function-name="oct" />
- <rejection class="" function-name="qAddPostRoutine" />
- <rejection class="" function-name="qCompress" />
- <rejection class="" function-name="qInf" />
- <rejection class="" function-name="qUncompress" />
- <rejection class="" function-name="qRemovePostRoutine" />
- <rejection class="" function-name="qSetRealNumberPrecision" />
<rejection class="" function-name="reset" />
<rejection class="" function-name="right" />
<rejection class="" function-name="scientific" />
@@ -34,10 +31,17 @@
<rejection class="" function-name="uppercasebase" />
<rejection class="" function-name="uppercasedigits" />
<rejection class="" function-name="ws" />
- <rejection class="" function-name="" />
- <rejection class="" function-name="" />
- <rejection class="" function-name="" />
- <!-- End of rejections due to shiboken bugs -->
+ <!-- End of rejections -->
+ <rejection class="" function-name="qAddPostRoutine" />
+ <rejection class="" function-name="qRemovePostRoutine" />
+ <!-- Removed because it have uchar* in their arguments-->
+ <rejection class="" function-name="qCompress" />
+ <!-- Removed because it's nto part of the public API, I guess -->
+ <rejection class="" function-name="qInf" />
+ <!-- Same as qCompress -->
+ <rejection class="" function-name="qUncompress" />
+ <!-- We do not export QStreamManipulator, so use QTextStream.setRealNumberPrecision instead of this -->
+ <rejection class="" function-name="qSetRealNumberPrecision" />
<rejection class="QFutureSynchronizer"/>
diff --git a/PySide/__init__.py b/PySide/__init__.py
new file mode 100644
index 000000000..80970b9e5
--- /dev/null
+++ b/PySide/__init__.py
@@ -0,0 +1 @@
+__all__ = ['QtCore']
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 000000000..915c1664d
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,16 @@
+
+file(GLOB TEST_FILES */*_test.py)
+
+foreach(test_file ${TEST_FILES})
+ string(REGEX MATCH "/([^/]+)//?([^/]+)_test.py" test_name ${test_file} )
+ add_test(${CMAKE_MATCH_1}_${CMAKE_MATCH_2} sh
+ ${CMAKE_CURRENT_SOURCE_DIR}/run_test.sh
+ "${pysidebase_BINARY_DIR}"
+ "${CMAKE_BINARY_DIR}:${CMAKE_CURRENT_SOURCE_DIR}/util"
+ ${PYTHON_EXECUTABLE}
+ ${test_file})
+ set_tests_properties(${CMAKE_MATCH_1}_${CMAKE_MATCH_2} PROPERTIES TIMEOUT 5)
+# Should set python path here
+# Looks like it's fixed in 2.8:
+# http://www.vtk.org/Bug/print_bug_page.php?bug_id=7885
+endforeach(test_file ${TEST_FILES})
diff --git a/tests/phonon/basic_playing_test.py b/tests/phonon/basic_playing_test.py
new file mode 100644
index 000000000..100a036c0
--- /dev/null
+++ b/tests/phonon/basic_playing_test.py
@@ -0,0 +1,60 @@
+
+import os
+import unittest
+
+from PySide import QtCore
+from PySide import phonon
+
+from helper import UsesQCoreApplication
+
+# XXX Hack to get the correct filename
+example_file = os.path.join(os.path.dirname(__file__),'tone.ogg')
+
+class TestSimplePlaying(UsesQCoreApplication):
+ def setUp(self):
+ super(TestSimplePlaying, self).setUp()
+ self.app.setApplicationName('Dummy')
+ self.source = phonon.Phonon.MediaSource(example_file)
+ self.media = phonon.Phonon.MediaObject()
+ self.media.setCurrentSource(self.source)
+
+ QtCore.QObject.connect(self.media,
+ QtCore.SIGNAL('finished()'),
+ self.app,
+ QtCore.SLOT('quit()'))
+
+ self.called = False
+
+ def tearDown(self):
+ super(TestSimplePlaying, self).tearDown()
+
+ def testFinishedSignal(self):
+ # Should pass if finished() is called
+ self.media.play()
+ self.app.exec_()
+
+ def testMediaSource(self):
+ self.assertEqual(self.media.currentSource(), self.source)
+
+ def testPathCreation(self):
+ output = phonon.Phonon.AudioOutput()
+ path = phonon.Phonon.createPath(self.media, output)
+
+ # FIXME Both functions below are not exported by PyQt4
+ self.assertEqual(path.sink(), output)
+ self.assertEqual(path.source(), self.media)
+
+ def state_cb(self, newState, OldState):
+ self.called = True
+
+ def testStateChanged(self):
+ QtCore.QObject.connect(self.media,
+ QtCore.SIGNAL('stateChanged(Phonon::State, Phonon::State)'),
+ self.state_cb)
+
+ self.media.play()
+ self.app.exec_()
+ self.assert_(self.called)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/phonon/capabilities_test.py b/tests/phonon/capabilities_test.py
new file mode 100644
index 000000000..5f4b7da83
--- /dev/null
+++ b/tests/phonon/capabilities_test.py
@@ -0,0 +1,48 @@
+
+import unittest
+
+from PySide.QtCore import QString
+from PySide import phonon
+
+from helper import UsesQCoreApplication
+
+class CapabilitiesTest(UsesQCoreApplication):
+ def setUp(self):
+ super(CapabilitiesTest, self).setUp()
+ self.app.setApplicationName("Dummy")
+
+ def tearDown(self):
+ super(CapabilitiesTest, self).tearDown()
+
+
+ def testExists(self):
+ self.assert_(phonon.Phonon.BackendCapabilities)
+
+ def testNotifierIdentity(self):
+ # Notifier is a singleton
+ self.assertEqual(phonon.Phonon.BackendCapabilities.notifier(),
+ phonon.Phonon.BackendCapabilities.notifier())
+
+ self.assert_(phonon.Phonon.BackendCapabilities.notifier() is
+ phonon.Phonon.BackendCapabilities.notifier())
+
+ def testDevices(self):
+ # TODO Improve this test
+ devices = phonon.Phonon.BackendCapabilities.availableAudioOutputDevices()
+ for device in devices:
+ self.assert_(isinstance(device, phonon.Phonon.AudioOutputDevice))
+
+ def testMimeTypes(self):
+ # TODO Improve this test
+ mimeTypes = phonon.Phonon.BackendCapabilities.availableMimeTypes()
+ for mime in mimeTypes:
+ self.assert_(isinstance(mime, QString))
+
+ def testAudioEffects(self):
+ # TODO Improve this test
+ effects = phonon.Phonon.BackendCapabilities.availableAudioEffects()
+ for effect in effects:
+ self.assert_(isinstance(effect, phonon.Phonon.EffectDescription))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/phonon/tone.ogg b/tests/phonon/tone.ogg
new file mode 100644
index 000000000..dc1a455d3
--- /dev/null
+++ b/tests/phonon/tone.ogg
Binary files differ
diff --git a/tests/qtcore/blocking_signals_test.py b/tests/qtcore/blocking_signals_test.py
new file mode 100644
index 000000000..96582f6cc
--- /dev/null
+++ b/tests/qtcore/blocking_signals_test.py
@@ -0,0 +1,107 @@
+
+''' Test case for QObject.signalsBlocked() and blockSignal()'''
+
+import unittest
+import os
+from tempfile import mkstemp
+
+from PySide.QtCore import QObject, SIGNAL, QFile
+
+class TestSignalsBlockedBasic(unittest.TestCase):
+ '''Basic test case for signalsBlocked'''
+
+ def testBasic(self):
+ '''QObject.signalsBlocked() and blockSignals()
+ The signals aren't blocked by default.
+ blockSignals returns the previous value'''
+ obj = QObject()
+ self.assert_(not obj.signalsBlocked())
+ self.assert_(not obj.blockSignals(True))
+ self.assert_(obj.signalsBlocked())
+ self.assert_(obj.blockSignals(False))
+
+class TestSignalsBlocked(unittest.TestCase):
+ '''Test case to check if the signals are really blocked'''
+
+ def setUp(self):
+ #Set up the basic resources needed
+ self.obj = QObject()
+ self.args = tuple()
+ self.called = False
+
+ def tearDown(self):
+ #Delete used resources
+ del self.obj
+ del self.args
+
+ def callback(self, *args):
+ #Default callback
+ if args == self.args:
+ self.called = True
+ else:
+ raise TypeError("Invalid arguments")
+
+ def testShortCircuitSignals(self):
+ #Blocking of Python short-circuit signals
+ QObject.connect(self.obj, SIGNAL('mysignal'), self.callback)
+
+ self.obj.emit(SIGNAL('mysignal'))
+ self.assert_(self.called)
+
+ self.called = False
+ self.obj.blockSignals(True)
+ self.obj.emit(SIGNAL('mysignal'))
+ self.assert_(not self.called)
+
+ def testPythonSignals(self):
+ #Blocking of Python typed signals
+ QObject.connect(self.obj, SIGNAL('mysignal(int,int)'), self.callback)
+ self.args = (1, 3)
+
+ self.obj.emit(SIGNAL('mysignal(int,int)'), *self.args)
+ self.assert_(self.called)
+
+ self.called = False
+ self.obj.blockSignals(True)
+ self.obj.emit(SIGNAL('mysignal(int,int)'), *self.args)
+ self.assert_(not self.called)
+
+class TestQFileSignalBlocking(unittest.TestCase):
+ '''Test case for blocking the signal QIODevice.aboutToClose()'''
+
+ def setUp(self):
+ #Set up the needed resources - A temp file and a QFile
+ self.called = False
+ handle, self.filename = mkstemp()
+ os.close(handle)
+
+ self.qfile = QFile(self.filename)
+
+ def tearDown(self):
+ #Release acquired resources
+ os.remove(self.filename)
+ del self.qfile
+
+ def callback(self):
+ #Default callback
+ self.called = True
+
+ def testAboutToCloseBlocking(self):
+ #QIODevice.aboutToClose() blocking
+
+ QObject.connect(self.qfile, SIGNAL('aboutToClose()'), self.callback)
+
+ self.assert_(self.qfile.open(QFile.ReadOnly))
+ self.qfile.close()
+ self.assert_(self.called)
+
+ self.called = False
+ self.qfile.blockSignals(True)
+
+ self.assert_(self.qfile.open(QFile.ReadOnly))
+ self.qfile.close()
+ self.assert_(not self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/child_event_test.py b/tests/qtcore/child_event_test.py
new file mode 100644
index 000000000..ccc27c848
--- /dev/null
+++ b/tests/qtcore/child_event_test.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+'''Test case for QObject.childEvent and QTimer.childEvent overloading'''
+
+import unittest
+from time import sleep
+from PySide.QtCore import QObject, QTimer, QCoreApplication
+
+from helper import UsesQCoreApplication
+
+class ExtQObject(QObject):
+ def __init__(self):
+ QObject.__init__(self)
+ self.child_event_received = False
+
+ def childEvent(self, event):
+ QObject.childEvent(self, event)
+ self.child_event_received = True
+
+class ExtQTimer(QTimer):
+ def __init__(self):
+ QTimer.__init__(self)
+ self.child_event_received = False
+
+ def childEvent(self, event):
+ QTimer.childEvent(self, event)
+ self.child_event_received = True
+
+
+class TestChildEvent(UsesQCoreApplication):
+ '''Test case for QObject::childEvent and QTimer::childEvent'''
+
+ def setUp(self):
+ UsesQCoreApplication.setUp(self)
+
+ def tearDown(self):
+ UsesQCoreApplication.tearDown(self)
+
+ def testQObject(self):
+ parent = ExtQObject()
+ child = QObject()
+ child.setParent(parent)
+ print "parent seted"
+ #self.assert_(parent.child_event_received)
+
+ """
+ def testQTimer(self):
+ parent = ExtQTimer()
+ child = QObject()
+ child.setParent(parent)
+ self.assert_(parent.child_event_received)
+ """
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/duck_punching_test.py b/tests/qtcore/duck_punching_test.py
new file mode 100644
index 000000000..ddcf91d7b
--- /dev/null
+++ b/tests/qtcore/duck_punching_test.py
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+
+'''Test case for duck puching new implementations of C++ virtual methods into object instances.'''
+
+import unittest
+import new
+from PySide.QtCore import QObject
+from helper import UsesQCoreApplication
+
+class Duck(QObject):
+ def __init__(self):
+ QObject.__init__(self)
+ def childEvent(self, event):
+ QObject.childEvent(self, event)
+
+class TestDuckPunchingOnQObjectInstance(UsesQCoreApplication):
+ '''Test case for duck puching new implementations of C++ virtual methods into object instances.'''
+
+ def setUp(self):
+ #Acquire resources
+ self.duck_childEvent_called = False
+ UsesQCoreApplication.setUp(self)
+
+ def tearDown(self):
+ #Release resources
+ del self.duck_childEvent_called
+ UsesQCoreApplication.tearDown(self)
+
+
+ def testChildEventMonkeyPatch(self):
+ #Test if the new childEvent injected on QObject instance is called from C++
+ parent = QObject()
+ def childEvent(obj, event):
+ self.duck_childEvent_called = True
+ QObject.childEvent(obj, event)
+ parent.event = new.instancemethod(childEvent, parent, QObject)
+ child = QObject()
+ child.setParent(parent)
+ self.assert_(self.duck_childEvent_called)
+
+ def testChildEventMonkeyPatchWithInheritance(self):
+ #Test if the new childEvent injected on a QObject's extension class instance is called from C++
+ parent = Duck()
+ def childEvent(obj, event):
+ QObject.childEvent(obj, event)
+ self.duck_childEvent_called = True
+ child = QObject()
+ child.setParent(parent)
+ parent.event = new.instancemethod(childEvent, parent, QObject)
+ child = QObject()
+ child.setParent(parent)
+ self.assert_(self.duck_childEvent_called)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/missing_symbols_test.py b/tests/qtcore/missing_symbols_test.py
new file mode 100644
index 000000000..f535c53d3
--- /dev/null
+++ b/tests/qtcore/missing_symbols_test.py
@@ -0,0 +1,16 @@
+
+'''(Very) Simple test case for missing names from QtCore'''
+
+import unittest
+from PySide import QtCore
+
+class MissingClasses(unittest.TestCase):
+
+ def testQSettings(self): # Bug 232
+ getattr(QtCore, 'QSettings')
+
+ def testQtTrNoop(self): # Bug 220
+ getattr(QtCore, 'QT_TR_NOOP')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qbitarray_test.py b/tests/qtcore/qbitarray_test.py
new file mode 100755
index 000000000..d68b4756d
--- /dev/null
+++ b/tests/qtcore/qbitarray_test.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+'''Tests if QBitArray class is iterable and also '~' (__invert__) and bitwise operators'''
+
+import unittest
+
+from PySide.QtCore import QBitArray
+
+def bool_list_from_qbitarray(qbitarray):
+ '''This function is used instead of a list comprehension because
+ the QBitArray is being tested also to check if it is providing
+ the iterable protocol.
+ '''
+ qbitarray_values = []
+ for i in range(qbitarray.size()):
+ qbitarray_values.append(qbitarray.at(i))
+ return qbitarray_values
+
+class QBitArrayIsIterableTest(unittest.TestCase):
+ '''Tests if QBitArray class is iterable and also '~' (__invert__) and bitwise operators'''
+
+ def setUp(self):
+ #Acquire resources
+ self.qbitarray = QBitArray(3)
+ self.qbitarray_values = [True, False, False]
+ # WARNING: do not pythonify the following loop
+ for i in range(len(self.qbitarray_values)):
+ self.qbitarray.setBit(i, self.qbitarray_values[i])
+
+ self.inverted_qbitarray_values = [not bit for bit in self.qbitarray_values]
+
+ self.other_qbitarray = QBitArray(3)
+ self.other_qbitarray_values = [True, True, False]
+ # WARNING: do not pythonify the following loop
+ for i in range(len(self.other_qbitarray_values)):
+ self.other_qbitarray.setBit(i, self.other_qbitarray_values[i])
+
+ def tearDown(self):
+ #Release resources
+ del self.qbitarray
+ del self.other_qbitarray
+ del self.qbitarray_values
+ del self.other_qbitarray_values
+ del self.inverted_qbitarray_values
+
+ def testQBitArrayIsIterable(self):
+ #Tests if QBitArray class is iterable
+ qbitarray_is_iterable = True
+ try:
+ bitarray = [bit for bit in self.qbitarray]
+ except:
+ qbitarray_is_iterable = False
+ self.assertTrue(qbitarray_is_iterable)
+
+ def testQBitArrayInvertOperator(self):
+ #Tests QBitArray '~' (__invert__) operator
+ inverted_qbitarray = ~self.qbitarray
+ # WARNING: do not pythonify the following loop, the
+ # iterability of QBitArray class is tested in another place
+ inverted_qbitarray_values = bool_list_from_qbitarray(inverted_qbitarray)
+ self.assertEqual(self.inverted_qbitarray_values, inverted_qbitarray_values)
+
+ def testQBitArrayOrBitwiseOperator(self):
+ #Tests QBitArray '|' (or) operator
+ has_or_bitwise_operator = True
+ ored_qbitarray, ored_bool_list = None, None
+ try:
+ ored_qbitarray = self.qbitarray | self.other_qbitarray
+ ored_bool_list = [b1 | b2 for b1, b2 in zip(self.qbitarray_values, self.other_qbitarray_values)]
+ except:
+ has_or_bitwise_operator = False
+ self.assertTrue(has_or_bitwise_operator)
+ self.assertEqual(bool_list_from_qbitarray(ored_qbitarray), ored_bool_list)
+
+ def testQBitArrayAndBitwiseOperator(self):
+ #Tests QBitArray '&' (and) operator
+ has_and_bitwise_operator = True
+ anded_qbitarray, anded_bool_list = None, None
+ try:
+ anded_qbitarray = self.qbitarray | self.other_qbitarray
+ anded_bool_list = [b1 | b2 for b1, b2 in zip(self.qbitarray_values, self.other_qbitarray_values)]
+ except:
+ has_and_bitwise_operator = False
+ self.assertTrue(has_and_bitwise_operator)
+ self.assertEqual(bool_list_from_qbitarray(anded_qbitarray), anded_bool_list)
+
+ def testQBitArrayXorBitwiseOperator(self):
+ #Tests QBitArray '^' (xor) operator
+ has_xor_bitwise_operator = True
+ xored_qbitarray, xored_bool_list = None, None
+ try:
+ xored_qbitarray = self.qbitarray | self.other_qbitarray
+ xored_bool_list = [b1 | b2 for b1, b2 in zip(self.qbitarray_values, self.other_qbitarray_values)]
+ except:
+ has_xor_bitwise_operator = False
+ self.assertTrue(has_xor_bitwise_operator)
+ self.assertEqual(bool_list_from_qbitarray(xored_qbitarray), xored_bool_list)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qbytearray_buffer_protocol_test.py b/tests/qtcore/qbytearray_buffer_protocol_test.py
new file mode 100755
index 000000000..6e81f1e03
--- /dev/null
+++ b/tests/qtcore/qbytearray_buffer_protocol_test.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Tests QByteArray implementation of Python buffer protocol'''
+
+import unittest
+
+from os.path import isdir
+from PySide.QtCore import QByteArray
+
+class QByteArrayBufferProtocolTest(unittest.TestCase):
+ '''Tests QByteArray implementation of Python buffer protocol'''
+
+ def testQByteArrayBufferProtocol(self):
+ #Tests QByteArray implementation of Python buffer protocol using the os.path.isdir
+ #function which an unicode object or other object implementing the Python buffer protocol
+ os_path_isdir_function_correctly_called_with_a_qbytearray = True
+ try:
+ isdir(QByteArray('/tmp'))
+ except:
+ os_path_isdir_function_correctly_called_with_a_qbytearray = False
+ self.assertTrue(os_path_isdir_function_correctly_called_with_a_qbytearray)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qbytearray_concatenation_operator_test.py b/tests/qtcore/qbytearray_concatenation_operator_test.py
new file mode 100755
index 000000000..201c8173c
--- /dev/null
+++ b/tests/qtcore/qbytearray_concatenation_operator_test.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QByteArray concatenation with '+' operator'''
+
+import unittest
+
+from PySide.QtCore import QByteArray
+
+class QByteArrayConcatenationOperatorTest(unittest.TestCase):
+ '''Test cases for QByteArray concatenation with '+' operator'''
+
+ def testConcatQByteArrayAndPythonString(self):
+ #Test concatenation of a QByteArray with a Python string, in this order
+ concat_qbytearray_add_python_string_worked = True
+ qba = QByteArray('foo')
+ result = None
+ try:
+ result = qba + 'bar'
+ except:
+ concat_qbytearray_add_python_string_worked = False
+ self.assertTrue(concat_qbytearray_add_python_string_worked)
+ # NOTICE: the standard behavior of PyQt is to return a QString object
+ # for this case. As this is a minor issue the assertion will be left commented.
+ #self.assertEqual(result.__class__.__name__, 'QString')
+
+ def testConcatPythonStringAndQByteArray(self):
+ #Test concatenation of a Python string with a QByteArray, in this order
+ concat_python_string_add_qbytearray_worked = True
+ qba = QByteArray('foo')
+ result = None
+ try:
+ result = 'bar' + qba
+ except:
+ concat_python_string_add_qbytearray_worked = False
+ self.assertTrue(concat_python_string_add_qbytearray_worked)
+ self.assertEqual(result.__class__.__name__, 'QByteArray')
+
+ def testConcatPythonUnicodeAndQByteArray(self):
+ #Test concatenation of a Python unicode object with a QByteArray, in this order
+ concat_python_unicode_add_qbytearray_worked = True
+ qba = QByteArray('foo')
+ result = None
+ try:
+ result = u'ümlaut' + qba
+ except:
+ concat_python_unicode_add_qbytearray_worked = False
+ self.assertTrue(concat_python_unicode_add_qbytearray_worked)
+ self.assertEqual(result.__class__.__name__, 'unicode')
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qbytearray_operator_test.py b/tests/qtcore/qbytearray_operator_test.py
new file mode 100644
index 000000000..3485026c1
--- /dev/null
+++ b/tests/qtcore/qbytearray_operator_test.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QByteArray operators'''
+
+import unittest
+
+from PySide.QtCore import QByteArray, QString
+
+class QByteArrayOperatorEqual(unittest.TestCase):
+ '''TestCase for operator QByteArray == QByteArray'''
+
+ def testDefault(self):
+ #QByteArray() == QByteArray()
+ obj1 = QByteArray()
+ obj2 = QByteArray()
+ self.assertEqual(obj1, obj2)
+
+ def testSimple(self):
+ #QByteArray(some_string) == QByteArray(some_string)
+ string = 'egg snakes'
+ self.assertEqual(QByteArray(string), QByteArray(string))
+
+ def testPyString(self):
+ #QByteArray(string) == string
+ string = 'my test string'
+ self.assertEqual(QByteArray(string), string)
+
+ def testQString(self):
+ #QByteArray(string) == QString(string)
+ string = 'another test string'
+ self.assertEqual(QByteArray(string), QString(string))
+
+class QByteArrayOperatorAt(unittest.TestCase):
+ '''TestCase for operator QByteArray[]'''
+
+ def testInRange(self):
+ #QByteArray[x] where x is a valid index
+ string = 'abcdefgh'
+ obj = QByteArray(string)
+
+ for i in range(len(string)):
+ self.assertEqual(obj[i], string[i])
+
+ def testInRangeReverse(self):
+ #QByteArray[x] where x is a valid index (reverse order)
+ string = 'abcdefgh'
+ obj = QByteArray(string)
+
+ for i in range(len(string)-1, 0, -1):
+ self.assertEqual(obj[i], string[i])
+
+
+ def testOutOfRange(self):
+ #QByteArray[x] where x is out of index
+ string = '1234567'
+ obj = QByteArray(string)
+ self.assertRaises(IndexError, lambda :obj[len(string)])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qbytearray_test.py b/tests/qtcore/qbytearray_test.py
new file mode 100644
index 000000000..67f99f3d4
--- /dev/null
+++ b/tests/qtcore/qbytearray_test.py
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+'''Unit tests for QByteArray'''
+
+import unittest
+import ctypes
+import sys
+
+from PySide.QtCore import QByteArray
+
+class QByteArrayTestToNumber(unittest.TestCase):
+ def testToNumberInt(self):
+ obj = QByteArray('37')
+ self.assertEqual(37, obj.toInt()[0])
+
+ def testToNumberFloat(self):
+ obj = QByteArray('37.109')
+ self.assertEqual(ctypes.c_float(37.109).value,
+ obj.toFloat()[0])
+
+ def testToNumberDouble(self):
+ obj = QByteArray('37.109')
+ self.assertEqual(ctypes.c_double(37.109).value,
+ obj.toDouble()[0])
+
+class QByteArraySplit(unittest.TestCase):
+ '''Test case for QByteArray.split'''
+
+ def testPathSeparator(self):
+ #QByteArray.split('/')
+ obj = QByteArray(unittest.__file__)
+ self.assertEqual(obj.split('/'), unittest.__file__.split('/'))
+
+class QByteArrayData(unittest.TestCase):
+
+ '''Test case for QByteArray.data'''
+
+ def testData(self):
+ url = QByteArray("http://web.openbossa.org/")
+ self.assertEqual(url.data(), "http://web.openbossa.org/")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qcoreapplication_instance_test.py b/tests/qtcore/qcoreapplication_instance_test.py
new file mode 100755
index 000000000..365148d34
--- /dev/null
+++ b/tests/qtcore/qcoreapplication_instance_test.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QCoreApplication.instance static method'''
+
+import unittest
+
+from PySide.QtCore import QCoreApplication
+
+class QCoreApplicationInstanceTest(unittest.TestCase):
+ '''Test cases for QCoreApplication.instance static method'''
+
+ def testQCoreApplicationInstance(self):
+ #Tests QCoreApplication.instance()
+ self.assertEqual(QCoreApplication.instance(), None)
+ app = QCoreApplication([])
+ self.assertEqual(QCoreApplication.instance(), app)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qdatastream_test.py b/tests/qtcore/qdatastream_test.py
new file mode 100644
index 000000000..d2fcb6d81
--- /dev/null
+++ b/tests/qtcore/qdatastream_test.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+'''Unit tests for QDataStream'''
+
+import unittest
+
+from PySide.QtCore import QDataStream, QBuffer
+
+class QDataStreamTest(unittest.TestCase):
+ '''Test case for QByteArray.split'''
+
+ def testWriteFunction(self):
+ b = QBuffer()
+ b.open(QBuffer.ReadWrite)
+ ds = QDataStream(b)
+ ds.writeUInt8(chr(True))
+ self.assertEqual(b.buffer().at(0), chr(True))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qenum_test.py b/tests/qtcore/qenum_test.py
new file mode 100644
index 000000000..99ede66b2
--- /dev/null
+++ b/tests/qtcore/qenum_test.py
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+'''Test cases for QEnum and QFlags'''
+
+import unittest
+
+from PySide.QtCore import QIODevice, QString, Qt, QVariant
+
+class TestEnum(unittest.TestCase):
+
+ def testToInt(self):
+ self.assertEqual(QIODevice.NotOpen, 0)
+ self.assertEqual(QIODevice.ReadOnly, 1)
+ self.assertEqual(QIODevice.WriteOnly, 2)
+ self.assertEqual(QIODevice.ReadWrite, 1 | 2)
+ self.assertEqual(QIODevice.Append, 4)
+ self.assertEqual(QIODevice.Truncate, 8)
+ self.assertEqual(QIODevice.Text, 16)
+ self.assertEqual(QIODevice.Unbuffered, 32)
+
+ def testToIntInFunction(self):
+ self.assertEqual(QString.number(QIODevice.WriteOnly), "2")
+
+class TestQFlags(unittest.TestCase):
+ def testToItn(self):
+ om = QIODevice.OpenMode(QIODevice.NotOpen)
+
+ self.assertEqual(om, QIODevice.NotOpen)
+ self.assertTrue(om == 0)
+
+ self.assertTrue(om != QIODevice.ReadOnly)
+ self.assertTrue(om != 1)
+
+ def testToIntInFunction(self):
+ om = QIODevice.OpenMode(QIODevice.WriteOnly)
+ self.assertEqual(QString.number(int(om)), "2")
+
+class TestDuplicatedValues(unittest.TestCase):
+ def testQVariant(self):
+ self.assertEqual(QVariant.LastCoreType, QVariant.Hash)
+ self.assertEqual(QVariant.LastGuiType, QVariant.Transform)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qevent_test.py b/tests/qtcore/qevent_test.py
new file mode 100644
index 000000000..07f23f098
--- /dev/null
+++ b/tests/qtcore/qevent_test.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+'''Test cases for QtCore.QEvent'''
+
+import unittest
+
+from PySide.QtCore import QEvent
+
+class QEventTypeFlag(unittest.TestCase):
+ '''Test case for usage of QEvent.Type flags'''
+
+ def testFlagAccess(self):
+ #QEvent.Type flags usage
+
+ event = QEvent(QEvent.Timer)
+ self.assertEqual(event.type(), QEvent.Timer)
+
+ event = QEvent(QEvent.Close)
+ self.assertEqual(event.type(), QEvent.Close)
+
+ event = QEvent(QEvent.IconTextChange)
+ self.assertEqual(event.type(), QEvent.IconTextChange)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qflags_test.py b/tests/qtcore/qflags_test.py
new file mode 100644
index 000000000..6290926d7
--- /dev/null
+++ b/tests/qtcore/qflags_test.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+'''Test cases for QFlags'''
+
+import unittest
+from PySide.QtCore import *
+
+class QFLagTest(unittest.TestCase):
+ '''Test case for usage of flags'''
+
+ def testCallFunction(self):
+ f = QFile("/tmp/t0");
+ self.assertEqual(f.open(QIODevice.Truncate | QIODevice.Text | QIODevice.ReadWrite), True)
+ om = f.openMode()
+ self.assertEqual(om & QIODevice.Truncate, QIODevice.Truncate)
+ self.assertEqual(om & QIODevice.Text, QIODevice.Text)
+ self.assertEqual(om & QIODevice.ReadWrite, QIODevice.ReadWrite)
+ self.assert_(om == QIODevice.Truncate | QIODevice.Text | QIODevice.ReadWrite)
+ print (om != QIODevice.ReadOnly)
+ f.close()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qlocale_test.py b/tests/qtcore/qlocale_test.py
new file mode 100644
index 000000000..e2fd49d19
--- /dev/null
+++ b/tests/qtcore/qlocale_test.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+'''Unit tests for QLocale'''
+
+import unittest
+import ctypes
+import sys
+
+from PySide.QtCore import QLocale
+
+class QLocaleTestToNumber(unittest.TestCase):
+ def testToNumberInt(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual(37, obj.toInt('37')[0])
+
+ def testToNumberFloat(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual(ctypes.c_float(37.109).value,
+ obj.toFloat('37.109')[0])
+
+ def testToNumberDouble(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual(ctypes.c_double(37.109).value,
+ obj.toDouble('37.109')[0])
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qmetaobject_test.py b/tests/qtcore/qmetaobject_test.py
new file mode 100644
index 000000000..457db087c
--- /dev/null
+++ b/tests/qtcore/qmetaobject_test.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Tests for static methos conflicts with class methods'''
+
+import unittest
+
+from PySide.QtCore import *
+
+class Foo(QFile):
+ pass
+
+class qmetaobject_test(unittest.TestCase):
+ def test_QMetaObject(self):
+ qobj = QObject()
+ qobj_metaobj = qobj.metaObject()
+ self.assertEqual(qobj_metaobj.className(), "QObject")
+
+ obj = QFile()
+ m = obj.metaObject()
+ self.assertEqual(m.className(), "QFile")
+ self.assertNotEqual(m.methodCount(), qobj_metaobj.methodCount())
+
+ obj = Foo()
+ m = obj.metaObject()
+ self.assertEqual(m.className(), "Foo")
+ self.assertEqual(m.methodCount(), QFile().metaObject().methodCount())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qmodelindex_internalpointer_test.py b/tests/qtcore/qmodelindex_internalpointer_test.py
new file mode 100644
index 000000000..015d1c926
--- /dev/null
+++ b/tests/qtcore/qmodelindex_internalpointer_test.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+''' Test case for QAbstractListModel.createIndex and QModelIndex.internalPointer'''
+
+import sys
+import unittest
+from PySide.QtCore import *
+
+class MyModel (QAbstractListModel):
+ pass
+
+class TestQModelIndexInternalPointer(unittest.TestCase):
+ ''' Test case for QAbstractListModel.createIndex and QModelIndex.internalPointer'''
+
+ def setUp(self):
+ #Acquire resources
+ self.model = MyModel()
+
+ def tearDown(self):
+ #Release resources
+ del self.model
+
+ def testInternalPointer(self):
+ #Test QAbstractListModel.createIndex and
+ #QModelIndex.internalPointer with regular
+ #Python objects
+ idx = self.model.createIndex(0, 0, "Hello")
+ self.assertEqual("Hello", idx.internalPointer())
+ a = [1, 2, 3]
+ idx = self.model.createIndex(0, 0, a)
+ self.assertEqual(a, idx.internalPointer())
+
+ def testReferenceCounting(self):
+ #Test reference counting when retrieving data with
+ #QModelIndex.internalPointer
+ a = [1, 2, 3]
+ a_refcnt = sys.getrefcount(a)
+ idx = self.model.createIndex(0, 0, a)
+ ptr = idx.internalPointer()
+ self.assertEqual(sys.getrefcount(a), a_refcnt + 1)
+
+ def testIndexForDefaultDataArg(self):
+ #Test QAbstractListModel.createIndex with a default
+ #value for data argument
+ idx = self.model.createIndex(0, 0)
+ self.assertEqual(None, idx.internalPointer())
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qobject_children_segfault_test.py b/tests/qtcore/qobject_children_segfault_test.py
new file mode 100644
index 000000000..930a082cf
--- /dev/null
+++ b/tests/qtcore/qobject_children_segfault_test.py
@@ -0,0 +1,29 @@
+
+'''Test cases for parent-child relationship'''
+
+import unittest
+
+from PySide.QtCore import QObject, QCoreApplication
+
+class ChildrenCoreApplication(unittest.TestCase):
+ '''Test case for calling QObject.children after creating a QCoreApp'''
+
+ def testQCoreAppChildren(self):
+ #QObject.children() after creating a QCoreApplication
+ # Minimal test:
+ # 1- Create QCoreApp
+ # 2- Create parent and childrens
+ # 3- While keeping the children alive, call parent.children()
+ # 4- Delete parent
+ app = QCoreApplication([])
+ parent = QObject()
+ children = [QObject(parent) for x in range(25)]
+ # Uncomment the lines below to make the test pass
+ # del children
+ # del child2
+ del parent # XXX Segfaults here
+ self.assert_(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_connect_notify_test.py b/tests/qtcore/qobject_connect_notify_test.py
new file mode 100644
index 000000000..441037585
--- /dev/null
+++ b/tests/qtcore/qobject_connect_notify_test.py
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+
+''' Test case for QObject::connectNotify()'''
+
+import unittest
+from PySide.QtCore import *
+from helper import UsesQCoreApplication
+
+def cute_slot():
+ pass
+
+class Obj(QObject):
+ def __init__(self):
+ QObject.__init__(self)
+ self.con_notified = False
+ self.dis_notified = False
+
+ def connectNotify(self, signal):
+ self.con_notified = True
+
+ def disconnectNotify(self, signal):
+ self.dis_notified = True
+
+ def reset(self):
+ self.con_notified = False
+ self.dis_notified = False
+
+class TestQObjectConnectNotify(UsesQCoreApplication):
+ '''Test case for QObject::connectNotify'''
+ def setUp(self):
+ UsesQCoreApplication.setUp(self)
+ self.called = False
+
+ def tearDown(self):
+ UsesQCoreApplication.tearDown(self)
+
+ def testBasic(self):
+ sender = Obj()
+ receiver = QObject()
+ sender.connect(SIGNAL("destroyed()"), receiver, SLOT("deleteLater()"))
+ self.assert_(sender.con_notified)
+ sender.disconnect(SIGNAL("destroyed()"), receiver, SLOT("deleteLater()"))
+ self.assert_(sender.dis_notified)
+
+ def testPySignal(self):
+ sender = Obj()
+ receiver = QObject()
+ sender.connect(SIGNAL("foo()"), receiver, SLOT("deleteLater()"))
+ self.assert_(sender.con_notified)
+ sender.disconnect(SIGNAL("foo()"), receiver, SLOT("deleteLater()"))
+ self.assert_(sender.dis_notified)
+
+ def testPySlots(self):
+ sender = Obj()
+ receiver = QObject()
+ sender.connect(SIGNAL("destroyed()"), cute_slot)
+ self.assert_(sender.con_notified)
+ sender.disconnect(SIGNAL("destroyed()"), cute_slot)
+ self.assert_(sender.dis_notified)
+
+ def testpyAll(self):
+ sender = Obj()
+ receiver = QObject()
+ sender.connect(SIGNAL("foo()"), cute_slot)
+ self.assert_(sender.con_notified)
+ sender.disconnect(SIGNAL("foo()"), cute_slot)
+ self.assert_(sender.dis_notified)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_event_filter_test.py b/tests/qtcore/qobject_event_filter_test.py
new file mode 100644
index 000000000..8018fcda0
--- /dev/null
+++ b/tests/qtcore/qobject_event_filter_test.py
@@ -0,0 +1,80 @@
+
+'''Test cases for QObject.eventFilter'''
+
+import unittest
+
+from PySide.QtCore import QObject, QTimerEvent
+
+from helper import UsesQCoreApplication
+
+class FilterObject(QObject):
+ '''Filter object for the basic test'''
+ def __init__(self, obj=None, event_type=None, *args):
+ #Creates a new filter object
+ QObject.__init__(self, *args)
+ self.obj = obj
+ self.event_type = event_type
+ self.events_handled = 0
+ self.events_bypassed = 0
+
+ def setTargetObject(self, obj):
+ #Sets the object that will be filtered
+ self.obj = obj
+
+ def eventFilter(self, obj, event):
+ '''Just checks if is the correct object and event type
+ incrementing counter until reaching the limit. After that it
+ stops filtering the events for the object.'''
+ if (self.obj == obj):
+ if isinstance(event, self.event_type) and self.events_handled < 5:
+ self.events_handled += 1
+ return True
+ else:
+ self.events_bypassed += 1
+ return False
+ else:
+ return QObject.eventFilter(self, obj, event)
+
+class FilteredObject(QObject):
+ '''Class that will be filtered. Quits the app after 5 timer events'''
+ def __init__(self, app, *args):
+ QObject.__init__(self, *args)
+ self.app = app
+ self.times_called = 0
+
+ def timerEvent(self, evt):
+ #Overriden method
+ self.times_called += 1
+
+ if self.times_called == 5:
+ self.app.quit()
+
+class TestQObjectEventFilterPython(UsesQCoreApplication):
+ '''QObject.eventFilter - Reimplemented in python
+ Filters 5 TimerEvents and then bypasses the other events to the
+ timerEvent method. After 5 runs, the timerEvent method will ask
+ the core application to exit'''
+ def setUp(self):
+ #Acquire resources
+ UsesQCoreApplication.setUp(self)
+ self.obj_filter = FilterObject(event_type=QTimerEvent)
+ def tearDown(self):
+ #Release resources
+ del self.obj_filter
+ UsesQCoreApplication.tearDown(self)
+
+ def testEventFilter(self):
+ #QObject.eventFilter reimplemented in python
+ filtered = FilteredObject(self.app)
+ filtered.installEventFilter(self.obj_filter)
+ self.obj_filter.setTargetObject(filtered)
+
+ filtered.startTimer(0)
+
+ self.app.exec_()
+
+ self.assertEqual(filtered.times_called, 5)
+ self.assertEqual(self.obj_filter.events_handled, 5)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_inherits_test.py b/tests/qtcore/qobject_inherits_test.py
new file mode 100644
index 000000000..9e02b0a46
--- /dev/null
+++ b/tests/qtcore/qobject_inherits_test.py
@@ -0,0 +1,43 @@
+'''Test cases for QObject methods'''
+
+import unittest
+
+from PySide.QtCore import QObject
+
+class InheritsCase(unittest.TestCase):
+ '''Test case for QObject.inherits'''
+
+ def testCppInheritance(self):
+ #QObject.inherits() for c++ classes
+ #An class inherits itself
+ self.assert_(QObject().inherits('QObject'))
+
+ def testPythonInheritance(self):
+ #QObject.inherits() for python classes
+
+ class Dummy(QObject):
+ #Dummy class
+ pass
+
+ self.assert_(Dummy().inherits('QObject'))
+ self.assert_(Dummy().inherits('Dummy'))
+ self.assert_(not Dummy().inherits('FooBar'))
+
+ def testPythonMultiInheritance(self):
+ #QObject.inherits() for multiple inheritance
+ # QObject.inherits(classname) should fail if classname isn't a
+ # QObject subclass
+
+ class Parent(object):
+ #Dummy parent
+ pass
+ class Dummy(QObject, Parent):
+ #Dummy class
+ pass
+
+ self.assert_(Dummy().inherits('QObject'))
+ self.assert_(not Dummy().inherits('Parent'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_parent_test.py b/tests/qtcore/qobject_parent_test.py
new file mode 100644
index 000000000..4699fc60c
--- /dev/null
+++ b/tests/qtcore/qobject_parent_test.py
@@ -0,0 +1,234 @@
+
+'''Test cases for parent-child relationship'''
+
+import unittest
+from sys import getrefcount
+
+from PySide.QtCore import QObject, QTimer
+
+class ParentRefCountCase(unittest.TestCase):
+ '''Test case for the refcount changes of setParent'''
+
+ def setUp(self):
+ #Acquire resources
+ self.parent = QObject()
+ self.child = QObject()
+
+ def tearDown(self):
+ #Release resources
+ del self.child
+ del self.parent
+
+ def testSetParent(self):
+ #QObject.setParent() refcount changes
+ self.assertEqual(getrefcount(self.child), 2)
+ self.child.setParent(self.parent)
+ self.assertEqual(getrefcount(self.child), 3)
+
+ def testConstructor(self):
+ #QObject(QObject) refcount changes
+ child = QObject(self.parent)
+ self.assertEqual(getrefcount(child), 3)
+
+class ParentCase(unittest.TestCase):
+ '''Small collection of tests related to parent-child relationship'''
+
+ def testSetParent(self):
+ #QObject.setParent()
+ parent = QObject()
+ child = QObject()
+ child.setParent(parent)
+
+ self.assertEqual(parent, child.parent())
+
+ def testParentConstructor(self):
+ #QObject(parent)
+ parent = QObject()
+ child = QObject(parent)
+
+ self.assertEqual(parent, child.parent())
+
+ orig_repr = repr(child)
+ del child
+ self.assertEqual(orig_repr, repr(parent.children()[0]))
+
+ def testChildren(self):
+ #QObject.children()
+ parent = QObject()
+ children = [QObject(parent) for x in range(25)]
+
+ self.assertEqual(parent.children(), children)
+
+ def testFindChild(self):
+ #QObject.findChild() with all QObject
+ parent = QObject()
+ name = 'object%d'
+ children = [QObject(parent) for i in range(20)]
+
+ for i, child in enumerate(children):
+ child.setObjectName(name % i)
+
+ for i, child in enumerate(children):
+ self.assertEqual(child, parent.findChild(QObject, name % i))
+
+ def testFindChildren(self):
+ #QObject.findChildren() with all QObject
+ parent = QObject()
+ target_name = 'foo'
+ children = [QTimer(parent) for i in range(20)]
+ children.extend([QObject(parent) for i in range(20)])
+
+ for i, child in enumerate(children):
+ if i % 5 == 0:
+ child.setObjectName(target_name)
+ else:
+ child.setObjectName(str(i))
+
+ # Emulates findChildren with the intended outcome
+ target_children = [x for x in children if x.objectName() == target_name]
+ test_children = parent.findChildren(QObject, target_name)
+
+ self.assertEqual(sorted(target_children), sorted(test_children))
+
+ def testParentEquality(self):
+ #QObject.parent() == parent
+ parent = QObject()
+ child = QObject(parent)
+ self.assertEqual(parent, child.parent())
+
+
+class TestParentOwnership(unittest.TestCase):
+ '''Test case for Parent/Child object ownership'''
+
+ def testParentDestructor(self):
+ parent = QObject()
+ self.assertEqual(getrefcount(parent), 2)
+
+ child = QObject(parent)
+ self.assertEqual(getrefcount(child), 3)
+ self.assertEqual(getrefcount(parent), 2)
+
+ del parent
+ self.assertEqual(getrefcount(child), 2)
+
+ # this will fail because parent deleted child cpp object
+ self.assertRaises(RuntimeError, lambda :child.objectName())
+
+ # test parent with multiples children
+ def testMultipleChildren(self):
+ o = QObject()
+ self.assertEqual(getrefcount(o), 2)
+
+ c = QObject(o)
+ self.assertEqual(getrefcount(c), 3)
+ self.assertEqual(getrefcount(o), 2)
+
+ c2 = QObject(o)
+ self.assertEqual(getrefcount(o), 2)
+ self.assertEqual(getrefcount(c), 3)
+ self.assertEqual(getrefcount(c2), 3)
+
+ del o
+ self.assertEqual(getrefcount(c), 2)
+ self.assertEqual(getrefcount(c2), 2)
+
+ # this will fail because parent deleted child cpp object
+ self.assertRaises(RuntimeError, lambda :c.objectName())
+ self.assertRaises(RuntimeError, lambda :c2.objectName())
+
+ # test recursive parent
+ def testRecursiveParent(self):
+ o = QObject()
+ self.assertEqual(getrefcount(o), 2)
+
+ c = QObject(o)
+ self.assertEqual(getrefcount(c), 3)
+ self.assertEqual(getrefcount(o), 2)
+
+ c2 = QObject(c)
+ self.assertEqual(getrefcount(o), 2)
+ self.assertEqual(getrefcount(c), 3)
+ self.assertEqual(getrefcount(c2), 3)
+
+ del o
+ self.assertEqual(getrefcount(c), 2)
+ self.assertEqual(getrefcount(c2), 2)
+
+ # this will fail because parent deleted child cpp object
+ self.assertRaises(RuntimeError, lambda :c.objectName())
+ self.assertRaises(RuntimeError, lambda :c2.objectName())
+
+ # test parent transfer
+ def testParentTransfer(self):
+ o = QObject()
+ self.assertEqual(getrefcount(o), 2)
+
+ c = QObject()
+ self.assertEqual(getrefcount(c), 2)
+
+ c.setParent(o)
+ self.assertEqual(getrefcount(c), 3)
+
+ c.setParent(None)
+ self.assertEqual(getrefcount(c), 2)
+
+ del c
+ del o
+
+
+class ExtQObject(QObject):
+ def __init__(self):
+ QObject.__init__(self)
+
+class ReparentingTest(unittest.TestCase):
+ '''Test cases for reparenting'''
+
+ def testParentedQObjectIdentity(self):
+ object_list = []
+ parent = QObject()
+ for i in range(3):
+ obj = QObject()
+ object_list.append(obj)
+ obj.setParent(parent)
+ for child in parent.children():
+ self.assert_(child in object_list)
+
+ def testParentedExtQObjectType(self):
+ object_list = []
+ parent = QObject()
+ for i in range(3):
+ obj = ExtQObject()
+ object_list.append(obj)
+ obj.setParent(parent)
+ for orig, child in zip(object_list, parent.children()):
+ self.assertEqual(type(orig), type(child))
+
+ def testReparentedQObjectIdentity(self):
+ object_list = []
+ old_parent = QObject()
+ new_parent = QObject()
+ for i in range(3):
+ obj = QObject()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for child in new_parent.children():
+ self.assert_(child in object_list)
+
+ def testReparentedExtQObjectType(self):
+ object_list = []
+ old_parent = QObject()
+ new_parent = QObject()
+ for i in range(3):
+ obj = ExtQObject()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for orig, child in zip(object_list, new_parent.children()):
+ self.assertEqual(type(orig), type(child))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_property_test.py b/tests/qtcore/qobject_property_test.py
new file mode 100644
index 000000000..ecf101906
--- /dev/null
+++ b/tests/qtcore/qobject_property_test.py
@@ -0,0 +1,54 @@
+
+'''Test cases for QObject property and setProperty'''
+
+import unittest
+
+from PySide.QtCore import QObject, QVariant
+
+class PropertyCase(unittest.TestCase):
+ '''Test case for QObject properties'''
+
+ def testObjectNameProperty(self):
+ #QObject.setProperty() for existing C++ property
+ obj = QObject()
+ self.assert_(obj.setProperty('objectName', QVariant('dummy')))
+ self.assertEqual(obj.objectName(), 'dummy')
+
+ self.assert_(obj.setProperty('objectName', QVariant('foobar')))
+ self.assertEqual(obj.objectName(), 'foobar')
+
+ def testDynamicProperty(self):
+ #QObject.setProperty() for dynamic properties
+ obj = QObject()
+
+ # Should return false when creating a new dynamic property
+ self.assert_(not obj.setProperty('dummy', QVariant('mydata')))
+ prop = obj.property('dummy')
+ self.assert_(isinstance(prop, QVariant))
+ self.assert_(prop.isValid())
+ self.assertEqual(obj.property('dummy').toString(), 'mydata')
+
+ self.assert_(not obj.setProperty('dummy', QVariant('zigzag')))
+ prop = obj.property('dummy')
+ self.assert_(isinstance(prop, QVariant))
+ self.assert_(prop.isValid())
+ self.assertEqual(obj.property('dummy').toString(), 'zigzag')
+
+ self.assert_(not obj.setProperty('dummy', QVariant(42)))
+ prop = obj.property('dummy')
+ self.assert_(isinstance(prop, QVariant))
+ self.assert_(prop.isValid())
+ # QVariant.toInt has a bool* arg in C++, so returns a tuple
+ self.assertEqual(obj.property('dummy').toInt(), (42, True))
+
+
+ def testInvalidProperty(self):
+ #QObject.property() for invalid properties
+ obj = QObject()
+
+ prop = obj.property('dummy')
+ self.assert_(not prop.isValid())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_protected_methods_test.py b/tests/qtcore/qobject_protected_methods_test.py
new file mode 100644
index 000000000..37bda37bc
--- /dev/null
+++ b/tests/qtcore/qobject_protected_methods_test.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+'''Test cases for QObject protected methods'''
+
+import unittest
+
+from PySide.QtCore import QObject, QThread, SIGNAL
+
+class Dummy(QObject):
+ '''Dummy class'''
+ pass
+
+class QObjectReceivers(unittest.TestCase):
+ '''Test case for QObject.receivers()'''
+
+ def cb(self, *args):
+ #Dummy callback
+ pass
+
+ def testQObjectReceiversExtern(self):
+ #QObject.receivers() - Protected method external access
+
+ obj = Dummy()
+ self.assertEqual(obj.receivers(SIGNAL("destroyed()")), 0)
+
+ QObject.connect(obj, SIGNAL("destroyed()"), self.cb)
+ self.assertEqual(obj.receivers(SIGNAL("destroyed()")), 1)
+
+ def testQThreadReceiversExtern(self):
+ #QThread.receivers() - Inherited protected method
+
+ obj = QThread()
+ self.assertEqual(obj.receivers(SIGNAL('destroyed()')), 0)
+ QObject.connect(obj, SIGNAL("destroyed()"), self.cb)
+ self.assertEqual(obj.receivers(SIGNAL("destroyed()")), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_test.py b/tests/qtcore/qobject_test.py
new file mode 100644
index 000000000..848cce361
--- /dev/null
+++ b/tests/qtcore/qobject_test.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QObject methods'''
+
+import unittest
+
+from PySide.QtCore import QObject
+
+class ObjectNameCase(unittest.TestCase):
+ '''Tests related to QObject object name'''
+
+ def testSimple(self):
+ #QObject.objectName(string)
+ name = 'object1'
+ obj = QObject()
+ obj.setObjectName(name)
+
+ self.assertEqual(name, obj.objectName())
+
+ def testEmpty(self):
+ #QObject.objectName('')
+ name = ''
+ obj = QObject()
+ obj.setObjectName(name)
+
+ self.assertEqual(name, obj.objectName())
+
+ def testNone(self):
+ #QObject.objectName(None)
+ obj = QObject()
+
+ self.assertRaises(TypeError, obj.setObjectName, None)
+
+ def testDefault(self):
+ #QObject.objectName() default
+ obj = QObject()
+ self.assertEqual('', obj.objectName())
+
+ def testUnicode(self):
+ #QObject.setObjectName(unicode)
+ name = u'diseño'
+ #FIXME Strange error on upstream when using equal(name, obj)
+ obj = QObject()
+ obj.setObjectName(name)
+ self.assertEqual(obj.objectName(), name)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_timer_event_test.py b/tests/qtcore/qobject_timer_event_test.py
new file mode 100644
index 000000000..b46207d88
--- /dev/null
+++ b/tests/qtcore/qobject_timer_event_test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+'''Test case for QObject.timerEvent overloading'''
+
+import unittest
+from time import sleep
+from PySide.QtCore import QObject, QCoreApplication
+
+from helper import UsesQCoreApplication
+
+class Dummy(QObject):
+
+ def __init__(self, app):
+ super(Dummy, self).__init__()
+ self.times_called = 0
+ self.app = app
+
+ def timerEvent(self, event):
+ QObject.timerEvent(self, event)
+ event.accept()
+ self.times_called += 1
+
+ if self.times_called == 5:
+ self.app.exit(0)
+
+class QObjectTimerEvent(UsesQCoreApplication):
+
+ def setUp(self):
+ #Acquire resources
+ super(QObjectTimerEvent, self).setUp()
+
+ def tearDown(self):
+ #Release resources
+ super(QObjectTimerEvent, self).tearDown()
+
+ def testTimerEvent(self):
+ #QObject.timerEvent overloading
+ obj = Dummy(self.app)
+ timer_id = obj.startTimer(200)
+ self.app.exec_()
+ obj.killTimer(timer_id)
+ self.assertEqual(obj.times_called, 5)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qobject_tr_as_instance_test.py b/tests/qtcore/qobject_tr_as_instance_test.py
new file mode 100644
index 000000000..5aa70530b
--- /dev/null
+++ b/tests/qtcore/qobject_tr_as_instance_test.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+'''Unit tests for QObject's tr and trUtf8 static methods.'''
+
+import os
+import unittest
+from PySide.QtCore import QObject
+
+#from helper import UsesQCoreApplication
+
+class QObjectTrTest(unittest.TestCase):
+ '''Test case to check if QObject tr and trUtf8 static methods could be treated as instance methods.'''
+
+ def setUp(self):
+ self.obj = QObject()
+
+ def tearDown(self):
+ del self.obj
+
+ def testTrCommonCase(self):
+ #Test common case for QObject.tr
+ invar1 = 'test1'
+ outvar1 = self.obj.tr(invar1)
+ invar2 = 'test2'
+ outvar2 = self.obj.tr(invar2, 'test comment')
+ self.assertEqual((invar1, invar2), (outvar1, outvar2))
+
+ def testTrAsInstanceMethod(self):
+ #Test QObject.tr as instance
+ invar1 = 'test1'
+ outvar1 = QObject.tr(self.obj, invar1)
+ invar2 = 'test2'
+ outvar2 = QObject.tr(self.obj, invar2, 'test comment')
+ self.assertEqual((invar1, invar2), (outvar1, outvar2))
+
+ def testTrUtf8CommonCase(self):
+ #Test common case for QObject.trUtf8
+ invar1 = 'test1'
+ outvar1 = self.obj.trUtf8(invar1)
+ invar2 = 'test2'
+ outvar2 = self.obj.trUtf8(invar2, 'test comment')
+ self.assertEqual((invar1, invar2), (outvar1, outvar2))
+
+ def testTrUtf8AsInstanceMethod(self):
+ #Test QObject.trUtf8 as instance
+ invar1 = 'test1'
+ outvar1 = QObject.trUtf8(self.obj, invar1)
+ invar2 = 'test2'
+ outvar2 = QObject.trUtf8(self.obj, invar2, 'test comment')
+ self.assertEqual((invar1, invar2), (outvar1, outvar2))
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qrect_test.py b/tests/qtcore/qrect_test.py
new file mode 100644
index 000000000..3c5f5be05
--- /dev/null
+++ b/tests/qtcore/qrect_test.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python
+'''Test cases for QRect'''
+
+import unittest
+
+from PySide.QtCore import QPoint, QRect
+
+class RectConstructor(unittest.TestCase):
+
+ def testDefault(self):
+ #QRect()
+ obj = QRect()
+
+ self.assert_(obj.isNull())
+
+ def testConstructorQPoint(self):
+ topLeft = QPoint(3, 0)
+ bottomRight = QPoint(0, 3)
+
+ rect1 = QRect(topLeft, bottomRight)
+ rect2 = QRect(topLeft, bottomRight)
+
+ self.assertEqual(rect1, rect2)
+
+class RectOperator(unittest.TestCase):
+ '''Test case for QRect operators'''
+
+ def testEqual(self):
+ '''QRect == QRect
+ Note: operator == must be working as it's the main check
+ for correctness'''
+ rect1 = QRect()
+ rect2 = QRect()
+ self.assertEqual(rect1, rect2)
+
+ rect1 = QRect(0, 4, 100, 300)
+ rect2 = QRect(0, 4, 100, 300)
+ self.assertEqual(rect1, rect2)
+
+ def testNullRectIntersection(self):
+ #QRect & QRect for null rects
+ rect1 = QRect()
+ rect2 = QRect()
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, rect1)
+ self.assertEqual(rect3, rect2)
+
+ def testNoIntersect(self):
+ '''QRect & QRect for non-intersecting QRects
+ Non-intersecting QRects return a 'null' QRect for operator &'''
+ rect1 = QRect(10, 10, 5, 5)
+ rect2 = QRect(20, 20, 5, 5)
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, QRect())
+
+ def testIntersectPartial(self):
+ #QRect & QRect for partial intersections
+ rect1 = QRect(10, 10, 10, 10)
+ rect2 = QRect(15, 15, 10, 10)
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, QRect(15, 15, 5, 5))
+
+ def testIntersetEnclosed(self):
+ #QRect & QRect for a qrect inside another
+ rect1 = QRect(10, 10, 20, 20)
+ rect2 = QRect(15, 15, 5, 5)
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, rect2)
+
+ def testNullRectIntersectBounding(self):
+ #QRect | QRect for null rects
+ rect1 = QRect()
+ rect2 = QRect()
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, rect1)
+ self.assertEqual(rect3, rect2)
+
+ def testNoIntersectBounding(self):
+ '''QRect | QRect for non-intersecting QRects
+ Non-intersecting QRects return a greater QRect for operator |'''
+ rect1 = QRect(10, 10, 5, 5)
+ rect2 = QRect(20, 20, 5, 5)
+ rect3 = rect1 | rect2
+ self.assertEqual(rect3, QRect(10, 10, 15, 15))
+
+ def testBoundingPartialIntersection(self):
+ #QRect | QRect for partial intersections
+ rect1 = QRect(10, 10, 10, 10)
+ rect2 = QRect(15, 15, 10, 10)
+ rect3 = rect1 | rect2
+ self.assertEqual(rect3, QRect(10, 10, 15, 15))
+
+ def testBoundingEnclosed(self):
+ #QRect | QRect for a qrect inside another
+ rect1 = QRect(10, 10, 20, 20)
+ rect2 = QRect(15, 15, 5, 5)
+ rect3 = rect1 | rect2
+ self.assertEqual(rect3, rect1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qresource_test.py b/tests/qtcore/qresource_test.py
new file mode 100644
index 000000000..7fef29e01
--- /dev/null
+++ b/tests/qtcore/qresource_test.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+
+'''Test cases for QResource usage'''
+
+import unittest
+import os
+from PySide.QtCore import QFile, QIODevice
+import resources_mc
+
+class ResourcesUsage(unittest.TestCase):
+ '''Test case for resources usage'''
+
+ def setUp(self):
+ try:
+ f = open('quoteEnUS.txt')
+ except IOError:
+ f = open(os.path.join('qtcore', 'quoteEnUS.txt'))
+
+ self.text = f.read()
+ f.close()
+
+ def tearDown(self):
+ self.text = None
+
+ def testPhrase(self):
+ #Test loading of quote.txt resource
+ f = QFile(':/quote.txt')
+ f.open(QIODevice.ReadOnly|QIODevice.Text)
+ content = f.readAll()
+ f.close()
+ self.assertEqual(self.text, content)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qsize_test.py b/tests/qtcore/qsize_test.py
new file mode 100644
index 000000000..4fb060b74
--- /dev/null
+++ b/tests/qtcore/qsize_test.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+'''Unit tests for QSize'''
+
+import unittest
+
+from PySide.QtCore import QSize
+
+class QSizeOperator(unittest.TestCase):
+ def testOperatorMultiply(self):
+ #QSize operator * float
+ # bug 131
+ a = QSize(1, 1)
+ x = a * 3.4
+ self.assertEqual(QSize(3, 3), x)
+
+ def testOperatorRevertedMultiply(self):
+ #QSize operator * float, reverted
+ # bug 132
+ a = QSize(1, 1)
+ x = 3.4 * a
+ self.assertEqual(QSize(3, 3), x)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qslot_object_test.py b/tests/qtcore/qslot_object_test.py
new file mode 100644
index 000000000..862541b0b
--- /dev/null
+++ b/tests/qtcore/qslot_object_test.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+import unittest
+from PySide import QtCore
+
+global qApp
+
+class objTest(QtCore.QObject):
+
+ def __init__(self, parent=None):
+ QtCore.QObject.__init__(self, parent)
+
+ self.ok = False
+
+ def slot(self):
+ global qApp
+
+ self.ok = True
+ qApp.quit()
+
+
+
+class slotTest(unittest.TestCase):
+ def quit_app(self):
+ global qApp
+
+ qApp.quit()
+
+ def testBasic(self):
+ global qApp
+ timer = QtCore.QTimer()
+ timer.setInterval(100)
+
+ my_obj = objTest()
+ my_slot = QtCore.SLOT("slot()")
+ timer.connect(QtCore.SIGNAL("timeout()"), my_obj, my_slot)
+ timer.start(100)
+
+ QtCore.QTimer.singleShot(1000, self.quit_app)
+ qApp.exec_()
+
+ self.assert_(my_obj.ok)
+
+
+if __name__ == '__main__':
+ global qApp
+ qApp = QtCore.QCoreApplication([])
+ unittest.main()
diff --git a/tests/qtcore/qsrand_test.py b/tests/qtcore/qsrand_test.py
new file mode 100644
index 000000000..97d0a3b0b
--- /dev/null
+++ b/tests/qtcore/qsrand_test.py
@@ -0,0 +1,16 @@
+import gc
+import unittest
+
+from PySide.QtCore import qsrand
+
+class OverflowExceptionCollect(unittest.TestCase):
+ '''Test case for OverflowError exception during garbage collection. See bug #147'''
+
+ def testOverflow(self):
+ # NOTE: PyQt4 raises TypeError, but boost.python raises OverflowError
+ self.assertRaises(OverflowError, qsrand, 42415335332353253)
+ # should not abort if bug #147 is fixed
+ gc.collect()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qstring_buffer_protocol_test.py b/tests/qtcore/qstring_buffer_protocol_test.py
new file mode 100755
index 000000000..6ce6167dc
--- /dev/null
+++ b/tests/qtcore/qstring_buffer_protocol_test.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Tests QString implementation of Python buffer protocol'''
+
+import unittest
+
+from os.path import isdir
+from PySide.QtCore import QString
+
+class QStringBufferProtocolTest(unittest.TestCase):
+ '''Tests QString implementation of Python buffer protocol'''
+
+ def testQStringBufferProtocol(self):
+ #Tests QString implementation of Python buffer protocol using the os.path.isdir
+ #function which an unicode object or other object implementing the Python buffer protocol
+ os_path_isdir_function_correctly_called_with_a_qstring = True
+ try:
+ isdir(QString('/tmp'))
+ except:
+ os_path_isdir_function_correctly_called_with_a_qstring = False
+ self.assertTrue(os_path_isdir_function_correctly_called_with_a_qstring)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qstring_operator_test.py b/tests/qtcore/qstring_operator_test.py
new file mode 100644
index 000000000..0174fdbce
--- /dev/null
+++ b/tests/qtcore/qstring_operator_test.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QString operators'''
+
+import unittest
+
+from PySide.QtCore import QString, QByteArray
+
+class QStringOperatorEqual(unittest.TestCase):
+ '''TestCase for operator QString == QString'''
+
+ def testDefault(self):
+ #QString() == QString()
+ obj1 = QString()
+ obj2 = QString()
+ self.assertEqual(obj1, obj2)
+
+ def testSimple(self):
+ #QString(some_string) == QString(some_string)
+ string = 'egg snakes'
+ self.assertEqual(QString(string), QString(string))
+
+ def testUnicode(self):
+ #QString(unicode) == QString(unicode)
+ string = u'àâãá'
+ self.assertEqual(QString(string), QString(string))
+
+ def testPyString(self):
+ #QString(string) == string
+ string = 'my test string'
+ self.assertEqual(QString(string), string)
+ self.assertEqual(string, QString(string))
+
+ def testPyUnicodeString(self):
+ #QString(unicode) == unicode
+ string = u'àâãá'
+ self.assertEqual(QString(string), string)
+ self.assertEqual(string, unicode(QString(string)))
+
+ def testQByteArray(self):
+ #QString(string) == QByteArray(string)
+ string = 'another test string'
+ self.assertEqual(QString(string), QByteArray(string))
+
+class QStringOperatorAt(unittest.TestCase):
+ '''TestCase for operator QString[]'''
+
+ def testInRange(self):
+ #QString[x] where x is a valid index
+ string = 'abcdefgh'
+ obj = QString(string)
+
+ for i in range(len(string)):
+ self.assertEqual(obj[i], string[i])
+
+ def testInRangeReverse(self):
+ #QString[x] where x is a valid index (reverse order)
+ string = 'abcdefgh'
+ obj = QString(string)
+
+ for i in range(len(string)-1, 0, -1):
+ self.assertEqual(obj[i], string[i])
+
+
+ def testInRangeUnicode(self):
+ #QString[x] where x is a valid index (unicode)
+ string = u'àâãá'
+ obj = QString(string)
+
+ for i in range(len(string)):
+ self.assertEqual(obj[i], string[i])
+
+ def testInRangeUnicodeReverse(self):
+ #QString[x] where x is a valid index (unicode) (reverse order)
+ string = u'àâãá'
+ obj = QString(string)
+
+ for i in range(len(string)-1, 0, -1):
+ self.assertEqual(obj[i], string[i])
+
+ def testOutOfRange(self):
+ #QString[x] where x is out of index
+ string = '1234567'
+ obj = QString(string)
+ self.assertRaises(IndexError, lambda :obj[len(string)])
+
+ def testReturnQString(self):
+ #QString[x] must return a QString
+ string = QString('123456')
+ data = string[0]
+ self.assert_(isinstance(data, QString))
+
+class QStringOperatorAdd(unittest.TestCase):
+ '''TestCase for operator QString[]'''
+
+ def testOperatorAdd(self):
+ str1 = '123'
+ str2 = QString('456')
+ self.assertEquals('123456', str1 + str2)
+ self.assertEquals('456123', str2 + str1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qstring_qkeysequence_test.py b/tests/qtcore/qstring_qkeysequence_test.py
new file mode 100644
index 000000000..d39459cef
--- /dev/null
+++ b/tests/qtcore/qstring_qkeysequence_test.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Tests QString using QKeySequence parameter'''
+
+import unittest
+
+from PySide.QtCore import QString
+from PySide.QtGui import QKeySequence
+
+class QStringQKeySequenceTest(unittest.TestCase):
+ '''Tests QString using QKeySequence parameter'''
+
+ def testQStringQKeySequence(self):
+ a = QString(QKeySequence("Ctrl+A"))
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qstring_test.py b/tests/qtcore/qstring_test.py
new file mode 100644
index 000000000..35863a16b
--- /dev/null
+++ b/tests/qtcore/qstring_test.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QString'''
+
+import unittest
+import ctypes
+import sys
+
+from PySide.QtCore import QString, QByteArray
+
+class QStringToNumber(unittest.TestCase):
+ def testToNumberInt(self):
+ obj = QString('37')
+ self.assertEqual(37, obj.toInt()[0])
+
+ def testToNumberFloat(self):
+ obj = QString('37.109')
+ self.assertEqual(ctypes.c_float(37.109).value,
+ obj.toFloat()[0])
+
+ def testToNumberDouble(self):
+ obj = QString('37.109')
+ self.assertEqual(ctypes.c_double(37.109).value,
+ obj.toDouble()[0])
+
+ def testToULongLong(self):
+ obj = QString('37109')
+ self.assertEqual(ctypes.c_ulong(37109).value,
+ obj.toULongLong()[0])
+
+class QStringConstructor(unittest.TestCase):
+ '''Test case for QString constructors'''
+
+ def testQStringDefault(self):
+ #QString()
+ obj1 = QString()
+ obj2 = QString()
+
+ self.assertEqual(obj1, obj2)
+
+ def testQStringFromPy(self):
+ #QString(const char*)
+ sample = 'a new string'
+ obj1 = QString(sample)
+ obj2 = QString(sample)
+ self.assertEqual(obj1, obj2)
+
+ def testQStringFromUnicode(self):
+ sample = u'áâãà'
+ obj1 = QString(sample)
+ obj2 = QString(sample)
+ self.assertEqual(obj1, obj2)
+ self.assertEqual(obj1, sample)
+ self.assertEqual(obj2, sample)
+
+ def testQStringFromByteArray(self):
+ # QByteArray(const char *) must be working
+ sample = QByteArray('foo')
+ obj1 = QString(sample)
+ obj2 = QString(sample)
+ self.assertEqual(obj1, obj2)
+
+ def testQStringArg(self):
+ a = QString("%1 %2 %3").arg(1).arg("two").arg(3.14)
+ self.assertEquals("1 two 3.14", str(a))
+
+ def testQStringArgNegative(self):
+ a = QString("%1").arg(-20)
+ self.assertEquals("-20", str(a))
+
+
+class QStringComparison(unittest.TestCase):
+ '''Test case for comparison to python strings'''
+
+ def testComparePyString(self):
+ #Compare QStrings and Python strings.
+ py = ''
+ qstr = QString()
+ self.assertEqual(py, qstr)
+
+ py = 'The quick brown fox jumps over the lazy dog'
+ qstr = QString(py)
+ self.assertEqual(py, qstr)
+
+class QStringRange(unittest.TestCase):
+ '''Test case for ranges in python strings'''
+
+ def testSimpleRange(self):
+ #Test open start and open end intervals
+ py = 'The quick brown fox jumps over the lazy dog'
+ qstr = QString(py)
+ self.assertEqual(py[5:], qstr[5:])
+ self.assertEqual(py[:7], qstr[:7])
+
+class QStringIndexOf(unittest.TestCase):
+ def testEmpty(self):
+ string = QString()
+ self.assertEqual(string.indexOf(QString("aaa")), -1)
+ self.assertEqual(string.indexOf(QString()), 0)
+
+ def testString(self):
+ string = QString("the quick brown fox")
+ self.assertEqual(string.indexOf("quick", 0), 4)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qstringlist_test.py b/tests/qtcore/qstringlist_test.py
new file mode 100644
index 000000000..e2a238eb2
--- /dev/null
+++ b/tests/qtcore/qstringlist_test.py
@@ -0,0 +1,165 @@
+
+# -*- coding: utf-8 -*-
+
+'''Test cases for QStringList'''
+
+import unittest
+from random import shuffle
+
+from PySide.QtCore import QStringList, QString
+
+from helper import random_string
+
+class UsesManyStrings(unittest.TestCase):
+ '''Helper class to setup a list of strings and QStrings'''
+ def setUp(self):
+ #Creates a list of strings and python strings
+ self.size = 10
+ # List of Python strings
+ self.samples = [random_string() for x in range(self.size)]
+ # List of QStrings
+ self.strings = map(QString, self.samples)
+
+ self.obj = QStringList(self.strings)
+
+
+class TestConstructorBasic(unittest.TestCase):
+ '''Basic constructor test'''
+
+ def testEmpty(self):
+ #QStringList() - default constructor
+ obj = QStringList()
+ self.assert_(isinstance(obj, QStringList))
+
+ def testQString(self):
+ #QStringList(QString)
+ qstr = QString('aaaa')
+ obj = QStringList(qstr)
+ self.assert_(isinstance(obj, QStringList))
+
+ def testPyString(self):
+ #QStringList(python_string) constructor
+ string = 'forty two'
+ obj = QStringList(string)
+ self.assert_(isinstance(obj, QStringList))
+
+ def testPyStringUnicode(self):
+ #QStringList(unicode python_string) constructor
+ string = 'Nação Zumbi'
+ obj = QStringList(string)
+ self.assert_(isinstance(obj, QStringList))
+
+
+class TestConstructorList(UsesManyStrings):
+ '''Test case for QStringList(List) constructor'''
+
+ def testListQString(self):
+ #QStringList([QString]) constructor
+ obj = QStringList(self.strings)
+ self.assert_(isinstance(obj, QStringList))
+
+ def testListPyString(self):
+ #QStringList([python_string]) constructor
+ obj = QStringList(self.samples)
+ self.assert_(isinstance(obj, QStringList))
+
+ def testListMixed(self):
+ #QStringList([python_string and QString]) mixed constructor
+ mixed = self.samples + self.strings
+ shuffle(mixed)
+ obj = QStringList(mixed)
+ self.assert_(isinstance(obj, QStringList))
+
+ def testCopyList(self):
+ #QStringList(QStringList(list)) - copy constructor
+ obj = QStringList(self.strings)
+ obj2 = QStringList(obj)
+ self.assert_(isinstance(obj2, QStringList))
+ self.assertEqual(obj, obj2)
+
+
+class TestComparison(unittest.TestCase):
+ '''Test case for comparison of QStringLists'''
+
+ def testEqual(self):
+ #QStringList == QStringList
+ string = QString('aaaabvbbcccedde')
+ obj1 = QStringList(string)
+ obj2 = QStringList(string)
+ self.assertEqual(obj1, obj2)
+
+
+class TestIndexing(unittest.TestCase):
+ '''Test case for indexing through []'''
+ def testInvalidIndexEmpty(self):
+ #QStringList[x] for empty list
+ obj = QStringList()
+ self.assertRaises(IndexError, lambda:obj[0])
+
+ def testInvalidIndexQString(self):
+ #QStringList[1] raising IndexError for QStringList(QString)
+ obj = QStringList(QString('aaaaa'))
+ self.assertRaises(IndexError, lambda:obj[1])
+
+ def testValidIndexQString(self):
+ #QStringList[0] not raising IndexError for QStringList(QString)
+ string = QString('abcdefg')
+ obj = QStringList(string)
+ self.assertEqual(obj[0], string)
+
+ def testNegativeIndexing(self):
+ #QStringList[-1] not raising IndexError for QStringList(QString)
+ string = QString('abcdefg')
+ obj = QStringList(string)
+ self.assertEqual(obj[-1], string)
+
+
+class TestListIndexing(UsesManyStrings):
+ '''Test case for indexing QStringList longer than 1 string'''
+
+ def testValid(self):
+ #QStringList[] for valid indexes
+ for i in range(self.size):
+ self.assertEqual(self.strings[i], self.obj[i])
+
+ def testNegativeValid(self):
+ #QStringList[] for valid indexes
+ for i in range(-1, -self.size, -1):
+ self.assertEqual(self.strings[i], self.obj[i])
+
+ def testInvalid(self):
+ #QStringList[] for invalid negative indexes
+ self.assertRaises(IndexError, lambda : self.obj[self.size])
+ self.assertRaises(IndexError, lambda : self.obj[-(self.size+1)])
+
+
+class TestSlicing(UsesManyStrings):
+ '''Test case for slicing a QStringList'''
+
+ def testSlicing(self):
+ #QStringList slicing
+ for i in range(self.size):
+ self.assertEqual(self.obj[i:], self.strings[i:])
+ self.assertEqual(self.obj[:i], self.strings[:i])
+ for j in range(i):
+ self.assertEqual(self.obj[j:i], self.strings[j:i])
+
+ for i in range(-1, -self.size, -1):
+ self.assertEqual(self.obj[:i], self.strings[:i])
+
+
+class TestShiftOperator(UsesManyStrings):
+ '''Test case for QStringList lshift operator'''
+
+ def testShiftOperator(self):
+ #QStringList lshift
+ a = QStringList()
+ a << "a" << "b" << "c";
+ self.assertEquals(3, a.count())
+ b = ["1", "2", "3"]
+ c = ["4", "5", "6"]
+ a << b << c
+ self.assertEquals(9, a.count())
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qtext_codec_test.py b/tests/qtcore/qtext_codec_test.py
new file mode 100644
index 000000000..2bd7f8139
--- /dev/null
+++ b/tests/qtcore/qtext_codec_test.py
@@ -0,0 +1,20 @@
+import gc
+import unittest
+
+from PySide.QtCore import QTextCodec
+
+class TestCodecGetters(unittest.TestCase):
+
+ def testCodecsNames(self):
+ for codec_name in QTextCodec.availableCodecs():
+ codec = QTextCodec.codecForName(codec_name)
+ self.assert_(type(codec), QTextCodec)
+
+ def testCodecsMibs(self):
+ for codec_num in QTextCodec.availableMibs():
+ codec = QTextCodec.codecForMib(codec_num)
+ self.assert_(type(codec), QTextCodec)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qthread_prod_cons_test.py b/tests/qtcore/qthread_prod_cons_test.py
new file mode 100644
index 000000000..fc634dd88
--- /dev/null
+++ b/tests/qtcore/qthread_prod_cons_test.py
@@ -0,0 +1,107 @@
+#!/usr/bin/python
+'''Producer-Consumer test/example with QThread'''
+
+import unittest
+from random import random
+import logging
+
+logging.basicConfig(level=logging.WARNING)
+
+from PySide.QtCore import QThread, QCoreApplication, QObject, SIGNAL
+
+class Bucket(QObject):
+ '''Dummy class to hold the produced values'''
+ def __init__(self, max_size=10, *args):
+ #Constructor which receives the max number of produced items
+ super(Bucket, self).__init__(*args)
+ self.data = []
+ self.max_size = 10
+
+ def pop(self):
+ #Retrieves an item
+ return self.data.pop(0)
+
+ def push(self, data):
+ #Pushes an item
+ self.data.append(data)
+
+class Producer(QThread):
+ '''Producer thread'''
+
+ def __init__(self, bucket, *args):
+ #Constructor. Receives the bucket
+ super(Producer, self).__init__(*args)
+ self.runs = 0
+ self.bucket = bucket
+ self.production_list = []
+
+ def run(self):
+ #Produces at most bucket.max_size items
+ while self.runs < self.bucket.max_size:
+ value = int(random()*10) % 10
+ self.bucket.push(value)
+ self.production_list.append(value)
+ logging.debug('PRODUCER - pushed %d' % value)
+ self.runs += 1
+ self.msleep(5)
+
+
+
+class Consumer(QThread):
+ '''Consumer thread'''
+ def __init__(self, bucket, *args):
+ #Constructor. Receives the bucket
+ super(Consumer, self).__init__(*args)
+ self.runs = 0
+ self.bucket = bucket
+ self.consumption_list = []
+
+ def run(self):
+ #Consumes at most bucket.max_size items
+ while self.runs < self.bucket.max_size:
+ try:
+ value = self.bucket.pop()
+ self.consumption_list.append(value)
+ logging.debug('CONSUMER - got %d' % value)
+ self.runs += 1
+ except IndexError:
+ logging.debug('CONSUMER - empty bucket')
+ self.msleep(5)
+
+class ProducerConsumer(unittest.TestCase):
+ '''Basic test case for producer-consumer QThread'''
+
+ def setUp(self):
+ #Create fixtures
+ self.app = QCoreApplication([])
+
+ def tearDown(self):
+ #Destroy fixtures
+ del self.app
+
+ def finishCb(self):
+ #Quits the application
+ self.app.exit(0)
+
+ def testProdCon(self):
+ #QThread producer-consumer example
+ bucket = Bucket()
+ prod = Producer(bucket)
+ cons = Consumer(bucket)
+
+ prod.start()
+ cons.start()
+
+ QObject.connect(prod, SIGNAL('finished()'), self.finishCb)
+ QObject.connect(cons, SIGNAL('finished()'), self.finishCb)
+
+ self.app.exec_()
+
+ prod.wait()
+ cons.wait()
+
+ self.assertEqual(prod.production_list, cons.consumption_list)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qthread_signal_test.py b/tests/qtcore/qthread_signal_test.py
new file mode 100755
index 000000000..edd7d77f4
--- /dev/null
+++ b/tests/qtcore/qthread_signal_test.py
@@ -0,0 +1,64 @@
+
+'''Test cases for connecting signals between threads'''
+
+import unittest
+
+from PySide.QtCore import QThread, QObject, SIGNAL, QCoreApplication
+
+thread_run = False
+
+class Source(QObject):
+ def __init__(self, *args):
+ QObject.__init__(self, *args)
+
+ def emit_sig(self):
+ self.emit(SIGNAL('source()'))
+
+class Target(QObject):
+ def __init__(self, *args):
+ QObject.__init__(self, *args)
+ self.called = False
+
+ def myslot(self):
+ self.called = True
+
+class ThreadJustConnects(QThread):
+ def __init__(self, source, *args):
+ QThread.__init__(self, *args)
+ self.source = source
+ self.target = Target()
+
+ def run(self):
+ global thread_run
+ thread_run = True
+ QObject.connect(self.source, SIGNAL('source()'), self.target.myslot)
+
+ while not self.target.called:
+ pass
+
+
+
+class BasicConnection(unittest.TestCase):
+
+ def testEmitOutsideThread(self):
+ global thread_run
+
+ app = QCoreApplication([])
+ source = Source()
+ thread = ThreadJustConnects(source)
+
+ QObject.connect(thread, SIGNAL('finished()'), lambda: app.exit(0))
+ thread.start()
+
+ while not thread_run:
+ pass
+
+ source.emit_sig()
+
+ app.exec_()
+ thread.wait()
+
+ self.assert_(thread.target.called)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qthread_test.py b/tests/qtcore/qthread_test.py
new file mode 100644
index 000000000..410afb908
--- /dev/null
+++ b/tests/qtcore/qthread_test.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python
+'''Test cases for QThread'''
+
+import unittest
+from PySide.QtCore import QThread, QCoreApplication, QObject, SIGNAL, QMutex, QTimer
+from PySide.QtCore import QEventLoop
+
+from helper import UsesQCoreApplication
+
+mutex = QMutex()
+
+class Dummy(QThread):
+ '''Dummy thread'''
+ def __init__(self, *args):
+ super(Dummy, self).__init__(*args)
+ self.called = False
+
+ def run(self):
+ #Start-quit sequence
+ mutex.lock()
+ self.called = True
+ mutex.unlock()
+
+class QThreadSimpleCase(UsesQCoreApplication):
+
+ def setUp(self):
+ UsesQCoreApplication.setUp(self)
+ self.called = False
+
+ def tearDown(self):
+ UsesQCoreApplication.tearDown(self)
+
+ def testThread(self):
+ #Basic QThread test
+ obj = Dummy()
+ obj.start()
+ obj.wait()
+
+ self.assert_(obj.called)
+
+ def cb(self, *args):
+ self.called = True
+ #self.exit_app_cb()
+
+ def abort_application(self):
+ self._thread.terminate()
+ self.app.quit()
+
+ def testSignalFinished(self):
+ #QThread.finished() (signal)
+ obj = Dummy()
+ QObject.connect(obj, SIGNAL('finished()'), self.cb)
+ mutex.lock()
+ obj.start()
+ mutex.unlock()
+
+ self._thread = obj
+ QTimer.singleShot(1000, self.abort_application)
+ self.app.exec_()
+
+ self.assert_(self.called)
+
+ def testSignalStarted(self):
+ #QThread.started() (signal)
+ obj = Dummy()
+ QObject.connect(obj, SIGNAL('started()'), self.cb)
+ obj.start()
+
+ self._thread = obj
+ QTimer.singleShot(1000, self.abort_application)
+ self.app.exec_()
+
+ self.assert_(self.called)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qtimer_singleshot_test.py b/tests/qtcore/qtimer_singleshot_test.py
new file mode 100644
index 000000000..96107ecce
--- /dev/null
+++ b/tests/qtcore/qtimer_singleshot_test.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+
+'''Test cases for QTimer.singleShot'''
+
+import unittest
+
+from PySide.QtCore import QObject, QTimer, QCoreApplication, SIGNAL
+from helper import UsesQCoreApplication
+
+class WatchDog(QObject):
+ '''Exits the QCoreApplication main loop after sometime.'''
+
+ def __init__(self, watched):
+ QObject.__init__(self)
+ self.times_called = 0
+ self.watched = watched
+
+ def timerEvent(self, evt):
+ self.times_called += 1
+ if self.times_called == 20:
+ self.watched.exit_app_cb()
+
+class TestSingleShot(UsesQCoreApplication):
+ '''Test case for QTimer.singleShot'''
+
+ def setUp(self):
+ #Acquire resources
+ UsesQCoreApplication.setUp(self)
+ self.watchdog = WatchDog(self)
+ self.called = False
+
+ def tearDown(self):
+ #Release resources
+ del self.watchdog
+ del self.called
+ UsesQCoreApplication.tearDown(self)
+
+ def callback(self):
+ self.called = True
+ self.app.quit()
+
+ def testSingleShot(self):
+ timer = QTimer.singleShot(100, self.callback)
+ self.app.exec_()
+ self.assert_(self.called)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qtimer_timeout_test.py b/tests/qtcore/qtimer_timeout_test.py
new file mode 100644
index 000000000..8dfe39529
--- /dev/null
+++ b/tests/qtcore/qtimer_timeout_test.py
@@ -0,0 +1,57 @@
+
+'''Test case for timeout() signals from QTimer object.'''
+
+import unittest
+import os
+from tempfile import mkstemp
+from PySide.QtCore import QObject, QTimer, SIGNAL
+from helper import UsesQCoreApplication
+
+class WatchDog(QObject):
+ '''Exits the QCoreApplication main loop after sometime.'''
+
+ def __init__(self, watched):
+ QObject.__init__(self)
+ self.times_called = 0
+ self.watched = watched
+
+ def timerEvent(self, evt):
+ self.times_called += 1
+ if self.times_called == 20:
+ self.watched.exit_app_cb()
+
+
+class TestTimeoutSignal(UsesQCoreApplication):
+ '''Test case to check if the signals are really being caught'''
+
+ def setUp(self):
+ #Acquire resources
+ UsesQCoreApplication.setUp(self)
+ self.watchdog = WatchDog(self)
+ self.timer = QTimer()
+ self.called = False
+
+ def tearDown(self):
+ #Release resources
+ del self.watchdog
+ del self.timer
+ del self.called
+ UsesQCoreApplication.tearDown(self)
+
+ def callback(self, *args):
+ #Default callback
+ self.called = True
+
+ def testTimeoutSignal(self):
+ #Test the QTimer timeout() signal
+ QObject.connect(self.timer, SIGNAL('timeout()'), self.callback)
+ self.timer.start(4)
+ self.watchdog.startTimer(10)
+
+ self.app.exec_()
+
+ self.assert_(self.called)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/qtnamespace_test.py b/tests/qtcore/qtnamespace_test.py
new file mode 100644
index 000000000..3343a276b
--- /dev/null
+++ b/tests/qtcore/qtnamespace_test.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+'''Test suite for QtCore.Qt namespace'''
+
+import unittest
+
+from PySide.QtCore import Qt
+
+class QtNamespace(unittest.TestCase):
+ '''Test case for accessing attributes from Qt namespace'''
+
+ def testBasic(self):
+ #Access to Qt namespace
+ getattr(Qt, 'Horizontal')
+ getattr(Qt, 'WindowMaximizeButtonHint')
+ self.assert_(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/quoteEnUS.txt b/tests/qtcore/quoteEnUS.txt
new file mode 100644
index 000000000..909b4fa17
--- /dev/null
+++ b/tests/qtcore/quoteEnUS.txt
@@ -0,0 +1 @@
+Fine! Dishonor! Dishonor on you, dishonor on ya cow!
diff --git a/tests/qtcore/qurl_test.py b/tests/qtcore/qurl_test.py
new file mode 100644
index 000000000..14243a11a
--- /dev/null
+++ b/tests/qtcore/qurl_test.py
@@ -0,0 +1,91 @@
+#!/usr/bin/python
+'''Test suite for QtCore.QUrl'''
+
+import unittest
+
+from PySide.QtCore import QUrl
+
+class QUrlBasicConstructor(unittest.TestCase):
+ '''Tests the basic constructors'''
+
+ def testBasic(self):
+ #Default constructor for QUrl
+ url = QUrl()
+ self.assertEqual(url.toString(), "")
+
+ def testSetAttributes(self):
+ #Construct QUrl by set* methods
+ url = QUrl()
+
+ url.setScheme('ftp')
+ self.assertEqual(url.toString(), 'ftp:')
+
+ url.setHost('www.google.com')
+ self.assertEqual(url.toString(), 'ftp://www.google.com')
+
+ url.setPort(8080)
+ self.assertEqual(url.toString(), 'ftp://www.google.com:8080')
+
+ url.setPath('mail/view')
+ self.assertEqual(url.toString(),
+ 'ftp://www.google.com:8080/mail/view')
+
+ url.setUserName('john')
+ self.assertEqual(url.toString(),
+ 'ftp://john@www.google.com:8080/mail/view')
+
+ url.setPassword('abc123')
+ self.assertEqual(url.toString(),
+ 'ftp://john:abc123@www.google.com:8080/mail/view')
+
+class QueryItemsTest(unittest.TestCase):
+ '''Test query item management'''
+
+ def testQueryItems(self):
+ #QUrl.queryItems
+ url = QUrl('http://www.google.com/search?q=python&hl=en')
+ valid_data = [(('q'), ('python')), (('hl'), ('en'))]
+
+ self.assertEqual(sorted(url.queryItems()), sorted(valid_data))
+
+ def testEncodedQueryItems(self):
+ #QUrl.encodedQueryItems
+ url = QUrl('http://www.google.com/search?q=python&hl=en')
+ valid_data = [(('q'), ('python')), (('hl'), ('en'))]
+
+ self.assertEqual(sorted(url.encodedQueryItems()), sorted(valid_data))
+
+ def testSetQueryItems(self):
+ #QUrl.setQueryItems
+ urla = QUrl('http://www.google.com/search?q=python&hl=en')
+ urlb = QUrl('http://www.google.com/search')
+
+ urlb.setQueryItems(urla.queryItems())
+
+ self.assertEqual(urla, urlb)
+
+ def testAddQueryItem(self):
+ #QUrl.addQueryItem
+ url = QUrl()
+ valid_data = [('hl', 'en'), ('user', 'konqui')]
+
+ url.addQueryItem(*valid_data[0])
+ self.assertEqual(url.queryItems()[0], valid_data[0])
+
+ url.addQueryItem(*valid_data[1])
+ self.assertEqual(sorted(url.queryItems()), sorted(valid_data))
+
+ def testAllEncodedQueryItemsValues(self):
+ #QUrl.allEncodedQueryItemValues
+ url = QUrl()
+ key = 'key'
+ valid_data = ['data', 'valid', 'test']
+
+ for i, data in enumerate(valid_data):
+ url.addQueryItem(key, data)
+ self.assertEqual(url.allEncodedQueryItemValues(key),
+ list(valid_data[:i+1]))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/qvariant_test.py b/tests/qtcore/qvariant_test.py
new file mode 100644
index 000000000..b3f80c895
--- /dev/null
+++ b/tests/qtcore/qvariant_test.py
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QVariant'''
+
+import unittest
+import sys
+
+from PySide.QtCore import QSize, QVariant, QByteArray, QStringList
+
+class Dummy(object):
+ pass
+
+class MySize(QSize):
+ pass
+
+class QVariantToNumber(unittest.TestCase):
+ def testToNumberInt(self):
+ obj = QVariant('37')
+ self.assertEqual(37, obj.toInt()[0])
+
+ def testToNumberFloat(self):
+ obj = QVariant('37.109')
+ self.assertEqual(37.109, obj.toDouble()[0])
+
+class QVariantTypeName(unittest.TestCase):
+ def testTypeNameQString(self):
+ #QVariant.typeName()
+ obj = QVariant('aaaa')
+ self.assertEqual('QString', obj.typeName())
+
+ def testTypeNameInt(self):
+ obj = QVariant(34)
+ self.assertEqual('int', obj.typeName())
+
+ def testTypeNameDouble(self):
+ obj = QVariant(3.14)
+ self.assertEqual('double', obj.typeName())
+
+ def testTypeNameBool(self):
+ obj = QVariant(True)
+ self.assertEqual('bool', obj.typeName())
+
+ def testTypeNameQByteArray(self):
+ obj = QVariant(QByteArray('aaaa'))
+ self.assertEqual('QByteArray', obj.typeName())
+
+ def testTypeNameNone(self):
+ obj = QVariant()
+ self.assertEqual(None, obj.typeName())
+
+ def testTypeNameQVariantList(self):
+ obj = QVariant([1,Dummy(),3,4])
+ self.assertEqual('QVariantList', obj.typeName())
+
+ def testTypeNameQStringList(self):
+ obj = QVariant(QStringList())
+ self.assertEqual('QStringList', obj.typeName())
+
+ def testTypeNamePythonClasses(self):
+ ## QVariant of python classes
+ d = Dummy()
+ obj = QVariant(d)
+ self.assertEqual('PyQt_PyObject', obj.typeName())
+
+ # This works only on PyQt4 4.5.x, not on PyQt4 4.4.x or PySide
+ def testSubClassConvertion(self):
+ mysize = MySize(0, 0)
+ variant = QVariant(mysize)
+
+ assert(variant.type() != QVariant.Size)
+ assert(variant.toPyObject() is mysize)
+
+class QVariantConstructor(unittest.TestCase):
+ def testCopyConstructor(self):
+ obj = QVariant(1)
+ cpy = QVariant(obj)
+
+ self.assertEqual(obj.type(), cpy.type())
+
+ def testQStringConstructor(self):
+ obj = QVariant("PySide")
+ self.assertEqual(obj.type(), QVariant.String)
+
+class QVariantToPyObject(unittest.TestCase):
+ def testQVariantPyList(self):
+ obj = QVariant([1, 'two', 3])
+ self.assertEqual(obj.toPyObject(), [1, 'two', 3])
+
+ def testPyObject(self):
+ d = Dummy()
+ obj = QVariant(d)
+ self.assertEqual(d, obj.toPyObject())
+
+ def atestNoneToPyObject(self):
+ # XXX Do not run by default because segfaults with PyQt4
+ obj = QVariant()
+ self.assertEqual(None, obj.toPyObject())
+
+ def testQStringToPyObject(self):
+ d = 'abc'
+ obj = QVariant('abc')
+ self.assertEqual(d, obj.toPyObject())
+
+class QVartiantTypeTest(unittest.TestCase):
+ def testQSize(self):
+ class MySize(QSize):
+ pass
+
+ mysize = MySize(5, 5)
+ variant = QVariant(mysize)
+ self.assert_(variant.type() != QVariant.Size)
+ self.assert_(variant.toPyObject() is mysize)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/resources.qrc b/tests/qtcore/resources.qrc
new file mode 100644
index 000000000..cea17b440
--- /dev/null
+++ b/tests/qtcore/resources.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="quote.txt">quoteEnUS.txt</file>
+ </qresource>
+</RCC>
+
diff --git a/tests/qtcore/resources_mc.py b/tests/qtcore/resources_mc.py
new file mode 100644
index 000000000..132c8db12
--- /dev/null
+++ b/tests/qtcore/resources_mc.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+# Resource object code
+#
+# Created: Thu Mar 26 11:08:45 2009
+# by: The Resource Compiler for PyQt (Qt v4.5.0)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PySide import QtCore
+
+qt_resource_data = "\
+\x00\x00\x00\x35\
+\x46\
+\x69\x6e\x65\x21\x20\x44\x69\x73\x68\x6f\x6e\x6f\x72\x21\x20\x44\
+\x69\x73\x68\x6f\x6e\x6f\x72\x20\x6f\x6e\x20\x79\x6f\x75\x2c\x20\
+\x64\x69\x73\x68\x6f\x6e\x6f\x72\x20\x6f\x6e\x20\x79\x61\x20\x63\
+\x6f\x77\x21\x0a\
+"
+
+qt_resource_name = "\
+\x00\x09\
+\x06\xa8\xaa\x74\
+\x00\x71\
+\x00\x75\x00\x6f\x00\x74\x00\x65\x00\x2e\x00\x74\x00\x78\x00\x74\
+"
+
+qt_resource_struct = "\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+"
+
+def qInitResources():
+ QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/tests/qtcore/resources_mc.pyc b/tests/qtcore/resources_mc.pyc
new file mode 100644
index 000000000..a8140b1d1
--- /dev/null
+++ b/tests/qtcore/resources_mc.pyc
Binary files differ
diff --git a/tests/qtcore/static_method_test.py b/tests/qtcore/static_method_test.py
new file mode 100755
index 000000000..26955d925
--- /dev/null
+++ b/tests/qtcore/static_method_test.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+'''Tests for static methos conflicts with class methods'''
+
+import unittest
+
+from PySide import QtCore
+
+class static_function_test(unittest.TestCase):
+ def testMemberQFileExists(self):
+ f = QtCore.QFile("/tmp/foo.txt")
+ self.assertEqual(f.exists(), False)
+
+ def testStatocQFileExists(self):
+ self.assertEqual(QtCore.QFile.fileExists("/tmp/foo.txt"), False)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/static_protected_methods_test.py b/tests/qtcore/static_protected_methods_test.py
new file mode 100644
index 000000000..9d920a438
--- /dev/null
+++ b/tests/qtcore/static_protected_methods_test.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+'''Unit tests for static protected methods'''
+
+import unittest, time
+
+from PySide.QtCore import QThread
+
+class Test (QThread):
+ def run(self):
+ start = time.time()
+ self.sleep(1)
+ self.time_elapsed = time.time() - start
+
+class QStaticProtectedCall(unittest.TestCase):
+ '''Test case for static protected method call'''
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def testPathSeparator(self):
+ thread = Test()
+ thread.start()
+ thread.wait()
+ self.assertTrue(thread.time_elapsed <= 1.1) # tolarance of 100ms
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/thread_signals.py b/tests/qtcore/thread_signals.py
new file mode 100644
index 000000000..e2b66730b
--- /dev/null
+++ b/tests/qtcore/thread_signals.py
@@ -0,0 +1,39 @@
+
+''' Test case for QObject.signalsBlocked() and blockSignal()'''
+
+import unittest
+import os
+from tempfile import mkstemp
+
+from PySide.QtCore import QObject, SIGNAL, QFile, QThread, QTimer
+from helper import UsesQCoreApplication
+
+class MyThread(QThread):
+
+ def run(self):
+ self.emit(SIGNAL("test(const QString&)"),
+ "INdT - PySide");
+
+class TestThreadSignal(UsesQCoreApplication):
+
+ __called__ = True
+ def _callback(self, msg):
+ self.assertEqual(msg, "INdT - PySide")
+ self.__called__ = True
+ self._quit()
+
+ def _quit(self):
+ self.app.quit()
+
+ def testThread(self):
+ t = MyThread()
+ QObject.connect(t, SIGNAL("test(const QString&)"),
+ self._callback);
+
+ t.start()
+ QTimer.singleShot(100, self._quit)
+ self.app.exec_()
+ self.assert_(self.__called__);
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtcore/translation_test.py b/tests/qtcore/translation_test.py
new file mode 100644
index 000000000..31bb20e74
--- /dev/null
+++ b/tests/qtcore/translation_test.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+'''Unit tests to test QTranslator and translation in general.'''
+
+import os
+import unittest
+from PySide.QtCore import QObject, QTranslator, QCoreApplication
+
+from helper import UsesQCoreApplication
+
+class TranslationTest(UsesQCoreApplication):
+ '''Test case for Qt translation facilities.'''
+
+ def setUp(self):
+ super(TranslationTest, self).setUp()
+ self.trdir = os.path.join(os.path.dirname(__file__), 'translations')
+ # os.system is probably not the best way to do it
+ os.system('lrelease %s/*.ts > /dev/null' % self.trdir)
+
+ def tearDown(self):
+ os.system('rm %s/*.qm > /dev/null' % self.trdir)
+ super(TranslationTest, self).tearDown()
+
+ def testLatin(self):
+ #Set string value to Latin
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_latin.qm'))
+ self.app.installTranslator(translator)
+
+ obj = QObject()
+ obj.setObjectName(obj.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), u'Orbis, te saluto!')
+
+ def testRussian(self):
+ #Set string value to Russian
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_russian.qm'))
+ self.app.installTranslator(translator)
+
+ obj = QObject()
+ obj.setObjectName(obj.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), u'привет мир!')
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/translations/trans_latin.ts b/tests/qtcore/translations/trans_latin.ts
new file mode 100644
index 000000000..b9fcf41be
--- /dev/null
+++ b/tests/qtcore/translations/trans_latin.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="lt">
+<defaultcodec></defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Hello World!</source>
+ <translation>Orbis, te saluto!</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/qtcore/translations/trans_russian.ts b/tests/qtcore/translations/trans_russian.ts
new file mode 100644
index 000000000..d1ba49bd2
--- /dev/null
+++ b/tests/qtcore/translations/trans_russian.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="ru">
+<defaultcodec></defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Hello World!</source>
+ <translation>привет мир!</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/qtcore/unaryoperator_test.py b/tests/qtcore/unaryoperator_test.py
new file mode 100755
index 000000000..94db1feec
--- /dev/null
+++ b/tests/qtcore/unaryoperator_test.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+'''Tests the presence of unary operator __neg__ on the QPoint class'''
+
+import unittest
+
+from PySide.QtCore import QPoint
+
+class NegUnaryOperatorTest(unittest.TestCase):
+ '''Tests the presence of unary operator __neg__ on the QPoint class'''
+
+ def setUp(self):
+ #Acquire resources
+ self.x, self.y = 10, 20
+ self.neg_x, self.neg_y = -self.x, -self.y
+ self.qpoint = QPoint(self.x, self.y)
+
+ def tearDown(self):
+ #Release resources
+ del self.qpoint
+ del self.x
+ del self.y
+ del self.neg_x
+ del self.neg_y
+
+ def testNegUnaryOperator(self):
+ #Test __neg__ unary operator on QPoint class
+ __neg__method_exists = True
+ try:
+ neg_qpoint = -self.qpoint
+ except:
+ __neg__method_exists = False
+
+ self.assertTrue(__neg__method_exists)
+ self.assertEqual(self.qpoint, -neg_qpoint)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtcore/unicode_test.py b/tests/qtcore/unicode_test.py
new file mode 100644
index 000000000..f0bb883ed
--- /dev/null
+++ b/tests/qtcore/unicode_test.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+'''Unit tests for QString conversion to/from Python Unicode'''
+
+import unittest
+
+from PySide.QtCore import QObject
+
+class UnicodeConversion(unittest.TestCase):
+ '''Test case for QString to/from Python Unicode conversion'''
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def testSetRegularStringRetrieveUnicode(self):
+ #Set regular Python string retrieve unicode
+ obj = QObject()
+ obj.setObjectName('test')
+ self.assertEqual(obj.objectName(), u'test')
+
+ def testSetUnicodeRetrieveUnicode(self):
+ #Set Python unicode string and retrieve unicode
+ obj = QObject()
+ obj.setObjectName(u'ümlaut')
+ self.assertEqual(obj.objectName(), u'ümlaut')
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/float_to_int_implicit_conversion_test.py b/tests/qtgui/float_to_int_implicit_conversion_test.py
new file mode 100644
index 000000000..cc7d18fd9
--- /dev/null
+++ b/tests/qtgui/float_to_int_implicit_conversion_test.py
@@ -0,0 +1,32 @@
+
+'''Test cases for QImage'''
+
+import unittest
+
+from PySide.QtGui import QImage, qRgb
+
+from helper import UsesQApplication
+
+class SetPixelFloat(UsesQApplication):
+ '''Test case for calling setPixel with float as argument'''
+
+ def setUp(self):
+ #Acquire resources
+ super(SetPixelFloat, self).setUp()
+ self.color = qRgb(255, 0, 0)
+ self.image = QImage(200, 200, QImage.Format_RGB32)
+
+ def tearDown(self):
+ #Release resources
+ del self.color
+ del self.image
+ super(SetPixelFloat, self).tearDown()
+
+ def testFloat(self):
+ #QImage.setPixel(float, float, color) - Implicit conversion
+ self.image.setPixel(3.14, 4.2, self.color)
+ self.assertEqual(self.image.pixel(3.14, 4.2), self.color)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/grandparent_method_test.py b/tests/qtgui/grandparent_method_test.py
new file mode 100644
index 000000000..3c1829377
--- /dev/null
+++ b/tests/qtgui/grandparent_method_test.py
@@ -0,0 +1,23 @@
+
+'''Tests for calling methods further than the direct parent'''
+
+import unittest
+
+from PySide.QtGui import QPushButton, QWidget
+
+from helper import UsesQApplication
+
+class Dummy(QPushButton):
+
+ def show(self):
+ QWidget.show(self)
+ self.called = True
+
+class GrandParentMethod(UsesQApplication):
+ def testMethod(self):
+ obj = Dummy()
+ obj.show()
+ self.assert_(obj.called)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/missing_symbols_test.py b/tests/qtgui/missing_symbols_test.py
new file mode 100644
index 000000000..de23c569e
--- /dev/null
+++ b/tests/qtgui/missing_symbols_test.py
@@ -0,0 +1,29 @@
+
+'''(Very) Simple test case for missing names from QtGui'''
+
+import unittest
+from PySide import QtGui
+
+class MissingClasses(unittest.TestCase):
+ def testQDrag(self): # Bug 222
+ getattr(QtGui, 'QDrag')
+
+ def testQDropEvent(self): # Bug 255
+ getattr(QtGui, 'QDropEvent')
+
+class MissingMembers(unittest.TestCase):
+
+ def testQFontMetricsSize(self): # Bug 223
+ QtGui.QFontMetrics.size
+
+ def testQLayoutSetSpacing(self): # Bug 231
+ QtGui.QLayout.setSpacing
+
+ def testQImageLoad(self): # Bug 257
+ QtGui.QImage.load
+
+ def testQStandardItemModelinsertRow(self): # Bug 227
+ QtGui.QStandardItemModel.insertRow
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/paint_event_test.py b/tests/qtgui/paint_event_test.py
new file mode 100644
index 000000000..02253908e
--- /dev/null
+++ b/tests/qtgui/paint_event_test.py
@@ -0,0 +1,71 @@
+
+'''Test paint event override in python'''
+
+import unittest
+
+from PySide.QtCore import QTimerEvent
+from PySide.QtGui import QApplication, QWidget
+
+from helper import UsesQApplication
+
+class MyWidget(QWidget):
+ '''Sample widget'''
+
+ def __init__(self, app=None):
+ #Creates a new widget
+ if app is None:
+ app = QApplication([])
+
+ super(MyWidget, self).__init__()
+ self.app = app
+ self.runs = 0
+ self.max_runs = 5
+ self.paint_event_called = False
+
+ def timerEvent(self, event):
+ #Timer event method
+ self.runs += 1
+
+ if self.runs == self.max_runs:
+ self.app.quit()
+
+ if not isinstance(event, QTimerEvent):
+ raise TypeError('Invalid event type. Must be QTimerEvent')
+
+ def paintEvent(self, event):
+ #Empty paint event method
+ # XXX: should be using super here, but somehow PyQt4
+ # complains about paintEvent not present in super
+ QWidget.paintEvent(self, event)
+ self.paint_event_called = True
+
+
+class PaintEventOverride(UsesQApplication):
+ '''Test case for overriding QWidget.paintEvent'''
+
+ qapplication = True
+
+ def setUp(self):
+ #Acquire resources
+ super(PaintEventOverride, self).setUp()
+ self.widget = MyWidget(self.app)
+
+ def tearDown(self):
+ #Release resources
+ del self.widget
+ super(PaintEventOverride, self).tearDown()
+
+ def testPaintEvent(self):
+ #Test QWidget.paintEvent override
+ timer_id = self.widget.startTimer(100)
+ self.widget.show()
+ self.app.exec_()
+
+ self.widget.killTimer(timer_id)
+
+ self.assert_(self.widget.paint_event_called)
+ self.assertEqual(self.widget.runs, 5)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/parent_method_test.py b/tests/qtgui/parent_method_test.py
new file mode 100644
index 000000000..8d0ba9601
--- /dev/null
+++ b/tests/qtgui/parent_method_test.py
@@ -0,0 +1,25 @@
+
+import unittest
+
+from PySide.QtCore import QObject, QTimer, QThread
+from PySide.QtGui import *
+
+class Foo(QTableView):
+ def __init__(self, parent=None):
+ QTableView.__init__(self, parent)
+
+from helper import UsesQApplication
+
+class TestParentType(UsesQApplication):
+
+ def testParentType(self):
+ # Test the problem with calling QObject.parent from a QWidget
+ # when the parent is a python class derived from a QWidget-derived
+ # class. The method was returning the last C++ class in the hierarchy
+ parent = Foo()
+ w2 = QWidget(parent)
+ self.assert_(isinstance(w2.parentWidget(), Foo))
+ self.assert_(isinstance(w2.parent(), Foo))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/parent_policy_test.py b/tests/qtgui/parent_policy_test.py
new file mode 100755
index 000000000..e90da5a49
--- /dev/null
+++ b/tests/qtgui/parent_policy_test.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+
+import unittest
+
+from helper import UsesQApplication
+from PySide.QtCore import QAbstractTableModel, QVariant
+from PySide.QtGui import QTableView
+
+class TestModel(QAbstractTableModel):
+ def __init__(self, parent=None):
+ QAbstractTableModel.__init__(self, parent)
+ def rowCount(self, parent):
+ return 0
+ def columnCount(self, parent):
+ return 0
+ def data(self, index, role):
+ return QVariant()
+
+class ParentPolicyTest(UsesQApplication):
+
+ def testModelWithoutParent(self):
+ view = QTableView()
+ model = TestModel()
+ view.setModel(model)
+ samemodel = view.model()
+ self.assertEqual(model, samemodel)
+
+ def testModelWithParent(self):
+ view = QTableView()
+ model = TestModel(self.app)
+ view.setModel(model)
+ samemodel = view.model()
+ self.assertEqual(model, samemodel)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/python_properties_test.py b/tests/qtgui/python_properties_test.py
new file mode 100644
index 000000000..ce50431a1
--- /dev/null
+++ b/tests/qtgui/python_properties_test.py
@@ -0,0 +1,19 @@
+import unittest
+from PySide import QtGui, QtCore
+
+class Properties(unittest.TestCase):
+
+ def testStaticProperty(self):
+ self.assertEqual(QtGui.QGraphicsItem.UserType, 65536)
+
+ def testMemberProperty(self):
+ i = QtGui.QGraphicsItem()
+ self.assertEqual(i.UserType, 65536)
+
+ def testInstanceProperty(self):
+ p = QtGui.QStyleOptionViewItemV3()
+ self.assert_(isinstance(p.locale, QtCore.QLocale))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qapp_test.py b/tests/qtgui/qapp_test.py
new file mode 100644
index 000000000..c371492e6
--- /dev/null
+++ b/tests/qtgui/qapp_test.py
@@ -0,0 +1,17 @@
+
+''' Test the presence of qApp Macro'''
+
+import unittest
+
+from PySide import QtGui
+
+class QAppPresence(unittest.TestCase):
+
+ def testQApp(self):
+ #QtGui.qApp variable is instance of QApplication
+ self.assert_(isinstance(QtGui.qApp, QtGui.QApplication))
+
+
+if __name__ == '__main__':
+ app = QtGui.QApplication([])
+ unittest.main()
diff --git a/tests/qtgui/qapplication_exit_segfault_test.py b/tests/qtgui/qapplication_exit_segfault_test.py
new file mode 100644
index 000000000..72b810a98
--- /dev/null
+++ b/tests/qtgui/qapplication_exit_segfault_test.py
@@ -0,0 +1,17 @@
+
+import unittest
+import sys
+
+from PySide.QtGui import QApplication, QPushButton, QWidget, QSpinBox
+
+class QApplicationDelete(unittest.TestCase):
+ '''Test for segfault when deleting a QApplication before a QWidget'''
+
+ def testQPushButton(self):
+ #QApplication deleted before QPushButton
+ a = QApplication([])
+ b = QPushButton('aaaa')
+ del a
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qapplication_singleton_test.py b/tests/qtgui/qapplication_singleton_test.py
new file mode 100644
index 000000000..9c959f9d4
--- /dev/null
+++ b/tests/qtgui/qapplication_singleton_test.py
@@ -0,0 +1,12 @@
+
+import unittest
+
+from PySide.QtGui import QApplication
+
+class TestSingleton(unittest.TestCase):
+ def testBasic(self):
+ a = QApplication([])
+ self.assertRaises(RuntimeError, QApplication, [])
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qbrush_test.py b/tests/qtgui/qbrush_test.py
new file mode 100644
index 000000000..cf11652a5
--- /dev/null
+++ b/tests/qtgui/qbrush_test.py
@@ -0,0 +1,24 @@
+
+'''Test cases for QBrush'''
+
+import unittest
+
+from PySide.QtCore import Qt
+from PySide.QtGui import QApplication, QColor, QBrush
+
+from helper import UsesQApplication
+
+class Constructor(UsesQApplication):
+ '''Test case for constructor of QBrush'''
+
+ def testQColor(self):
+ #QBrush(QColor) constructor
+ color = QColor('black')
+ obj = QBrush(color)
+ self.assertEqual(obj.color(), color)
+
+ obj = QBrush(Qt.blue)
+ self.assertEqual(obj.color(), Qt.blue)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qdatastream_gui_operators_test.py b/tests/qtgui/qdatastream_gui_operators_test.py
new file mode 100644
index 000000000..7d46984ff
--- /dev/null
+++ b/tests/qtgui/qdatastream_gui_operators_test.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+
+import unittest
+import sys
+
+from PySide import QtGui, QtCore
+
+
+class QAppPresence(unittest.TestCase):
+
+ def testQPixmap(self):
+ ds = QtCore.QDataStream()
+ p = QtGui.QPixmap()
+ ds << p
+ ds >> p
+
+if __name__ == '__main__':
+ app = QtGui.QApplication([])
+ unittest.main()
diff --git a/tests/qtgui/qgraphicsitem_test.py b/tests/qtgui/qgraphicsitem_test.py
new file mode 100644
index 000000000..43545a431
--- /dev/null
+++ b/tests/qtgui/qgraphicsitem_test.py
@@ -0,0 +1,35 @@
+
+''' Test cases related to QGraphicsItem and subclasses'''
+
+import unittest
+
+from PySide.QtGui import QGraphicsScene, QPolygonF, QColor, QBrush
+
+from helper import UsesQApplication
+
+class QColorOnSetBrush(UsesQApplication):
+ '''Test case for passing a QColor directly to setBrush'''
+
+ def setUp(self):
+ #Acquire resources
+ super(QColorOnSetBrush, self).setUp()
+
+ self.scene = QGraphicsScene()
+ poly = QPolygonF()
+ self.item = self.scene.addPolygon(poly)
+ self.color = QColor('black')
+
+ def tearDown(self):
+ #Release resources
+ del self.color
+ del self.item
+ del self.scene
+ super(QColorOnSetBrush, self).tearDown()
+
+ def testQColor(self):
+ #QGraphicsAbstractShapeItem.setBrush(QColor)
+ self.item.setBrush(self.color)
+ self.assertEqual(QBrush(self.color), self.item.brush())
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qgraphicsscene_test.py b/tests/qtgui/qgraphicsscene_test.py
new file mode 100644
index 000000000..abfd5839c
--- /dev/null
+++ b/tests/qtgui/qgraphicsscene_test.py
@@ -0,0 +1,152 @@
+
+'''Basic test cases for QGraphicsScene'''
+
+import unittest
+import gc
+
+from PySide.QtCore import QPointF
+from PySide.QtGui import QApplication, QPushButton, QPolygonF, QPixmap
+from PySide.QtGui import QGraphicsScene, QPainterPath
+from PySide.QtGui import QGraphicsEllipseItem, QGraphicsLineItem
+from PySide.QtGui import QGraphicsPathItem, QGraphicsPixmapItem
+from PySide.QtGui import QGraphicsPolygonItem, QGraphicsRectItem
+from PySide.QtGui import QGraphicsSimpleTextItem, QGraphicsTextItem
+from PySide.QtGui import QGraphicsProxyWidget
+
+from helper import UsesQApplication
+
+class Constructor(unittest.TestCase):
+ '''QGraphicsScene constructor'''
+
+ def testConstructor(self):
+ #QGraphicsScene constructor
+ obj = QGraphicsScene()
+ self.assert_(isinstance(obj, QGraphicsScene))
+
+
+class ConstructorWithRect(unittest.TestCase):
+ '''QGraphicsScene qrect constructor and related sizes'''
+
+ def setUp(self):
+ #Acquire resources
+ # PyQt4 doesn't accept a QRect as argument to constructor
+ self.scene = QGraphicsScene(0, 200, 150, 175)
+
+ def tearDown(self):
+ #Release resources
+ del self.scene
+
+ def testHeight(self):
+ #QGraphicsScene.height()
+ self.assertEqual(self.scene.height(), 175)
+
+ def testWidth(self):
+ #QGraphicsScene.width()
+ self.assertEqual(self.scene.width(), 150)
+
+
+class AddItem(UsesQApplication):
+ '''Tests for QGraphicsScene.add*'''
+
+ qapplication = True
+
+ def setUp(self):
+ #Acquire resources
+ super(AddItem, self).setUp()
+ self.scene = QGraphicsScene()
+ # While the scene does not inherits from QWidget, requires
+ # an application to make the internals work.
+
+ def tearDown(self):
+ #Release resources
+ del self.scene
+ super(AddItem, self).tearDown()
+
+ def testEllipse(self):
+ #QGraphicsScene.addEllipse
+ item = self.scene.addEllipse(100, 100, 100, 100)
+ self.assert_(isinstance(item, QGraphicsEllipseItem))
+
+ def testLine(self):
+ #QGraphicsScene.addLine
+ item = self.scene.addLine(100, 100, 200, 200)
+ self.assert_(isinstance(item, QGraphicsLineItem))
+
+ def testPath(self):
+ #QGraphicsScene.addPath
+ item = self.scene.addPath(QPainterPath())
+ self.assert_(isinstance(item, QGraphicsPathItem))
+
+ def testPixmap(self):
+ #QGraphicsScene.addPixmap
+ item = self.scene.addPixmap(QPixmap())
+ self.assert_(isinstance(item, QGraphicsPixmapItem))
+
+ def testPolygon(self):
+ #QGraphicsScene.addPolygon
+ points = [QPointF(0, 0), QPointF(100, 100), QPointF(0, 100)]
+ item = self.scene.addPolygon(QPolygonF(points))
+ self.assert_(isinstance(item, QGraphicsPolygonItem))
+
+ def testRect(self):
+ #QGraphicsScene.addRect
+ item = self.scene.addRect(100, 100, 100, 100)
+ self.assert_(isinstance(item, QGraphicsRectItem))
+
+ def testSimpleText(self):
+ #QGraphicsScene.addSimpleText
+ item = self.scene.addSimpleText('Monty Python 42')
+ self.assert_(isinstance(item, QGraphicsSimpleTextItem))
+
+ def testText(self):
+ #QGraphicsScene.addText
+ item = self.scene.addText('Monty Python 42')
+ self.assert_(isinstance(item, QGraphicsTextItem))
+
+ def testWidget(self):
+ #QGraphicsScene.addWidget
+ # XXX: printing some X11 error when using under PyQt4
+ item = self.scene.addWidget(QPushButton())
+ self.assert_(isinstance(item, QGraphicsProxyWidget))
+
+
+class ItemRetrieve(UsesQApplication):
+ '''Tests for QGraphicsScene item retrieval methods'''
+
+ qapplication = True
+
+ def setUp(self):
+ #Acquire resources
+ super(ItemRetrieve, self).setUp()
+ self.scene = QGraphicsScene()
+
+ self.topleft = QGraphicsRectItem(0, 0, 100, 100)
+ self.topright = QGraphicsRectItem(100, 0, 100, 100)
+ self.bottomleft = QGraphicsRectItem(0, 100, 100, 100)
+ self.bottomright = QGraphicsRectItem(100, 100, 100, 100)
+
+ self.items = [self.topleft, self.topright, self.bottomleft,
+ self.bottomright]
+
+ for item in self.items:
+ self.scene.addItem(item)
+
+ def tearDown(self):
+ #Release resources
+ del self.scene
+ super(ItemRetrieve, self).tearDown()
+
+ def testItems(self):
+ #QGraphicsScene.items()
+ items = self.scene.items()
+ self.assertEqual(items, self.items)
+
+ def testItemAt(self):
+ #QGraphicsScene.itemAt()
+ self.assertEqual(self.scene.itemAt(50, 50), self.topleft)
+ self.assertEqual(self.scene.itemAt(150, 50), self.topright)
+ self.assertEqual(self.scene.itemAt(50, 150), self.bottomleft)
+ self.assertEqual(self.scene.itemAt(150, 150), self.bottomright)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qlabel_pixmap_refcount.py b/tests/qtgui/qlabel_pixmap_refcount.py
new file mode 100644
index 000000000..db8783e98
--- /dev/null
+++ b/tests/qtgui/qlabel_pixmap_refcount.py
@@ -0,0 +1,46 @@
+
+'''Test cases for QLabel->pixmap refcount control'''
+
+import unittest
+import sys
+
+
+from helper import UsesQApplication
+from PySide.QtGui import QApplication, QLabel, QPixmap
+
+class QLabelTest(UsesQApplication):
+ '''Test case for constructor of QBrush'''
+
+ def testDestroyOwner(self):
+ p = QPixmap()
+ l = QLabel()
+ l.setPixmap(p)
+
+ del p
+
+ p1 = l.pixmap()
+ self.assertEqual(sys.getrefcount(p1), 2)
+ self.assertEqual(sys.getrefcount(l), 2)
+
+ del l
+ self.assertEqual(sys.getrefcount(p1), 2)
+
+
+ def testRefCount(self):
+ p = QPixmap()
+ l = QLabel()
+ l.setPixmap(p)
+
+ del p
+
+ p1 = l.pixmap()
+ self.assertEqual(sys.getrefcount(p1), 2)
+
+ p2 = l.pixmap()
+ self.assertEqual(sys.getrefcount(p2), 3)
+
+ p3 = l.pixmap()
+ self.assertEqual(sys.getrefcount(p3), 4)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qlayout_ref_test.py b/tests/qtgui/qlayout_ref_test.py
new file mode 100644
index 000000000..a8e924f14
--- /dev/null
+++ b/tests/qtgui/qlayout_ref_test.py
@@ -0,0 +1,96 @@
+
+'''Test cases for QLayout handling of child widgets references'''
+
+import unittest
+from sys import getrefcount
+
+from PySide.QtGui import QHBoxLayout, QVBoxLayout, QGridLayout
+from PySide.QtGui import QStackedLayout, QFormLayout
+from PySide.QtGui import QApplication, QPushButton, QLabel
+
+from helper import UsesQApplication
+
+class SaveReference(UsesQApplication):
+ '''Test case to check if QLayout-derived classes increment the refcount
+ of widgets passed to addWidget()'''
+
+ # Adding here as nose can't see the qapplication attrib we inherit
+ qapplication = True
+
+ def setUp(self):
+ #Acquire resources
+ super(SaveReference, self).setUp()
+ self.widget1 = QPushButton('click me')
+ self.widget2 = QLabel('aaa')
+
+ def tearDown(self):
+ #Release resources
+ del self.widget2
+ del self.widget1
+ super(SaveReference, self).tearDown()
+
+ def checkLayoutReference(self, layout):
+ #Checks the reference cound handling of layout.addWidget
+ self.assertEqual(getrefcount(self.widget1), 2)
+ layout.addWidget(self.widget1)
+ self.assertEqual(getrefcount(self.widget1), 3)
+
+ self.assertEqual(getrefcount(self.widget2), 2)
+ layout.addWidget(self.widget2)
+ self.assertEqual(getrefcount(self.widget2), 3)
+
+ # Check if doesn't mess around with previous widget refcount
+ self.assertEqual(getrefcount(self.widget1), 3)
+
+ def testHBoxReference(self):
+ #QHBoxLayout.addWidget reference count
+ self.checkLayoutReference(QHBoxLayout())
+
+ def testVBoxReference(self):
+ #QVBoxLayout.addWidget reference count
+ self.checkLayoutReference(QVBoxLayout())
+
+ def testGridReference(self):
+ #QGridLayout.addWidget reference count
+ self.checkLayoutReference(QGridLayout())
+
+ def testFormReference(self):
+ #QFormLayout.addWidget reference count
+ self.checkLayoutReference(QFormLayout())
+
+ def testStackedReference(self):
+ #QStackedLayout.addWidget reference count
+ self.checkLayoutReference(QStackedLayout())
+
+
+class MultipleAdd(UsesQApplication):
+ '''Test case to check if refcount is incremented only once when multiple
+ calls to addWidget are made with the same widget'''
+
+ qapplication = True
+
+ def setUp(self):
+ #Acquire resources
+ super(MultipleAdd, self).setUp()
+ self.widget = QPushButton('click me')
+ self.layout = QHBoxLayout()
+
+ def tearDown(self):
+ #Release resources
+ del self.widget
+ del self.layout
+ super(MultipleAdd, self).tearDown()
+
+ def testRefCount(self):
+ #Multiple QLayout.addWidget calls on the same widget
+ self.assertEqual(getrefcount(self.widget), 2)
+ self.layout.addWidget(self.widget)
+ self.assertEqual(getrefcount(self.widget), 3)
+ self.layout.addWidget(self.widget)
+ self.assertEqual(getrefcount(self.widget), 3)
+ self.layout.addWidget(self.widget)
+ self.assertEqual(getrefcount(self.widget), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qlayout_test.py b/tests/qtgui/qlayout_test.py
new file mode 100644
index 000000000..ae773bb0a
--- /dev/null
+++ b/tests/qtgui/qlayout_test.py
@@ -0,0 +1,52 @@
+import unittest
+import sys
+
+from helper import UsesQApplication
+from PySide.QtGui import QLayout, QWidget, QPushButton, QWidgetItem
+
+class MyLayout(QLayout):
+ def __init__(self, parent=None):
+ QLayout.__init__(self, parent)
+ self._list = []
+
+ def addItem(self, item):
+ self.add(item)
+
+ def addWidget(self, widget):
+ self.add(QWidgetItem(widget))
+
+ def itemAt(self, index):
+ if index < len(self._list):
+ return self._list[index]
+
+ return None
+
+ def count(self):
+ return len(self._list)
+
+ def add(self, item):
+ self._list.append(item)
+
+
+
+#Test if a layout implemented in python, the QWidget.setLayout works
+#fine because this implement som layout functions used in glue code of
+#QWidget, then in c++ when call a virtual function this need call the QLayout
+#function implemented in python
+
+class QLayoutTest(UsesQApplication):
+
+ def testOwnershipTransfer(self):
+ b = QPushButton("teste")
+ l = MyLayout()
+ l.addWidget(b)
+
+ self.assertEqual(sys.getrefcount(b), 2)
+
+ w = QWidget()
+ w.setLayout(l)
+
+ self.assertEqual(sys.getrefcount(b), 3)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qlcdnumber_test.py b/tests/qtgui/qlcdnumber_test.py
new file mode 100644
index 000000000..eb6a4f396
--- /dev/null
+++ b/tests/qtgui/qlcdnumber_test.py
@@ -0,0 +1,16 @@
+import unittest
+
+from PySide.QtGui import QApplication, QLCDNumber
+
+class QLCDNumberOverflow(unittest.TestCase):
+ '''Test case for unhandled overflow on QLCDNumber() numDigits argument (see bug #215).'''
+
+ def setUp(self):
+ self.app = QApplication([])
+
+ def testnumDigitsOverflow(self):
+ # NOTE: PyQt4 raises TypeError, but boost.python raises OverflowError
+ self.assertRaises(OverflowError, QLCDNumber, 840835495615213080)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qlistwidgetitem_test.py b/tests/qtgui/qlistwidgetitem_test.py
new file mode 100644
index 000000000..8f96c518f
--- /dev/null
+++ b/tests/qtgui/qlistwidgetitem_test.py
@@ -0,0 +1,25 @@
+
+import unittest
+
+from PySide import QtGui
+
+from helper import UsesQApplication
+
+class QListWidgetItemConstructor(UsesQApplication):
+
+ def setUp(self):
+ super(QListWidgetItemConstructor, self).setUp()
+ self.widgetList = QtGui.QListWidget()
+
+ def tearDown(self):
+ del self.widgetList
+ super(QListWidgetItemConstructor, self).tearDown()
+
+ def testConstructorWithParent(self):
+ # Bug 235 - QListWidgetItem constructor not saving ownership
+ QtGui.QListWidgetItem(self.widgetList)
+ item = self.widgetList.item(0)
+ self.assertEqual(item.listWidget(), self.widgetList)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qmainwindow_test.py b/tests/qtgui/qmainwindow_test.py
new file mode 100644
index 000000000..fce145d53
--- /dev/null
+++ b/tests/qtgui/qmainwindow_test.py
@@ -0,0 +1,32 @@
+import unittest
+import sys
+
+from PySide import QtGui
+from PySide import QtCore
+
+from helper import UsesQApplication
+
+class MainWindow(QtGui.QMainWindow):
+ def __init__(self):
+ QtGui.QMainWindow.__init__(self)
+
+ self.createToolbar()
+
+ def createToolbar(self):
+ pointerButton = QtGui.QToolButton()
+ pointerToolbar = self.addToolBar("Pointer type")
+ pointerToolbar.addWidget(pointerButton)
+
+
+class TestMainWindow(UsesQApplication):
+
+ def testCreateToolbar(self):
+ w = MainWindow()
+ w.show()
+ QtCore.QTimer.singleShot(1000, self.app.quit)
+ self.app.exec_()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/qmenu_test.py b/tests/qtgui/qmenu_test.py
new file mode 100644
index 000000000..37faf1613
--- /dev/null
+++ b/tests/qtgui/qmenu_test.py
@@ -0,0 +1,58 @@
+
+import unittest
+
+from PySide.QtGui import QMenu, QKeySequence, QIcon
+from PySide.QtCore import SLOT
+
+from helper import UsesQApplication
+
+class QMenuAddAction(UsesQApplication):
+
+ def setUp(self):
+ super(QMenuAddAction, self).setUp()
+ self.menu = QMenu()
+
+ def tearDown(self):
+ del self.menu
+ super(QMenuAddAction, self).tearDown()
+
+ def testAddActionWithoutKeySequenceCallable(self):
+ # bug #280
+ action = self.menu.addAction(self.app.tr('aaa'), lambda : 1)
+
+ def testAddActionKeySequenceCallable(self):
+ # bug #228
+ action = self.menu.addAction(self.app.tr('aaa'), lambda : 1,
+ QKeySequence(self.app.tr('Ctrl+O')))
+
+ def testAddActionKeySequenceSlot(self):
+ action = self.menu.addAction('Quit', self.app, SLOT('quit()'),
+ QKeySequence('Ctrl+O'))
+
+class QMenuAddActionWithIcon(UsesQApplication):
+
+ def setUp(self):
+ super(QMenuAddActionWithIcon, self).setUp()
+ self.menu = QMenu()
+ self.icon = QIcon()
+
+ def tearDown(self):
+ del self.menu
+ del self.icon
+ super(QMenuAddActionWithIcon, self).tearDown()
+
+ def testAddActionWithoutKeySequenceCallable(self):
+ # bug #280
+ action = self.menu.addAction(self.icon, self.app.tr('aaa'), lambda : 1)
+
+ def testAddActionKeySequenceCallable(self):
+ # bug #228
+ action = self.menu.addAction(self.icon, self.app.tr('aaa'), lambda : 1,
+ QKeySequence(self.app.tr('Ctrl+O')))
+
+ def testAddActionKeySequenceSlot(self):
+ action = self.menu.addAction(self.icon, 'Quit', self.app, SLOT('quit()'),
+ QKeySequence('Ctrl+O'))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qpainter_test.py b/tests/qtgui/qpainter_test.py
new file mode 100644
index 000000000..a51d87d64
--- /dev/null
+++ b/tests/qtgui/qpainter_test.py
@@ -0,0 +1,31 @@
+import unittest
+
+from PySide.QtGui import QPainter
+from PySide.QtCore import QRect, Qt
+
+class QPainterDrawText(unittest.TestCase):
+
+ def setUp(self):
+ self.painter = QPainter()
+ self.text = 'teste!'
+
+ def tearDown(self):
+ del self.text
+ del self.painter
+
+ def testDrawText(self):
+ # bug #254
+ rect = self.painter.drawText(100, 100, 100, 100,
+ Qt.AlignCenter | Qt.TextWordWrap,
+ self.text)
+ self.assertNotEqual(rect, None)
+
+ def testDrawTextWithRect(self):
+ # bug #225
+ rect = QRect(100, 100, 100, 100)
+ self.painter.drawText(rect, Qt.AlignCenter | Qt.TextWordWrap,
+ self.text)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/qpixmap_test.py b/tests/qtgui/qpixmap_test.py
new file mode 100644
index 000000000..1bff9fff3
--- /dev/null
+++ b/tests/qtgui/qpixmap_test.py
@@ -0,0 +1,16 @@
+import unittest
+
+from helper import UsesQApplication
+from PySide.QtGui import QPixmap
+from PySide.QtCore import QVariant
+
+#Only test if is possible create a QPixmap from a QVariant
+class QPixmapTest(UsesQApplication):
+ def testQVariantConstructor(self):
+ pixmap = QPixmap()
+ v = QVariant(pixmap)
+ pixmap_copy = QPixmap(v)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/qpushbutton_test.py b/tests/qtgui/qpushbutton_test.py
new file mode 100644
index 000000000..984960879
--- /dev/null
+++ b/tests/qtgui/qpushbutton_test.py
@@ -0,0 +1,30 @@
+import unittest
+
+from helper import UsesQApplication
+from PySide.QtGui import QPushButton, QMenu, QWidget
+from PySide.QtCore import QTimer
+
+class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ m = QMenu(self)
+ b = QPushButton("Hello", self)
+ b.setMenu(m)
+
+
+class QPushButtonTest(UsesQApplication):
+ def createMenu(self, button):
+ m = QMenu()
+ button.setMenu(m)
+
+ def testSetMenu(self):
+ w = MyWidget()
+ w.show()
+
+ timer = QTimer.singleShot(100, self.app.quit)
+ self.app.exec_()
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/qregion_test.py b/tests/qtgui/qregion_test.py
new file mode 100644
index 000000000..2274d5e92
--- /dev/null
+++ b/tests/qtgui/qregion_test.py
@@ -0,0 +1,21 @@
+import unittest
+import sys
+
+from PySide.QtGui import QRegion
+from PySide.QtCore import QPoint
+from helper import UsesQApplication
+
+class QRegionTest(UsesQApplication):
+
+ def testFunctionUnit(self):
+ r = QRegion(0, 0, 10, 10)
+ r2 = QRegion(5, 5, 10, 10)
+
+ ru = r.united(r2)
+ self.assert_(ru.contains(QPoint(0,0)))
+ self.assert_(ru.contains(QPoint(5,5)))
+ self.assert_(ru.contains(QPoint(10,10)))
+ self.assert_(ru.contains(QPoint(14,14)))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qshortcut_test.py b/tests/qtgui/qshortcut_test.py
new file mode 100644
index 000000000..c08cf217c
--- /dev/null
+++ b/tests/qtgui/qshortcut_test.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+''' Test the QShortcut constructor'''
+
+import unittest
+import sys
+
+from PySide import QtGui, QtCore
+
+class Foo(QtGui.QWidget):
+ def __init__(self):
+ QtGui.QWidget.__init__(self)
+ self.ok = False
+
+ def slot_of_foo(self):
+ self.ok = True
+
+class MyShortcut(QtGui.QShortcut):
+ def __init__(self, keys, wdg, slot):
+ QtGui.QShortcut.__init__(self, keys, wdg, slot)
+
+ def emit_signal(self):
+ self.emit(QtCore.SIGNAL("activated()"))
+
+class QAppPresence(unittest.TestCase):
+
+ def testQShortcut(self):
+ self.qapp = QtGui.QApplication([])
+ f = Foo()
+
+ self.sc = MyShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Return), f, f.slot_of_foo)
+ QtCore.QTimer.singleShot(0, self.init);
+ self.qapp.exec_()
+ self.assertEquals(f.ok, True)
+
+ def init(self):
+ self.sc.emit_signal();
+ self.qapp.quit()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qstandarditemmodel_test.py b/tests/qtgui/qstandarditemmodel_test.py
new file mode 100644
index 000000000..d83d856da
--- /dev/null
+++ b/tests/qtgui/qstandarditemmodel_test.py
@@ -0,0 +1,26 @@
+import unittest
+
+from PySide.QtGui import *
+from PySide.QtCore import *
+
+from helper import UsesQApplication
+
+class QStandardItemModelTest(UsesQApplication):
+
+ def setUp(self):
+ super(QStandardItemModelTest, self).setUp()
+ self.window = QWidget()
+ self.model = QStandardItemModel(0, 3, self.window)
+
+ def tearDown(self):
+ del self.window
+ del self.model
+ super(QStandardItemModelTest, self).tearDown()
+
+ def testInsertRow(self):
+ # bug #227
+ self.model.insertRow(0)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/qstyle_test.py b/tests/qtgui/qstyle_test.py
new file mode 100644
index 000000000..c4a55d67d
--- /dev/null
+++ b/tests/qtgui/qstyle_test.py
@@ -0,0 +1,14 @@
+
+import unittest
+
+from PySide.QtGui import QPixmap, QStyle
+
+from helper import UsesQApplication
+
+class StandardPixmap(UsesQApplication):
+ def testDefaultOptions(self): # Bug 253
+ pixmap = self.app.style().standardPixmap(QStyle.SP_DirClosedIcon)
+ self.assert_(isinstance(pixmap, QPixmap))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qtabwidget_test.py b/tests/qtgui/qtabwidget_test.py
new file mode 100644
index 000000000..143f99cab
--- /dev/null
+++ b/tests/qtgui/qtabwidget_test.py
@@ -0,0 +1,21 @@
+
+import unittest
+
+from PySide.QtGui import QTabWidget
+from helper import TimedQApplication
+
+class RemoveTabMethod(TimedQApplication):
+ def setUp(self):
+ TimedQApplication.setUp(self)
+ self.tab = QTabWidget()
+
+ def tearDown(self):
+ del self.tab
+ TimedQApplication.tearDown(self)
+
+
+ def testRemoveTabPresence(self):
+ self.assert_(getattr(self.tab, 'removeTab'))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qtoolbar_test.py b/tests/qtgui/qtoolbar_test.py
new file mode 100644
index 000000000..1bcf566db
--- /dev/null
+++ b/tests/qtgui/qtoolbar_test.py
@@ -0,0 +1,35 @@
+
+'''Test cases for QToolbar'''
+
+import unittest
+
+from PySide.QtGui import QToolBar, QMainWindow, QAction
+
+from helper import UsesQApplication
+
+class AddActionText(UsesQApplication):
+ '''Test case for calling QToolbar.addAction passing a text'''
+
+ def setUp(self):
+ #Acquire resources
+ super(AddActionText, self).setUp()
+ self.window = QMainWindow()
+ self.toolbar = QToolBar()
+ self.window.addToolBar(self.toolbar)
+
+ def tearDown(self):
+ #Release resources
+ super(AddActionText, self).tearDown()
+ del self.toolbar
+ del self.window
+
+ def testText(self):
+ #QToolBar.addAction(text) - add a QToolButton
+ self.toolbar.addAction('aaaa')
+ self.assertEqual(len(self.toolbar.actions()), 1)
+ action = self.toolbar.actions()[0]
+ self.assert_(isinstance(action, QAction))
+ self.assertEqual(action.text(), 'aaaa')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qtoolbox_test.py b/tests/qtgui/qtoolbox_test.py
new file mode 100644
index 000000000..dd0d2c6a5
--- /dev/null
+++ b/tests/qtgui/qtoolbox_test.py
@@ -0,0 +1,31 @@
+
+import unittest
+
+from PySide.QtGui import QToolBox, QWidget, QIcon
+
+from helper import UsesQApplication
+
+class OwnershipControl(UsesQApplication):
+
+ def setUp(self):
+ super(OwnershipControl, self).setUp()
+ self.toolbox = QToolBox()
+
+ def tearDown(self):
+ del self.toolbox
+ super(OwnershipControl, self).tearDown()
+
+ def testAddItem(self):
+ # Was losing ownership of the widget.
+ index = self.toolbox.addItem(QWidget(), 'item')
+ item = self.toolbox.widget(index)
+ self.assert_(isinstance(item, QWidget))
+
+ def testAddItemWithIcon(self):
+ index = self.toolbox.addItem(QWidget(), QIcon(), 'item')
+ item = self.toolbox.widget(index)
+ self.assert_(isinstance(item, QWidget))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qvariant_test.py b/tests/qtgui/qvariant_test.py
new file mode 100644
index 000000000..052e67d71
--- /dev/null
+++ b/tests/qtgui/qvariant_test.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QVariant with QtGui types'''
+
+import unittest
+
+from PySide.QtCore import *
+from PySide.QtGui import *
+
+class Dummy(object):
+ pass
+
+class QVariantTypeName(unittest.TestCase):
+ def testQPen(self):
+ obj = QVariant(QPen(Qt.red))
+ self.assertEqual('QPen', obj.typeName())
+
+ def testQColor(self):
+ obj = QVariant(QColor(Qt.red))
+ self.assertEqual('QColor', obj.typeName())
+
+ def testGlobalColor(self):
+ obj = QVariant(Qt.red)
+ # XXX: PyQt4 returns int instead of QColor like the C++ version
+ self.assertEqual('QColor', obj.typeName())
+
+ def testEnums(self):
+ obj = QVariant(Qt.SolidLine)
+ self.assertEqual('int', obj.typeName())
+
+class QVariantQColorImplicitlyConvertion(unittest.TestCase):
+ def testConversions(self):
+ c1 = QColor(0, 0, 0)
+ v = QVariant(c1)
+ c2 = QColor(v)
+ self.assertEqual(c1, c2)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/qwidget_setlayout_test.py b/tests/qtgui/qwidget_setlayout_test.py
new file mode 100644
index 000000000..c715396ed
--- /dev/null
+++ b/tests/qtgui/qwidget_setlayout_test.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+import unittest
+
+from PySide.QtGui import QWidget, QVBoxLayout, QPushButton, QApplication, QHBoxLayout
+from helper import UsesQApplication
+
+class QWidgetTest(UsesQApplication):
+
+ def test_setLayout(self):
+ layout = QVBoxLayout()
+ btn1 = QPushButton("button_v1")
+ layout.addWidget(btn1)
+
+ btn2 = QPushButton("button_v2")
+ layout.addWidget(btn2)
+
+ layout2 = QHBoxLayout()
+
+ btn1 = QPushButton("button_h1")
+ layout2.addWidget(btn1)
+
+ btn2 = QPushButton("button_h2")
+ layout2.addWidget(btn2)
+
+ layout.addLayout(layout2)
+
+ widget = QWidget()
+ widget.setLayout(layout)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/qwidget_test.py b/tests/qtgui/qwidget_test.py
new file mode 100644
index 000000000..288db372a
--- /dev/null
+++ b/tests/qtgui/qwidget_test.py
@@ -0,0 +1,18 @@
+
+import unittest
+
+from PySide.QtGui import QWidget
+from helper import UsesQApplication
+
+class QWidgetVisible(UsesQApplication):
+
+ def testBasic(self):
+ # Also related to bug #244, on existence of setVisible'''
+ widget = QWidget()
+ self.assert_(not widget.isVisible())
+ widget.setVisible(True)
+ self.assert_(widget.isVisible())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/reference_count_test.py b/tests/qtgui/reference_count_test.py
new file mode 100644
index 000000000..b54986821
--- /dev/null
+++ b/tests/qtgui/reference_count_test.py
@@ -0,0 +1,71 @@
+
+'''Test cases for Reference count when the object is created in c++ side'''
+
+import unittest
+
+import sys
+import weakref
+import gc
+
+
+from PySide.QtCore import Qt, QPointF
+from PySide.QtGui import QApplication, QGraphicsScene, QGraphicsRectItem, QPolygonF, QGraphicsPolygonItem, QGraphicsRectItem
+
+from helper import UsesQApplication
+
+destroyedRect = False
+destroyedPol = False
+
+def rect_del(o):
+ global destroyedRect
+ destroyedRect = True
+
+def pol_del(o):
+ global destroyedPol
+ destroyedPol = True
+
+class ReferenceCount(UsesQApplication):
+
+ def setUp(self):
+ super(ReferenceCount, self).setUp()
+ self.scene = QGraphicsScene()
+
+ def tearDown(self):
+ super(ReferenceCount, self).tearDown()
+
+ def beforeTest(self):
+ points = [QPointF(0, 0), QPointF(100, 100), QPointF(0, 100)]
+ pol = self.scene.addPolygon(QPolygonF(points))
+ self.assert_(isinstance(pol, QGraphicsPolygonItem))
+ self.wrp = weakref.ref(pol, pol_del)
+
+ #refcount need be 3 because one ref for QGraphicsScene, and one to rect obj
+ self.assertEqual(sys.getrefcount(pol), 3)
+
+ def testReferenceCount(self):
+ global destroyedRect
+ global destroyedPol
+
+ self.beforeTest()
+
+ rect = self.scene.addRect(10.0, 10.0, 10.0, 10.0)
+ self.assert_(isinstance(rect, QGraphicsRectItem))
+
+ self.wrr = weakref.ref(rect, rect_del)
+
+ #refcount need be 3 because one ref for QGraphicsScene, and one to rect obj
+ self.assertEqual(sys.getrefcount(rect), 3)
+
+ del rect
+ #not destroyed because one ref continue in QGraphicsScene
+ self.assertEqual(destroyedRect, False)
+ self.assertEqual(destroyedPol, False)
+
+ del self.scene
+
+ #QGraphicsScene was destroyed and this destroy internal ref to rect
+ self.assertEqual(destroyedRect, True)
+ self.assertEqual(destroyedPol, True)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/timed_app_test.py b/tests/qtgui/timed_app_test.py
new file mode 100644
index 000000000..4af9a0130
--- /dev/null
+++ b/tests/qtgui/timed_app_test.py
@@ -0,0 +1,14 @@
+
+import unittest
+
+from helper import TimedQApplication
+
+class TestTimedApp(TimedQApplication):
+ '''Simple test case for TimedQApplication'''
+
+ def testFoo(self):
+ #Simple test of TimedQApplication
+ self.app.exec_()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtgui/virtual_protected_inheritance_test.py b/tests/qtgui/virtual_protected_inheritance_test.py
new file mode 100644
index 000000000..15de37dfb
--- /dev/null
+++ b/tests/qtgui/virtual_protected_inheritance_test.py
@@ -0,0 +1,70 @@
+
+'''Test cases for overriding inherited protected virtual methods'''
+
+import unittest
+
+from PySide.QtCore import QTimerEvent
+from PySide.QtGui import QApplication, QSpinBox
+
+from helper import UsesQApplication
+
+class MySpinButton(QSpinBox):
+ '''Simple example class of overriding QObject.timerEvent'''
+
+ def __init__(self, max_runs=5, app=None):
+ #Creates a new spinbox that will run <max_runs> and quit <app>
+ super(MySpinButton, self).__init__()
+
+ if app is None:
+ app = QApplication([])
+
+ self.app = app
+ self.max_runs = max_runs
+ self.runs = 0
+
+ def timerEvent(self, event):
+ #Timer event method
+ self.runs += 1
+
+ self.setValue(self.runs)
+
+ if self.runs == self.max_runs:
+ self.app.quit()
+
+ if not isinstance(event, QTimerEvent):
+ raise TypeError('Invalid event type. Must be TimerEvent')
+
+class TimerEventTest(UsesQApplication):
+ '''Test case for running QObject.timerEvent from inherited class'''
+
+ qapplication = True
+
+ def setUp(self):
+ #Acquire resources
+ super(TimerEventTest, self).setUp()
+ self.widget = MySpinButton(app=self.app)
+
+ def tearDown(self):
+ #Release resources
+ del self.widget
+ super(TimerEventTest, self).tearDown()
+
+ def testMethod(self):
+ #QWidget.timerEvent overrinding (protected inherited)
+ timer_id = self.widget.startTimer(0)
+
+ self.app.exec_()
+
+ self.widget.killTimer(timer_id)
+
+ self.assertEqual(self.widget.runs, 5)
+
+
+if __name__ == '__main__':
+ unittest.main()
+ #app = QApplication([])
+ #widget = MySpinButton(app=app)
+ #widget.startTimer(500)
+ #widget.show()
+ #app.exec_()
+
diff --git a/tests/qtgui/virtual_pure_override.py b/tests/qtgui/virtual_pure_override.py
new file mode 100644
index 000000000..c496e4907
--- /dev/null
+++ b/tests/qtgui/virtual_pure_override.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+import unittest
+
+from PySide.QtGui import QGraphicsScene, QGraphicsRectItem, QGraphicsView, QApplication, QBrush, QColor
+from PySide.QtCore import QTimer
+from helper import UsesQApplication
+
+qgraphics_item_painted = False
+
+class RoundRectItem(QGraphicsRectItem):
+
+ def __init__(self, x, y, w, h):
+ QGraphicsRectItem.__init__(self, x, y, w, h)
+
+ def paint(self, painter, qstyleoptiongraphicsitem, qwidget):
+ global qgraphics_item_painted
+ qgraphics_item_painted = True
+
+
+class QGraphicsItemTest(UsesQApplication):
+
+ def createRoundRect(self, scene):
+ item = RoundRectItem(10, 10, 100, 100)
+ item.setBrush(QBrush(QColor(255, 0, 0)))
+ scene.addItem(item)
+ return item
+
+ def quit_app(self):
+ self.app.quit()
+
+ def test_setParentItem(self):
+ global qgraphics_item_painted
+
+ scene = QGraphicsScene()
+ scene.addText("test")
+ view = QGraphicsView(scene)
+
+ rect = self.createRoundRect(scene)
+ view.show()
+ QTimer.singleShot(1000, self.quit_app)
+ self.app.exec_()
+ self.assert_(qgraphics_item_painted)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtgui/x11_symbols.py b/tests/qtgui/x11_symbols.py
new file mode 100644
index 000000000..29cce150e
--- /dev/null
+++ b/tests/qtgui/x11_symbols.py
@@ -0,0 +1,17 @@
+
+''' Test the presence of X11 symbols in QtGui'''
+
+import unittest
+
+from PySide.QtGui import QPixmap
+
+class X11Test(unittest.TestCase):
+
+ def test(self):
+ self.assert_('handle' in dir(QPixmap))
+ self.assert_('x11Info' in dir(QPixmap))
+ self.assert_('x11PictureHandle' in dir(QPixmap))
+ self.assert_('x11SetDefaultScreen' in dir(QPixmap))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qthelp/test_help.py b/tests/qthelp/test_help.py
new file mode 100644
index 000000000..e2ff532a6
--- /dev/null
+++ b/tests/qthelp/test_help.py
@@ -0,0 +1,14 @@
+
+import unittest
+
+from PySide.QtHelp import QHelpEngine
+
+from helper import UsesQApplication
+
+class QHelpEngineCreation(UsesQApplication):
+
+ def testConstructor(self):
+ helpEngine = QHelpEngine('mycollection.qch')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtnetwork/http_test.py b/tests/qtnetwork/http_test.py
new file mode 100644
index 000000000..28564f5a0
--- /dev/null
+++ b/tests/qtnetwork/http_test.py
@@ -0,0 +1,48 @@
+
+'''Test cases for QHttp'''
+
+import unittest
+
+from PySide.QtCore import *
+from PySide.QtNetwork import *
+
+from helper import UsesQApplication
+
+class HttpSignalsCase(UsesQApplication):
+ '''Test case for launching QHttp signals'''
+
+ def setUp(self):
+ super(HttpSignalsCase, self).setUp()
+
+ self.http = QHttp()
+ self.url = QUrl('http://www.google.com')
+ self.timer = QTimer.singleShot(250, self.app.quit)
+
+ def tearDown(self):
+ del self.http
+ super(HttpSignalsCase, self).tearDown()
+
+ def callback(self, ident):
+ self.called = True
+
+ def testDefaultArgs(self):
+ #QHttp signal requestStarted signal
+ # @bug 114
+ QObject.connect(self.http, SIGNAL('requestStarted(int)'), self.callback)
+ self.http.get(self.url.path())
+
+ self.app.exec_()
+ self.assert_(self.called)
+
+class testHttp(UsesQApplication):
+ def testRead(self):
+ header = QHttpRequestHeader("GET", QString(QUrl.toPercentEncoding("/index.html")))
+ header.setValue("Host", "qtsoftware.com");
+ http = QHttp()
+ http.setHost("qtsoftware.com")
+ http.request(header)
+ data = http.read(100)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtnetwork/tcpserver_test.py b/tests/qtnetwork/tcpserver_test.py
new file mode 100644
index 000000000..77f830e36
--- /dev/null
+++ b/tests/qtnetwork/tcpserver_test.py
@@ -0,0 +1,25 @@
+
+'''Test cases for QTCPServer'''
+
+import unittest
+
+from PySide.QtNetwork import QTcpServer
+
+class ListenDefaultArgsCase(unittest.TestCase):
+ '''Test case for TcpServer.listen with default args'''
+
+ def setUp(self):
+ #Acquire resources
+ self.server = QTcpServer()
+
+ def tearDown(self):
+ #Release resources
+ del self.server
+
+ def testDefaultArgs(self):
+ # @bug 108
+ #Default arguments for QTcpServer.listen
+ self.server.listen()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtnetwork/udpsocket_test.py b/tests/qtnetwork/udpsocket_test.py
new file mode 100644
index 000000000..26cff7f65
--- /dev/null
+++ b/tests/qtnetwork/udpsocket_test.py
@@ -0,0 +1,54 @@
+
+'''Test cases for QUdpSocket'''
+
+import unittest
+
+from PySide.QtCore import QUrl, QObject, SIGNAL, QCoreApplication, QTimer
+from PySide.QtNetwork import QUdpSocket, QHostAddress
+
+class HttpSignalsCase(unittest.TestCase):
+ '''Test case for bug #124 - readDatagram signature
+
+ QUdpSocket.readDatagram must return a tuple with the datagram, host and
+ port, while receiving only the max payload size.'''
+
+ def setUp(self):
+ #Acquire resources
+ self.app = QCoreApplication([])
+ self.socket = QUdpSocket()
+ self.socket.bind(45454)
+ self.server = QUdpSocket()
+ self.timer = QTimer.singleShot(1000, self.app.quit)
+ self.a = QTimer.singleShot(100, self.broadcast)
+ #self.a = QTimer()
+ #self.a.setInterval(100)
+ #QObject.connect(self.a, SIGNAL('timeout()'), self.broadcast)
+ #self.a.start()
+
+ def tearDown(self):
+ #Release resources
+ del self.socket
+ del self.server
+ del self.app
+
+ def broadcast(self):
+ addr = QHostAddress(QHostAddress.Broadcast)
+ self.server.writeDatagram('datagram', addr, 45454)
+
+ def callback(self):
+ while self.socket.hasPendingDatagrams():
+ datagram, host, port = self.socket.readDatagram(
+ self.socket.pendingDatagramSize())
+ self.called = True
+ self.app.quit()
+
+ def testDefaultArgs(self):
+ #QUdpSocket.readDatagram pythonic return
+ # @bug 124
+ QObject.connect(self.socket, SIGNAL('readyRead()'), self.callback)
+ self.app.exec_()
+
+ self.assert_(self.called)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtscript/test_base.py b/tests/qtscript/test_base.py
new file mode 100644
index 000000000..6ad27e007
--- /dev/null
+++ b/tests/qtscript/test_base.py
@@ -0,0 +1,4 @@
+from PySide import QtScript
+
+
+#only test if the module import works fine bug #278
diff --git a/tests/qtsql/qsqldatabaseandqueries_test.py b/tests/qtsql/qsqldatabaseandqueries_test.py
new file mode 100755
index 000000000..49f220937
--- /dev/null
+++ b/tests/qtsql/qsqldatabaseandqueries_test.py
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+'''Test cases for QtSql database creation, destruction and queries'''
+
+import sys
+import unittest
+
+from PySide import QtSql
+from PySide.QtCore import QVariant, QString
+
+class SqlDatabaseCreationDestructionAndQueries(unittest.TestCase):
+ '''Test cases for QtSql database creation, destruction and queries'''
+
+ def setUp(self):
+ #Acquire resources
+ self.assertFalse(QtSql.QSqlDatabase.drivers().isEmpty(), "installed Qt has no DB drivers")
+ self.assertTrue("QSQLITE" in QtSql.QSqlDatabase.drivers(), "\"QSQLITE\" driver not available in this Qt version")
+ self.db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
+ self.db.setDatabaseName(":memory:")
+ self.assertTrue(self.db.open())
+
+ def tearDown(self):
+ #Release resources
+ self.db.close()
+ QtSql.QSqlDatabase.removeDatabase(":memory:")
+ del self.db
+
+ def testTableCreationAndDestruction(self):
+ #Test table creation and destruction
+ query = QtSql.QSqlQuery()
+ query.exec_("CREATE TABLE dummy(id int primary key, dummyfield varchar(20))")
+ query.exec_("DROP TABLE dummy")
+ query.clear()
+
+ def testTableInsertionAndRetrieval(self):
+ #Test table creation, insertion and retrieval
+ query = QtSql.QSqlQuery()
+ query.exec_("CREATE TABLE person(id int primary key, "
+ "firstname varchar(20), lastname varchar(20))")
+ query.exec_("INSERT INTO person VALUES(101, 'George', 'Harrison')")
+ query.prepare("INSERT INTO person (id, firstname, lastname) "
+ "VALUES (:id, :firstname, :lastname)")
+ query.bindValue(":id", QVariant(102))
+ query.bindValue(":firstname", QVariant("John"))
+ query.bindValue(":lastname", QVariant("Lennon"))
+ query.exec_()
+
+ lastname = ''
+ query.exec_("SELECT lastname FROM person where id=101")
+ self.assertTrue(query.isActive())
+ query.next()
+ lastname = query.value(0).toString()
+ self.assertEqual(lastname, 'Harrison')
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/qtuitools/test_ui.py b/tests/qtuitools/test_ui.py
new file mode 100644
index 000000000..6f599cefb
--- /dev/null
+++ b/tests/qtuitools/test_ui.py
@@ -0,0 +1,14 @@
+
+import unittest
+
+from PySide.QtUiTools import QUiLoader
+
+from helper import UsesQApplication
+
+class QUiLoaderCreation(UsesQApplication):
+
+ def testConstructor(self):
+ loader = QUiLoader()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtwebkit/fox.html b/tests/qtwebkit/fox.html
new file mode 100644
index 000000000..e7691eb66
--- /dev/null
+++ b/tests/qtwebkit/fox.html
@@ -0,0 +1,6 @@
+<html>
+<title>Title</title>
+<body>
+<p>The quick <b>brown</b> fox <i>jumps</i> over the lazy dog.</p>
+</body>
+</html>
diff --git a/tests/qtwebkit/webpage_test.py b/tests/qtwebkit/webpage_test.py
new file mode 100644
index 000000000..ed98c9f8d
--- /dev/null
+++ b/tests/qtwebkit/webpage_test.py
@@ -0,0 +1,54 @@
+
+'''Test cases for QWebPage'''
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL, QUrl
+from PySide.QtWebKit import QWebPage
+from PySide.QtNetwork import QNetworkAccessManager
+
+from helper import adjust_filename, TimedQApplication
+
+class TestFindText(TimedQApplication):
+ '''Test cases for finding text'''
+
+ def setUp(self):
+ TimedQApplication.setUp(self, timeout=250)
+ self.page = QWebPage()
+ QObject.connect(self.page, SIGNAL('loadFinished(bool)'),
+ self.load_finished)
+ self.called = False
+
+ def tearDown(self):
+ #Release resources
+ del self.page
+ self.called = False
+ TimedQApplication.tearDown(self)
+
+ def testFindSelectText(self):
+ url = QUrl.fromLocalFile(adjust_filename('fox.html', __file__))
+ self.page.currentFrame().setUrl(url)
+ self.app.exec_()
+ self.assert_(self.called)
+
+ def load_finished(self, ok):
+ #Callback to check if load was successful
+ self.assert_(self.page.findText('fox'))
+ self.assertEqual(self.page.selectedText(), 'fox')
+ self.app.quit()
+ if ok:
+ self.called = True
+
+class SetNetworkAccessManaterCase(TimedQApplication):
+
+ def testSetNetworkAccessManager(self):
+ page = QWebPage()
+ manager = QNetworkAccessManager()
+ page.setNetworkAccessManager(manager)
+
+ def testNetWorkAccessManager(self):
+ page = QWebPage()
+ a = page.networkAccessManager()
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/qtwebkit/webview_test.py b/tests/qtwebkit/webview_test.py
new file mode 100644
index 000000000..176d4873e
--- /dev/null
+++ b/tests/qtwebkit/webview_test.py
@@ -0,0 +1,48 @@
+
+'''Test cases for QWebView'''
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL, QUrl
+from PySide.QtWebKit import QWebView
+
+from helper import adjust_filename, TimedQApplication
+
+
+class TestLoadFinished(TimedQApplication):
+ '''Test case for signal QWebView.loadFinished(bool)'''
+
+ def setUp(self):
+ #Acquire resources
+ TimedQApplication.setUp(self, timeout=250)
+ self.view = QWebView()
+ QObject.connect(self.view, SIGNAL('loadFinished(bool)'),
+ self.load_finished)
+ self.called = False
+
+ def tearDown(self):
+ #Release resources
+ del self.view
+ self.called = False
+ TimedQApplication.tearDown(self)
+
+ def testLoadFinishedFromFile(self):
+ url = QUrl.fromLocalFile(adjust_filename('fox.html', __file__))
+ self.view.setUrl(url)
+ self.app.exec_()
+
+ self.assert_(self.called)
+
+ def testLoadFinishedFromUrl(self):
+ url = QUrl('http://www.python.org')
+ self.view.setUrl(url)
+ self.app.exec_()
+
+ def load_finished(self, ok):
+ #Callback to check if load was successful
+ self.app.quit()
+ if ok:
+ self.called = True
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/run_test.sh b/tests/run_test.sh
new file mode 100755
index 000000000..85058c185
--- /dev/null
+++ b/tests/run_test.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+
+# This is a nasty workaround of a CTest limitation
+# of setting the environment variables for the test.
+
+# $1: LD_LIBRARY_PATH
+# $2: $PYTHON_PATH
+# $3: python executable
+# $4: test file
+
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$1
+export PYTHONPATH=$PYTHON_PATH:$2
+$3 $4
diff --git a/tests/signals/args_dont_match.py b/tests/signals/args_dont_match.py
new file mode 100644
index 000000000..b81c5682c
--- /dev/null
+++ b/tests/signals/args_dont_match.py
@@ -0,0 +1,21 @@
+
+import unittest
+from PySide.QtCore import *
+
+class ArgsDontMatch(unittest.TestCase):
+
+ def callback(self, arg1):
+ self.ok = True
+
+ def testConnectSignalToSlotWithLessArgs(self):
+ self.ok = False
+ obj1 = QObject()
+ QObject.connect(obj1, SIGNAL('the_signal(int, int, int)'), self.callback)
+ obj1.emit(SIGNAL('the_signal(int, int, int)'), 1, 2, 3)
+
+ self.assert_(self.ok)
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/invalid_callback_test.py b/tests/signals/invalid_callback_test.py
new file mode 100644
index 000000000..3328bb5c6
--- /dev/null
+++ b/tests/signals/invalid_callback_test.py
@@ -0,0 +1,29 @@
+
+'''Test cases for passing invalid callbacks to QObject.connect'''
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL
+
+class InvalidCallback(unittest.TestCase):
+ '''Test case for passing an invalid callback to QObject.connect'''
+
+ def setUp(self):
+ #Acquire resources
+ self.obj = QObject()
+
+ def tearDown(self):
+ #Release resources
+ try:
+ del self.obj
+ except AttributeError:
+ pass
+
+ def testIntegerCb(self):
+ #Test passing an int as callback to QObject.connect
+ self.assertRaises(TypeError, QObject.connect, self.obj,
+ SIGNAL('destroyed()'), 42)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/signals/lambda_test.py b/tests/signals/lambda_test.py
new file mode 100644
index 000000000..9a76ced09
--- /dev/null
+++ b/tests/signals/lambda_test.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+'''Connecting lambda to signals'''
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL
+from PySide.QtGui import QApplication, QSpinBox, QPushButton
+
+from helper import UsesQApplication
+
+class Dummy(QObject):
+ def __init__(self, *args):
+ super(Dummy, self).__init__(*args)
+
+class BasicCase(unittest.TestCase):
+
+ def testSimplePythonSignalNoArgs(self):
+ #Connecting a lambda to a simple python signal without arguments
+ obj = Dummy()
+ QObject.connect(obj, SIGNAL('foo()'), lambda : setattr(obj, 'called', True))
+ obj.emit(SIGNAL('foo()'))
+ self.assert_(obj.called)
+
+ def testSimplePythonSignal(self):
+ #Connecting a lambda to a simple python signal witharguments
+ obj = Dummy()
+ arg = 42
+ QObject.connect(obj, SIGNAL('foo(int)'), lambda x : setattr(obj, 'arg', 42))
+ obj.emit(SIGNAL('foo(int)'), arg)
+ self.assertEqual(obj.arg, arg)
+
+class QtSigLambda(UsesQApplication):
+
+ qapplication = True
+
+ def testButton(self):
+ #Connecting a lambda to a QPushButton.clicked()
+ obj = QPushButton('label')
+ QObject.connect(obj, SIGNAL('clicked()'), lambda : setattr(obj, 'called', True))
+ obj.click()
+ self.assert_(obj.called)
+
+ def testSpinButton(self):
+ #Connecting a lambda to a QPushButton.clicked()
+ obj = QSpinBox()
+ arg = 444
+ QObject.connect(obj, SIGNAL('valueChanged(int)'), lambda x: setattr(obj, 'arg', 444))
+ obj.setValue(444)
+ self.assertEqual(obj.arg, arg)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/multiple_connections_test.py b/tests/signals/multiple_connections_test.py
new file mode 100644
index 000000000..f8dab32d5
--- /dev/null
+++ b/tests/signals/multiple_connections_test.py
@@ -0,0 +1,65 @@
+
+import unittest
+import random
+
+from PySide.QtCore import QObject, SIGNAL
+from PySide.QtGui import QPushButton, QSpinBox, QApplication
+
+from helper import BasicPySlotCase, UsesQApplication
+
+def random_gen(count=100, largest=99, lowest=0):
+ for i in range(count):
+ yield random.randint(lowest, largest)
+
+class MultipleSignalConnections(UsesQApplication):
+
+ qapplication = True
+
+ def run_many(self, sender, signal, receivers, args=None):
+ """Utility method to connect a list of receivers to a signal.
+ sender - QObject that will emit the signal
+ signal - string with the signal signature
+ receivers - list of BasicPySlotCase instances
+ args - tuple with the arguments to be sent.
+ """
+
+ if args is None:
+ args = tuple()
+
+ for rec in receivers:
+ rec.setUp()
+ QObject.connect(sender, SIGNAL(signal), rec.cb)
+ rec.args = tuple(args)
+
+ sender.emit(SIGNAL(signal), *args)
+
+ for rec in receivers:
+ self.assert_(rec.called)
+
+ def testButtonClick(self):
+ """Multiple connections to QPushButton.clicked()"""
+ sender = QPushButton('button')
+ receivers = [BasicPySlotCase() for x in range(30)]
+ self.run_many(sender, 'clicked()', receivers)
+
+ def testSpinBoxValueChanged(self):
+ """Multiple connections to QSpinBox.valueChanged(int)"""
+ for test in random_gen(30):
+ sender = QSpinBox()
+ #FIXME if number of receivers if higher than 50, segfaults
+ receivers = [BasicPySlotCase() for x in range(10)]
+ self.run_many(sender, 'valueChanged(int)', receivers, (test,))
+
+ def testPythonSignal(self):
+ """Multiple connections to a python signal (short-circuit)"""
+ class Dummy(QObject):
+ pass
+
+ for test in random_gen(30):
+ sender = Dummy()
+ receivers = [BasicPySlotCase() for x in range(10)]
+ self.run_many(sender, 'foobar', receivers, (test, ))
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/signals/pysignal_test.py b/tests/signals/pysignal_test.py
new file mode 100644
index 000000000..923d8b782
--- /dev/null
+++ b/tests/signals/pysignal_test.py
@@ -0,0 +1,105 @@
+
+import unittest
+from PySide.QtCore import QObject, SIGNAL, SLOT
+from PySide.QtGui import QSpinBox, QApplication, QWidget
+
+class Dummy(QObject):
+ """Dummy class used in this test."""
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+class PythonSigSlot(unittest.TestCase):
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except:
+ pass
+
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testNoArgs(self):
+ """Python signal and slots without arguments"""
+ obj1 = Dummy()
+
+ QObject.connect(obj1, SIGNAL('foo()'), self.callback)
+ self.args = tuple()
+ obj1.emit(SIGNAL('foo()'), *self.args)
+
+ self.assert_(self.called)
+
+ def testWithArgs(self):
+ """Python signal and slots with integer arguments"""
+ obj1 = Dummy()
+
+ QObject.connect(obj1, SIGNAL('foo(int)'), self.callback)
+ self.args = (42,)
+ obj1.emit(SIGNAL('foo(int)'), *self.args)
+
+ self.assert_(self.called)
+
+app = QApplication([])
+
+class SpinBoxPySignal(unittest.TestCase):
+ """Tests the connection of python signals to QSpinBox qt slots."""
+
+ qapplication = True
+
+ def setUp(self):
+ self.obj = Dummy()
+ self.spin = QSpinBox()
+ self.spin.setValue(0)
+
+ def tearDown(self):
+ del self.obj
+ del self.spin
+
+ def testValueChanged(self):
+ """Emission of a python signal to QSpinBox setValue(int)"""
+ QObject.connect(self.obj, SIGNAL('dummy(int)'), self.spin, SLOT('setValue(int)'))
+ self.assertEqual(self.spin.value(), 0)
+
+ self.obj.emit(SIGNAL('dummy(int)'), 4)
+ self.assertEqual(self.spin.value(), 4)
+
+ def testValueChangedMultiple(self):
+ """Multiple emissions of a python signal to QSpinBox setValue(int)"""
+ QObject.connect(self.obj, SIGNAL('dummy(int)'), self.spin, SLOT('setValue(int)'))
+ self.assertEqual(self.spin.value(), 0)
+
+ self.obj.emit(SIGNAL('dummy(int)'), 4)
+ self.assertEqual(self.spin.value(), 4)
+
+ self.obj.emit(SIGNAL('dummy(int)'), 77)
+ self.assertEqual(self.spin.value(), 77)
+
+
+class WidgetPySignal(unittest.TestCase):
+ """Tests the connection of python signals to QWidget qt slots."""
+
+ qapplication = True
+
+ def setUp(self):
+ self.obj = Dummy()
+ self.widget = QWidget()
+
+ def tearDown(self):
+ del self.obj
+ del self.widget
+
+ def testShow(self):
+ """Emission of a python signal to QWidget slot show()"""
+ self.widget.hide()
+
+ QObject.connect(self.obj, SIGNAL('dummy()'), self.widget, SLOT('show()'))
+ self.assert_(not self.widget.isVisible())
+
+ self.obj.emit(SIGNAL('dummy()'))
+ self.assert_(self.widget.isVisible())
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/qobject_destroyed_test.py b/tests/signals/qobject_destroyed_test.py
new file mode 100644
index 000000000..01d1b5886
--- /dev/null
+++ b/tests/signals/qobject_destroyed_test.py
@@ -0,0 +1,23 @@
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL
+
+class QObjectDestroyed(unittest.TestCase):
+ """Very simple test case for the destroyed() signal of QObject"""
+
+ def setUp(self):
+ self.called = False
+
+ def destroyed_cb(self):
+ self.called = True
+
+ def testDestroyed(self):
+ """Emission of QObject.destroyed() to a python slot"""
+ obj = QObject()
+ QObject.connect(obj, SIGNAL('destroyed()'), self.destroyed_cb)
+ del obj
+ self.assert_(self.called)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/qobject_receivers_test.py b/tests/signals/qobject_receivers_test.py
new file mode 100644
index 000000000..e1d429ec6
--- /dev/null
+++ b/tests/signals/qobject_receivers_test.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+''' Test case for QObject.receivers()'''
+
+import unittest
+from PySide.QtCore import *
+
+def cute_slot():
+ pass
+
+class TestQObjectReceivers(unittest.TestCase):
+ '''Test case for QObject::receivers'''
+
+ def testBasic(self):
+ sender = QObject()
+ receiver1 = QObject()
+ receiver2 = QObject()
+ self.assertEqual(sender.receivers(SIGNAL("")), 0)
+ sender.connect(sender, SIGNAL("destroyed()"), receiver1, SLOT("deleteLater()"))
+ self.assertEqual(sender.receivers(SIGNAL("destroyed()")), 1)
+ sender.connect(sender, SIGNAL("destroyed()"), receiver2, SLOT("deleteLater()"))
+ self.assertEqual(sender.receivers(SIGNAL("destroyed()")), 2)
+ sender.disconnect(sender, SIGNAL("destroyed()"), receiver2, SLOT("deleteLater()"))
+ self.assertEqual(sender.receivers(SIGNAL("destroyed()")), 1)
+ del receiver2
+ del receiver1
+ del sender
+
+ def testPySlots(self):
+ sender = QObject()
+ receiver = QObject()
+ sender.connect(sender, SIGNAL("destroyed()"), cute_slot)
+ self.assertEqual(sender.receivers(SIGNAL("destroyed( )")), 1)
+ sender.connect(sender, SIGNAL("destroyed()"), receiver, SLOT("deleteLater()"))
+ self.assertEqual(sender.receivers(SIGNAL("destroyed()")), 2)
+ del sender
+ del receiver
+
+ def testPySignals(self):
+ sender = QObject()
+ receiver = QObject()
+ sender.connect(sender, SIGNAL("some_dynamic_signal()"), cute_slot)
+ self.assertEqual(sender.receivers(SIGNAL("some_dynamic_signal( )")), 1)
+ sender.connect(sender, SIGNAL("some_dynamic_signal()"), receiver, SLOT("deleteLater()"))
+ self.assertEqual(sender.receivers(SIGNAL("some_dynamic_signal( )")), 2)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/qobject_sender_test.py b/tests/signals/qobject_sender_test.py
new file mode 100755
index 000000000..5f11cda04
--- /dev/null
+++ b/tests/signals/qobject_sender_test.py
@@ -0,0 +1,91 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+'''Test cases for QObject.sender()'''
+
+import unittest
+from PySide.QtCore import *
+from helper import UsesQCoreApplication
+
+class ExtQTimer(QTimer):
+ def __init__(self):
+ QTimer.__init__(self)
+
+class Receiver(QObject):
+ def __init__(self):
+ QObject.__init__(self)
+ self.the_sender = None
+
+ def callback(self):
+ self.the_sender = self.sender()
+ if QCoreApplication.instance():
+ QCoreApplication.instance().exit()
+
+class ObjectSenderTest(unittest.TestCase):
+ '''Test case for QObject.sender() method.'''
+
+ def testSenderPythonSignal(self):
+ sender = QObject()
+ recv = Receiver()
+ QObject.connect(sender, SIGNAL('foo()'), recv.callback)
+ sender.emit(SIGNAL('foo()'))
+ self.assertEquals(sender, recv.the_sender)
+
+class ObjectSenderCheckOnReceiverTest(unittest.TestCase):
+ '''Test case for QObject.sender() method, this one tests the equality on the Receiver object.'''
+
+ def testSenderPythonSignal(self):
+ sender = QObject()
+ recv = Receiver()
+ QObject.connect(sender, SIGNAL('foo()'), recv.callback)
+ sender.emit(SIGNAL('foo()'))
+ self.assertEquals(sender, recv.the_sender)
+
+class ObjectSenderWithQAppTest(UsesQCoreApplication):
+ '''Test case for QObject.sender() method with QApplication.'''
+
+ def testSenderCppSignal(self):
+ sender = QTimer()
+ sender.setObjectName('foo')
+ recv = Receiver()
+ QObject.connect(sender, SIGNAL('timeout()'), recv.callback)
+ sender.start(10)
+ self.app.exec_()
+ self.assertEquals(sender, recv.the_sender)
+
+ def testSenderCppSignalSingleShotTimer(self):
+ recv = Receiver()
+ QTimer.singleShot(10, recv.callback)
+ self.app.exec_()
+ self.assertEquals(QObject, type(recv.the_sender))
+
+ def testSenderCppSignalWithPythonExtendedClass(self):
+ sender = ExtQTimer()
+ recv = Receiver()
+ QObject.connect(sender, SIGNAL('timeout()'), recv.callback)
+ sender.start(10)
+ self.app.exec_()
+ self.assertEquals(sender, recv.the_sender)
+
+class ObjectSenderWithQAppCheckOnReceiverTest(UsesQCoreApplication):
+ '''Test case for QObject.sender() method with QApplication.'''
+
+ def testSenderCppSignal(self):
+ sender = QTimer()
+ sender.setObjectName('foo')
+ recv = Receiver()
+ QObject.connect(sender, SIGNAL('timeout()'), recv.callback)
+ sender.start(10)
+ self.app.exec_()
+ self.assertEquals(sender, recv.the_sender)
+
+ def testSenderCppSignalWithPythonExtendedClass(self):
+ sender = ExtQTimer()
+ recv = Receiver()
+ QObject.connect(sender, SIGNAL('timeout()'), recv.callback)
+ sender.start(10)
+ self.app.exec_()
+ self.assertEquals(sender, recv.the_sender)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/signals/segfault_proxyparent_test.py b/tests/signals/segfault_proxyparent_test.py
new file mode 100644
index 000000000..2b41f67c4
--- /dev/null
+++ b/tests/signals/segfault_proxyparent_test.py
@@ -0,0 +1,73 @@
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL
+
+# Description of the problem
+# After creating an PyObject that inherits from QObject, connecting it,
+# deleting it and later creating another Python QObject-based object, this
+# new object will point to the same memory position as the first one.
+
+# Somehow the underlying QObject also points to the same position.
+
+# In PyQt4, the connection works fine with the same memory behavior,
+# so it looks like specific to SIP.
+
+class Dummy(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+class Joe(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+class SegfaultCase(unittest.TestCase):
+ """Test case for the segfault happening when parent() is called inside
+ ProxyObject"""
+
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except:
+ pass
+
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testSegfault(self):
+ """Regression: Segfault for qobjects in the same memory position."""
+ obj = Dummy()
+ QObject.connect(obj, SIGNAL('bar(int)'), self.callback)
+ self.args = (33,)
+ obj.emit(SIGNAL('bar(int)'), self.args[0])
+ self.assert_(self.called)
+ del obj
+
+ obj = Joe()
+ QObject.connect(obj, SIGNAL('bar(int)'), self.callback)
+ self.args = (33,)
+ obj.emit(SIGNAL('bar(int)'), self.args[0])
+ self.assert_(self.called)
+
+
+ def testSameReference(self):
+ """Example of how sip(?) reuses memory positions"""
+ obj = Dummy()
+ s1 = str(obj)
+ del obj
+ obj = Dummy()
+ s2 = str(obj)
+ self.assertEqual(s1, s2)
+
+ obj2 = Dummy()
+ s3 = str(obj2)
+ self.assertNotEqual(s2, s3)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/signals/short_circuit_test.py b/tests/signals/short_circuit_test.py
new file mode 100644
index 000000000..e36420cad
--- /dev/null
+++ b/tests/signals/short_circuit_test.py
@@ -0,0 +1,66 @@
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL, SLOT
+
+class Dummy(QObject):
+ """Dummy class used in this test."""
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+class ShortCircuitSignals(unittest.TestCase):
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except:
+ pass
+
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testNoArgs(self):
+ """Short circuit signal without arguments"""
+ obj1 = Dummy()
+
+ QObject.connect(obj1, SIGNAL('foo'), self.callback)
+ self.args = tuple()
+ obj1.emit(SIGNAL('foo'), *self.args)
+
+ self.assert_(self.called)
+
+ def testWithArgs(self):
+ """Short circuit signal with integer arguments"""
+ obj1 = Dummy()
+
+ QObject.connect(obj1, SIGNAL('foo'), self.callback)
+ self.args = (42,)
+ obj1.emit(SIGNAL('foo'), *self.args)
+
+ self.assert_(self.called)
+
+ def testMultipleArgs(self):
+ """Short circuit signal with multiple arguments"""
+ obj1 = Dummy()
+
+ QObject.connect(obj1, SIGNAL('foo'), self.callback)
+ self.args = (42,33,'char')
+ obj1.emit(SIGNAL('foo'), *self.args)
+
+ self.assert_(self.called)
+
+ def testComplexArgs(self):
+ """Short circuit signal with complex arguments"""
+ obj1 = Dummy()
+
+ QObject.connect(obj1, SIGNAL('foo'), self.callback)
+ self.args = (42, obj1)
+ obj1.emit(SIGNAL('foo'), *self.args)
+
+ self.assert_(self.called)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/signal2signal_connect_test.py b/tests/signals/signal2signal_connect_test.py
new file mode 100644
index 000000000..bdc2328bf
--- /dev/null
+++ b/tests/signals/signal2signal_connect_test.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+
+''' Test case for signal to signal connections.'''
+
+import unittest
+from PySide.QtCore import *
+
+def cute_slot():
+ pass
+
+class TestSignal2SignalConnect(unittest.TestCase):
+ '''Test case for signal to signal connections'''
+
+ def setUp(self):
+ #Set up the basic resources needed
+ self.sender = QObject()
+ self.forwarder = QObject()
+ self.args = None
+ self.called = False
+
+ def tearDown(self):
+ #Delete used resources
+ try:
+ del self.sender
+ except:
+ pass
+ try:
+ del self.forwarder
+ except:
+ pass
+ del self.args
+
+ def callback_noargs(self):
+ #Default callback without arguments
+ self.called = True
+
+ def callback_args(self, *args):
+ #Default callback with arguments
+ if args == self.args:
+ self.called = True
+ else:
+ raise TypeError("Invalid arguments")
+
+ def callback_qobject(self, *args):
+ #Default callback for QObject as argument
+ if args[0].objectName() == self.args[0]:
+ self.called = True
+ else:
+ raise TypeError("Invalid arguments")
+
+
+ def testSignalWithoutArguments(self):
+ QObject.connect(self.sender, SIGNAL("destroyed()"),
+ self.forwarder, SIGNAL("forward()"))
+ QObject.connect(self.forwarder, SIGNAL("forward()"),
+ self.callback_noargs)
+ del self.sender
+ self.assert_(self.called)
+
+
+ def testSignalWithOnePrimitiveTypeArgument(self):
+ QObject.connect(self.sender, SIGNAL("mysignal(int)"),
+ self.forwarder, SIGNAL("mysignal(int)"))
+ QObject.connect(self.forwarder, SIGNAL("mysignal(int)"),
+ self.callback_args)
+ self.args = (19,)
+ self.sender.emit(SIGNAL('mysignal(int)'), *self.args)
+ self.assert_(self.called)
+
+
+ def testSignalWithMultiplePrimitiveTypeArguments(self):
+ QObject.connect(self.sender, SIGNAL("mysignal(int,int)"),
+ self.forwarder, SIGNAL("mysignal(int,int)"))
+ QObject.connect(self.forwarder, SIGNAL("mysignal(int,int)"),
+ self.callback_args)
+ self.args = (23, 29)
+ self.sender.emit(SIGNAL('mysignal(int,int)'), *self.args)
+ self.assert_(self.called)
+
+
+ def testSignalWithOneStringArgument(self):
+ QObject.connect(self.sender, SIGNAL("mysignal(QString)"),
+ self.forwarder, SIGNAL("mysignal(QString)"))
+ QObject.connect(self.forwarder, SIGNAL("mysignal(QString)"),
+ self.callback_args)
+ self.args = ('myargument',)
+ self.sender.emit(SIGNAL('mysignal(QString)'), *self.args)
+ self.assert_(self.called)
+
+
+ def testSignalWithOneQObjectArgument(self):
+ QObject.connect(self.sender, SIGNAL('destroyed(QObject*)'),
+ self.forwarder, SIGNAL('forward(QObject*)'))
+ QObject.connect(self.forwarder, SIGNAL('forward(QObject*)'),
+ self.callback_qobject)
+
+ obj_name = 'sender'
+ self.sender.setObjectName(obj_name)
+ self.args = (obj_name, )
+ del self.sender
+ self.assert_(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
+
diff --git a/tests/signals/signal_connectiontype_support.py b/tests/signals/signal_connectiontype_support.py
new file mode 100644
index 000000000..d0c35c53a
--- /dev/null
+++ b/tests/signals/signal_connectiontype_support.py
@@ -0,0 +1,28 @@
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL, Qt
+
+class Dummy(QObject):
+ """Dummy class used in this test."""
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+class TestConnectionTypeSupport(unittest.TestCase):
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testNoArgs(self):
+ """Connect signal using a Qt.ConnectionType as argument"""
+ obj1 = Dummy()
+
+ QObject.connect(obj1, SIGNAL('foo'), self.callback, Qt.DirectConnection)
+ self.args = tuple()
+ obj1.emit(SIGNAL('foo'), *self.args)
+
+ self.assert_(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/signal_emission_test.py b/tests/signals/signal_emission_test.py
new file mode 100644
index 000000000..8d9af620c
--- /dev/null
+++ b/tests/signals/signal_emission_test.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+
+"""Tests covering signal emission and receiving to python slots"""
+
+import sys
+import unittest
+
+from PySide.QtCore import QObject, QTimer, QCoreApplication, SIGNAL, SLOT
+from PySide.QtGui import QSpinBox, QPushButton, QApplication
+from helper import BasicPySlotCase, UsesQApplication
+
+class ButtonPySlot(UsesQApplication, BasicPySlotCase):
+ """Tests the connection of python slots to QPushButton signals"""
+
+ qapplication = True
+
+ def setUp(self):
+ super(ButtonPySlot, self).setUp()
+
+ def tearDown(self):
+ super(ButtonPySlot, self).setUp()
+
+ def testButtonClicked(self):
+ """Connection of a python slot to QPushButton.clicked()"""
+ button = QPushButton('Mylabel')
+ QObject.connect(button, SIGNAL('clicked()'), self.cb)
+ self.args = tuple()
+ button.emit(SIGNAL('clicked()'))
+ self.assert_(self.called)
+
+ def testButtonClickedWrongArgs(self):
+ """Python slot connected to QPushButton.clicked() and more args"""
+ button = QPushButton('Mylabel')
+ QObject.connect(button, SIGNAL('clicked()'), self.cb)
+ self.args = tuple()
+ button.emit(SIGNAL('clicked()'), 44)
+ self.assert_(self.called)
+
+ def testButtonClick(self):
+ """Indirect qt signal emission using the QPushButton.click() method """
+ button = QPushButton('label')
+ QObject.connect(button, SIGNAL('clicked()'), self.cb)
+ self.args = tuple()
+ button.click()
+ self.assert_(self.called)
+
+
+class SpinBoxPySlot(UsesQApplication, BasicPySlotCase):
+ """Tests the connection of python slots to QSpinBox signals"""
+
+ qapplication = True
+
+ def setUp(self):
+ super(SpinBoxPySlot, self).setUp()
+ self.spin = QSpinBox()
+
+ def tearDown(self):
+ del self.spin
+ super(SpinBoxPySlot, self).tearDown()
+
+ def testSpinBoxValueChanged(self):
+ """Connection of a python slot to QSpinBox.valueChanged(int)"""
+ QObject.connect(self.spin, SIGNAL('valueChanged(int)'), self.cb)
+ self.args = [3]
+ self.spin.emit(SIGNAL('valueChanged(int)'), *self.args)
+ self.assert_(self.called)
+
+ def testSpinBoxValueChangedImplicit(self):
+ """Indirect qt signal emission using QSpinBox.setValue(int)"""
+ QObject.connect(self.spin, SIGNAL('valueChanged(int)'), self.cb)
+ self.args = [42]
+ self.spin.setValue(self.args[0])
+ self.assert_(self.called)
+
+ def atestSpinBoxValueChangedFewArgs(self):
+ """Emission of signals with fewer arguments than needed"""
+ # XXX: PyQt4 crashes on the assertRaises
+ QObject.connect(self.spin, SIGNAL('valueChanged(int)'), self.cb)
+ self.args = (554,)
+ self.assertRaises(TypeError, self.spin.emit, SIGNAL('valueChanged(int)'))
+
+class QSpinBoxQtSlots(UsesQApplication):
+ """Tests the connection to QSpinBox qt slots"""
+
+ qapplication = True
+
+ def testSetValueIndirect(self):
+ """Indirect signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
+ spinSend = QSpinBox()
+ spinRec = QSpinBox()
+
+ spinRec.setValue(5)
+
+ QObject.connect(spinSend, SIGNAL('valueChanged(int)'), spinRec, SLOT('setValue(int)'))
+ self.assertEqual(spinRec.value(), 5)
+ spinSend.setValue(3)
+ self.assertEqual(spinRec.value(), 3)
+ self.assertEqual(spinSend.value(), 3)
+
+ def testSetValue(self):
+ """Direct signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
+ spinSend = QSpinBox()
+ spinRec = QSpinBox()
+
+ spinRec.setValue(5)
+ spinSend.setValue(42)
+
+ QObject.connect(spinSend, SIGNAL('valueChanged(int)'), spinRec, SLOT('setValue(int)'))
+ self.assertEqual(spinRec.value(), 5)
+ self.assertEqual(spinSend.value(), 42)
+ spinSend.emit(SIGNAL('valueChanged(int)'), 3)
+
+ self.assertEqual(spinRec.value(), 3)
+ #Direct emission shouldn't change the value of the emitter
+ self.assertEqual(spinSend.value(), 42)
+
+ spinSend.emit(SIGNAL('valueChanged(int)'), 66)
+ self.assertEqual(spinRec.value(), 66)
+ self.assertEqual(spinSend.value(), 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/signal_func_test.py b/tests/signals/signal_func_test.py
new file mode 100644
index 000000000..39bd1b293
--- /dev/null
+++ b/tests/signals/signal_func_test.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+
+import unittest
+
+from PySide.QtCore import SIGNAL, SLOT
+
+class SIGNALSLOTTests(unittest.TestCase):
+ '''Test the output of SIGNAL and SLOT.'''
+
+ def testSIGNAL(self):
+ #SIGNAL function
+ a = "foobar"
+ self.assertEqual(str(SIGNAL(a)), "2foobar")
+
+ def testSLOT(self):
+ #SLOT function
+ a = "foobar"
+ self.assertEqual(str(SLOT(a)), "1foobar")
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/signal_manager_refcount_test.py b/tests/signals/signal_manager_refcount_test.py
new file mode 100644
index 000000000..191ce9d63
--- /dev/null
+++ b/tests/signals/signal_manager_refcount_test.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+
+from sys import getrefcount
+import unittest
+from PySide.QtCore import QObject, SIGNAL
+
+class SignalManagerRefCount(unittest.TestCase):
+ """Simple test case to check if the signal_manager is erroneously incrementing the object refcounter"""
+
+ def testObjectRefcount(self):
+ """Emission of QObject.destroyed() to a python slot"""
+ def callback():
+ pass
+ obj = QObject()
+ refcount = getrefcount(obj)
+ QObject.connect(obj, SIGNAL('destroyed()'), callback)
+ self.assertEqual(refcount, getrefcount(obj))
+ QObject.disconnect(obj, SIGNAL('destroyed()'), callback)
+ self.assertEqual(refcount, getrefcount(obj))
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/signals/signal_with_primitive_type_test.py b/tests/signals/signal_with_primitive_type_test.py
new file mode 100644
index 000000000..96ff353cc
--- /dev/null
+++ b/tests/signals/signal_with_primitive_type_test.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+import unittest
+from PySide.QtCore import *
+
+
+class SignalPrimitiveTypeTest(unittest.TestCase):
+
+ def signalValueChanged(self, v):
+ self.called = True
+ self._app.quit()
+
+ def createTimeLine(self):
+ self.called = False
+ tl = QTimeLine(10000)
+ QObject.connect(tl, SIGNAL("valueChanged(qreal)"), self.signalValueChanged)
+ return tl
+
+ def testTimeLine(self):
+ self._valueChangedCount = 0
+ self._app = QCoreApplication([])
+ tl = self.createTimeLine()
+ tl.start()
+ self._app.exec_()
+ self.assert_(self.called)
+
+if __name__ == '__main__':
+ unittest.main()
+
+
diff --git a/tests/signals/slot_reference_count_test.py b/tests/signals/slot_reference_count_test.py
new file mode 100644
index 000000000..62037f28c
--- /dev/null
+++ b/tests/signals/slot_reference_count_test.py
@@ -0,0 +1,54 @@
+
+''' Forced disconnection: Delete one end of the signal connection'''
+
+import unittest
+from sys import getrefcount
+
+from PySide.QtCore import QObject, SIGNAL, SLOT
+
+class Dummy(QObject):
+ def dispatch(self):
+ self.emit(SIGNAL('foo()'))
+
+class PythonSignalRefCount(unittest.TestCase):
+
+ def setUp(self):
+ self.emitter = Dummy()
+
+ def tearDown(self):
+ self.emitter
+
+ def testRefCount(self):
+ def cb(*args):
+ pass
+
+ self.assertEqual(getrefcount(cb), 2)
+
+ QObject.connect(self.emitter, SIGNAL('foo()'), cb)
+ self.assertEqual(getrefcount(cb), 3)
+
+ QObject.disconnect(self.emitter, SIGNAL('foo()'), cb)
+ self.assertEqual(getrefcount(cb), 2)
+
+class CppSignalRefCount(unittest.TestCase):
+
+ def setUp(self):
+ self.emitter = QObject()
+
+ def tearDown(self):
+ self.emitter
+
+ def testRefCount(self):
+ def cb(*args):
+ pass
+
+ self.assertEqual(getrefcount(cb), 2)
+
+ QObject.connect(self.emitter, SIGNAL('destroyed()'), cb)
+ self.assertEqual(getrefcount(cb), 3)
+
+ QObject.disconnect(self.emitter, SIGNAL('destroyed()'), cb)
+ self.assertEqual(getrefcount(cb), 2)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/signals/upstream_segfault_test.py b/tests/signals/upstream_segfault_test.py
new file mode 100644
index 000000000..793b04b1c
--- /dev/null
+++ b/tests/signals/upstream_segfault_test.py
@@ -0,0 +1,64 @@
+
+import unittest
+
+from PySide.QtCore import QObject, SIGNAL, SLOT
+
+# Upstream version of segfault_test
+
+class Dummy(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+class Joe(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+class SegfaultCase(unittest.TestCase):
+ """Test case for the segfault happening when parent() is called inside
+ ProxyObject"""
+
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except:
+ pass
+
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testSegfault(self):
+ obj = Dummy()
+ QObject.connect(obj, SIGNAL('bar(int)'), self.callback)
+ self.args = (33,)
+ obj.emit(SIGNAL('bar(int)'), self.args[0])
+ self.assert_(self.called)
+
+ del obj
+ obj = Joe()
+ QObject.connect(obj, SIGNAL('bar(int)'), self.callback)
+ self.args = (33,)
+ obj.emit(SIGNAL('bar(int)'), self.args[0])
+ self.assert_(self.called)
+
+
+ def testSameReference(self):
+ """Example of how sip reuses an already used PyObject"""
+ obj = Dummy()
+ s1 = str(obj)
+ del obj
+ obj = Dummy()
+ s2 = str(obj)
+ self.assertEqual(s1, s2)
+
+ obj2 = Dummy()
+ s3 = str(obj2)
+ self.assertNotEqual(s2, s3)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/tests/util/color.py b/tests/util/color.py
new file mode 100644
index 000000000..4ddd31cab
--- /dev/null
+++ b/tests/util/color.py
@@ -0,0 +1,12 @@
+
+'''Function to print a colored line to terminal'''
+
+RED='\033[0;31m%s\033[m'
+
+def print_colored(message, color=RED):
+ print color % message
+
+if __name__ == '__main__':
+ print '42 - the answer'
+ print_colored("But what's the question?")
+ print 'Hum?'
diff --git a/tests/util/helper.py b/tests/util/helper.py
new file mode 100644
index 000000000..e27ee1ed9
--- /dev/null
+++ b/tests/util/helper.py
@@ -0,0 +1,120 @@
+
+'''Helper classes and functions'''
+
+import os
+import unittest
+
+from random import randint
+
+from PySide.QtCore import QCoreApplication, QTimer
+
+try:
+ from PySide.QtGui import QApplication
+except ImportError:
+ has_gui = False
+else:
+ has_gui = True
+
+def adjust_filename(filename, orig_mod_filename):
+ dirpath = os.path.dirname(os.path.abspath(orig_mod_filename))
+ return os.path.join(dirpath, filename)
+
+class BasicPySlotCase(object):
+ '''Base class that tests python slots and signal emissions.
+
+ Python slots are defined as any callable passed to QObject.connect().
+ '''
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except:
+ pass
+
+ def cb(self, *args):
+ '''Simple callback with arbitrary arguments.
+
+ The test function must setup the 'args' attribute with a sequence
+ containing the arguments expected to be received by this slot.
+ Currently only a single connection is supported.
+ '''
+ if tuple(self.args) == args:
+ self.called = True
+ else:
+ raise ValueError('Invalid arguments for callback')
+
+
+_instance = None
+_timed_instance = None
+
+if has_gui:
+ class UsesQApplication(unittest.TestCase):
+ '''Helper class to provide QApplication instances'''
+
+ qapplication = True
+
+ def setUp(self):
+ '''Creates the QApplication instance'''
+
+ # Simple way of making instance a singleton
+ super(UsesQApplication, self).setUp()
+ global _instance
+ if _instance is None:
+ _instance = QApplication([])
+
+ self.app = _instance
+
+ def tearDown(self):
+ '''Deletes the reference owned by self'''
+ del self.app
+ super(UsesQApplication, self).tearDown()
+
+ class TimedQApplication(unittest.TestCase):
+ '''Helper class with timed QApplication exec loop'''
+
+ def setUp(self, timeout=100):
+ '''Setups this Application.
+
+ timeout - timeout in milisseconds'''
+ global _timed_instance
+ if _timed_instance is None:
+ _timed_instance = QApplication([])
+
+ self.app = _timed_instance
+ QTimer.singleShot(timeout, self.app.quit)
+
+ def tearDown(self):
+ '''Delete resources'''
+ del self.app
+
+_core_instance = None
+
+class UsesQCoreApplication(unittest.TestCase):
+ '''Helper class for test cases that require an QCoreApplication
+ Just connect or call self.exit_app_cb. When called, will ask
+ self.app to exit.
+ '''
+
+ def setUp(self):
+ '''Set up resources'''
+
+ global _core_instance
+ if _core_instance is None:
+ _core_instance = QCoreApplication([])
+
+ self.app = _core_instance
+
+ def tearDown(self):
+ '''Release resources'''
+ del self.app
+
+ def exit_app_cb(self):
+ '''Quits the application'''
+ self.app.exit(0)
+
+
+def random_string(size=5):
+ '''Generate random string with the given size'''
+ return ''.join(map(chr, [randint(33, 126) for x in range(size)]))
diff --git a/tests/util/helper.pyc b/tests/util/helper.pyc
new file mode 100644
index 000000000..e6c45fa60
--- /dev/null
+++ b/tests/util/helper.pyc
Binary files differ
diff --git a/tests/util/module_wrapper/PySide/QtAssistant.py b/tests/util/module_wrapper/PySide/QtAssistant.py
new file mode 100644
index 000000000..d0975d51e
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtAssistant.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtAssistant import *
diff --git a/tests/util/module_wrapper/PySide/QtCore.py b/tests/util/module_wrapper/PySide/QtCore.py
new file mode 100644
index 000000000..a6a225649
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtCore.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtCore import *
diff --git a/tests/util/module_wrapper/PySide/QtDesigner.py b/tests/util/module_wrapper/PySide/QtDesigner.py
new file mode 100644
index 000000000..5cf9d5f6d
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtDesigner.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtDesigner import *
diff --git a/tests/util/module_wrapper/PySide/QtGui.py b/tests/util/module_wrapper/PySide/QtGui.py
new file mode 100644
index 000000000..0b8b4e957
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtGui.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtGui import *
diff --git a/tests/util/module_wrapper/PySide/QtHelp.py b/tests/util/module_wrapper/PySide/QtHelp.py
new file mode 100644
index 000000000..dd3fd6cd8
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtHelp.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtHelp import *
diff --git a/tests/util/module_wrapper/PySide/QtNetwork.py b/tests/util/module_wrapper/PySide/QtNetwork.py
new file mode 100644
index 000000000..1a669a421
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtNetwork.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtNetwork import *
diff --git a/tests/util/module_wrapper/PySide/QtScript.py b/tests/util/module_wrapper/PySide/QtScript.py
new file mode 100644
index 000000000..4f6b30e8e
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtScript.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtScript import *
diff --git a/tests/util/module_wrapper/PySide/QtSql.py b/tests/util/module_wrapper/PySide/QtSql.py
new file mode 100644
index 000000000..35dd0a106
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtSql.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtSql import *
diff --git a/tests/util/module_wrapper/PySide/QtSvg.py b/tests/util/module_wrapper/PySide/QtSvg.py
new file mode 100644
index 000000000..f308222b9
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtSvg.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtSvg import *
diff --git a/tests/util/module_wrapper/PySide/QtTest.py b/tests/util/module_wrapper/PySide/QtTest.py
new file mode 100644
index 000000000..95f64006b
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtTest.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtTest import *
diff --git a/tests/util/module_wrapper/PySide/QtWebKit.py b/tests/util/module_wrapper/PySide/QtWebKit.py
new file mode 100644
index 000000000..bffc79968
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtWebKit.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtWebKit import *
diff --git a/tests/util/module_wrapper/PySide/QtXml.py b/tests/util/module_wrapper/PySide/QtXml.py
new file mode 100644
index 000000000..2888a4e49
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtXml.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtXml import *
diff --git a/tests/util/module_wrapper/PySide/QtXmlPatterns.py b/tests/util/module_wrapper/PySide/QtXmlPatterns.py
new file mode 100644
index 000000000..6de76d830
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/QtXmlPatterns.py
@@ -0,0 +1,2 @@
+
+from PyQt4.QtXmlPatterns import *
diff --git a/tests/util/module_wrapper/PySide/__init__.py b/tests/util/module_wrapper/PySide/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/__init__.py
diff --git a/tests/util/module_wrapper/PySide/phonon.py b/tests/util/module_wrapper/PySide/phonon.py
new file mode 100644
index 000000000..2e4bd72a3
--- /dev/null
+++ b/tests/util/module_wrapper/PySide/phonon.py
@@ -0,0 +1,2 @@
+
+from PyQt4.phonon import *
diff --git a/tests/util/processtimer.py b/tests/util/processtimer.py
new file mode 100755
index 000000000..1991746ac
--- /dev/null
+++ b/tests/util/processtimer.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+import time,os
+
+class TimeoutException(Exception):
+ def __init__(self, msg):
+ self.msg = msg
+
+ def __str__(self):
+ return repr(self.msg)
+
+class ProcessTimer(object):
+ '''Timeout function for controlling a subprocess.Popen instance.
+
+ Naive implementation using busy loop, see later other means
+ of doing this.
+ '''
+
+ def __init__(self, proc, timeout):
+ self.proc = proc
+ self.timeout = timeout
+
+ def waitfor(self):
+ time_passed = 0
+ while(self.proc.poll() is None and time_passed < self.timeout):
+ time_passed = time_passed + 1
+ time.sleep(1)
+
+ if time_passed >= self.timeout:
+ raise TimeoutException("Timeout expired, possible deadlock")
+
+if __name__ == "__main__":
+ #simple example
+
+ from subprocess import Popen
+
+ proc = Popen(['sleep','10'])
+ t = ProcessTimer(proc,5)
+ try:
+ t.waitfor()
+ except TimeoutException:
+ print "timeout - PID: %d" % (t.proc.pid)
+ #TODO: detect SO and kill accordingly
+ #Linux
+ os.kill(t.proc.pid, 9)
+ #Windows (not tested)
+ #subprocess.Popen("taskkill /F /T /PID %i"%handle.pid , shell=True)
+ print "exit code: %d" % (t.proc.poll())
+
diff --git a/tests/util/pyqt_diff.py b/tests/util/pyqt_diff.py
new file mode 100644
index 000000000..b270750ed
--- /dev/null
+++ b/tests/util/pyqt_diff.py
@@ -0,0 +1,35 @@
+
+'''Script to show the difference between PyQt4 and ours'''
+
+import sys
+
+from color import print_colored
+
+def check_module_diff(module_name):
+ '''Difference between PySide and PyQt4 versions of qt bindings.
+ Returns a tuple with the members present only on PySide and only on PyQt4'''
+ boost_module = getattr(__import__('PySide.' + module_name), module_name)
+ orig_module = getattr(__import__('PyQt4.' + module_name), module_name)
+
+ boost_set = set(dir(boost_module))
+ orig_set = set(dir(orig_module))
+
+ return sorted(boost_set - orig_set), sorted(orig_set - boost_set)
+
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv
+
+ module_name = argv[1] if len(argv) >= 2 else 'QtCore'
+
+ only_boost, only_orig = check_module_diff(module_name)
+
+ print_colored('Only on Boost version')
+ print only_boost
+
+ print_colored('Only on SIP version')
+ print only_orig
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/util/pyqtcheck.py b/tests/util/pyqtcheck.py
new file mode 100755
index 000000000..a75744a11
--- /dev/null
+++ b/tests/util/pyqtcheck.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+import sys
+from optparse import OptionParser
+
+import PyQt4
+from PyQt4 import QtCore, QtGui, QtNetwork
+
+modules = [QtCore, QtGui, QtNetwork]
+
+def search(klass, method=None):
+ for module in modules:
+ try:
+ klass_obj = getattr(module, klass)
+ print "%s *found* on module %s" % (klass, module.__name__)
+ except AttributeError:
+ print "%s not found on module %s" % (klass, module.__name__)
+ continue
+
+ if method is None:
+ continue
+
+ try:
+ meth_obj = getattr(klass_obj, method)
+
+ meth_name = ".".join([klass, method])
+ klass_name = ".".join([module.__name__, klass])
+ print "\"%s\" *found* on class %s" % (meth_name, klass_name)
+ except AttributeError:
+ print "\"%s\" not found on class %s" % (method, klass)
+
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv[1:]
+
+ try:
+ klass, method = argv[0].split(".")
+ except:
+ klass = argv[0]
+ method = None
+
+ search(klass, method)
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/util/rename_imports.sh b/tests/util/rename_imports.sh
new file mode 100755
index 000000000..fd3ba1c62
--- /dev/null
+++ b/tests/util/rename_imports.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Rename import statements from .py script to use a specific module name
+set -e
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 <old_name> <new_name> <directories...>"
+ exit 1
+fi
+
+old_name=$1; shift
+new_name=$1; shift
+
+find "$@" -name "*.py" -exec sed -ri "s/(import|from) $old_name/\1 $new_name/" '{}' \;
diff --git a/tests/util/test_processtimer.py b/tests/util/test_processtimer.py
new file mode 100644
index 000000000..816ce5165
--- /dev/null
+++ b/tests/util/test_processtimer.py
@@ -0,0 +1,66 @@
+
+'Tests for processtimer.py'
+
+import unittest
+import os
+
+from subprocess import Popen, PIPE
+from processtimer import TimeoutException, ProcessTimer
+
+class TimeoutTest(unittest.TestCase):
+
+ def tearDown(self):
+ try:
+ os.kill(self.proc.pid, 9)
+ except OSError:
+ pass
+
+ def testRaise(self):
+ self.proc = Popen(['python2.5', '-c', 'while True: pass' ], stdout=PIPE, stderr=PIPE)
+ timer = ProcessTimer(self.proc, 1)
+ self.assertRaises(TimeoutException, timer.waitfor)
+
+class SimpleTest(unittest.TestCase):
+
+ def tearDown(self):
+ try:
+ os.kill(self.proc.pid, 9)
+ except OSError:
+ pass
+ def testSimple(self):
+ self.proc = Popen(['python2.5', '-c', '"print"'], stdout=PIPE, stderr=PIPE)
+ timer = ProcessTimer(self.proc, 10)
+ timer.waitfor()
+
+class TestEchoOutput(unittest.TestCase):
+
+ def tearDown(self):
+ try:
+ os.kill(self.proc.pid, 9)
+ except OSError:
+ pass
+
+ def testOutput(self):
+ self.proc = Popen(['python2.5', '-c', 'print 1',], stdout=PIPE, stderr=PIPE)
+ timer = ProcessTimer(self.proc, 1)
+ timer.waitfor()
+ self.assertEqual(self.proc.stdout.read().strip(), '1')
+
+class TestRetCode(unittest.TestCase):
+
+ def tearDown(self):
+ try:
+ os.kill(self.proc.pid, 9)
+ except OSError:
+ pass
+
+ def testSimple(self):
+ self.proc = Popen(['python2.5', '-c', 'print 1'], stdout=PIPE, stderr=PIPE)
+ timer = ProcessTimer(self.proc, 10)
+ timer.waitfor()
+
+ self.assertEqual(self.proc.poll(), 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/util/use_pyqt4.sh b/tests/util/use_pyqt4.sh
new file mode 100644
index 000000000..5b88fa5c7
--- /dev/null
+++ b/tests/util/use_pyqt4.sh
@@ -0,0 +1,3 @@
+
+OLD_PYTHONPATH=$PYTHONPATH
+PYTHONPATH=`pwd`/util/module_wrapper:$PYTHONPATH
diff --git a/tests/util/use_pyside.sh b/tests/util/use_pyside.sh
new file mode 100644
index 000000000..516207473
--- /dev/null
+++ b/tests/util/use_pyside.sh
@@ -0,0 +1,3 @@
+
+PYTHONPATH=$OLD_PYTHONPATH
+unset OLD_PYTHONPATH
diff --git a/tests/util/valgrind-python.supp b/tests/util/valgrind-python.supp
new file mode 100644
index 000000000..a54b451b3
--- /dev/null
+++ b/tests/util/valgrind-python.supp
@@ -0,0 +1,349 @@
+#
+# This is a valgrind suppression file that should be used when using valgrind.
+#
+# Here's an example of running valgrind:
+#
+# cd python/dist/src
+# valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \
+# ./python -E -tt ./Lib/test/regrtest.py -u bsddb,network
+#
+# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER
+# to use the preferred suppressions with Py_ADDRESS_IN_RANGE.
+#
+# If you do not want to recompile Python, you can uncomment
+# suppressions for PyObject_Free and PyObject_Realloc.
+#
+# See Misc/README.valgrind for more information.
+
+# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64)
+ Memcheck:Value8
+ fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:Py_ADDRESS_IN_RANGE
+}
+
+#
+# Leaks (including possible leaks)
+# Hmmm, I wonder if this masks some real leaks. I think it does.
+# Will need to fix that.
+#
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:realloc
+ fun:_PyObject_GC_Resize
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:malloc
+ fun:_PyObject_GC_New
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:malloc
+ fun:_PyObject_GC_NewVar
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+#
+# Non-python specific leaks
+#
+
+{
+ Handle pthread issue (possibly leaked)
+ Memcheck:Leak
+ fun:calloc
+ fun:allocate_dtv
+ fun:_dl_allocate_tls_storage
+ fun:_dl_allocate_tls
+}
+
+{
+ Handle pthread issue (possibly leaked)
+ Memcheck:Leak
+ fun:memalign
+ fun:_dl_allocate_tls_storage
+ fun:_dl_allocate_tls
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:PyObject_Realloc
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:PyObject_Realloc
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:PyObject_Realloc
+}
+
+###
+### All the suppressions below are for errors that occur within libraries
+### that Python uses. The problems to not appear to be related to Python's
+### use of the libraries.
+###
+
+{
+ Generic gentoo ld problems
+ Memcheck:Cond
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Param
+ write(buf)
+ fun:write
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_close
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Value8
+ fun:memmove
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Cond
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Cond
+ fun:memmove
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ GDBM problems, see test_gdbm
+ Memcheck:Param
+ write(buf)
+ fun:write
+ fun:gdbm_open
+
+}
+
+{
+ ZLIB problems, see test_gzip
+ Memcheck:Cond
+ obj:/lib/libz.so.1.2.3
+ obj:/lib/libz.so.1.2.3
+ fun:deflate
+}
+
+{
+ Avoid problems w/readline doing a putenv and leaking on exit
+ Memcheck:Leak
+ fun:malloc
+ fun:xmalloc
+ fun:sh_set_lines_and_columns
+ fun:_rl_get_screen_size
+ fun:_rl_init_terminal_io
+ obj:/lib/libreadline.so.4.3
+ fun:rl_initialize
+}
+
+###
+### These occur from somewhere within the SSL, when running
+### test_socket_sll. They are too general to leave on by default.
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Cond
+### fun:memset
+###}
+###{
+### somewhere in SSL stuff
+### Memcheck:Value4
+### fun:memset
+###}
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Cond
+### fun:MD5_Update
+###}
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Value4
+### fun:MD5_Update
+###}
+
+#
+# All of these problems come from using test_socket_ssl
+#
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_bin2bn
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_num_bits_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:BN_num_bits_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_mod_exp_mont_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_mod_exp_mont
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Param
+ write(buf)
+ fun:write
+ obj:/usr/lib/libcrypto.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:RSA_verify
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:RSA_verify
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:DES_set_key_unchecked
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:DES_encrypt2
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ obj:/usr/lib/libssl.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ obj:/usr/lib/libssl.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BUF_MEM_grow_clean
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:memcpy
+ fun:ssl3_read_bytes
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:SHA1_Update
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:SHA1_Update
+}
+
+