diff options
Diffstat (limited to 'sources/pyside6/tests/QtGui')
57 files changed, 3286 insertions, 0 deletions
diff --git a/sources/pyside6/tests/QtGui/CMakeLists.txt b/sources/pyside6/tests/QtGui/CMakeLists.txt new file mode 100644 index 000000000..71a5c7eb9 --- /dev/null +++ b/sources/pyside6/tests/QtGui/CMakeLists.txt @@ -0,0 +1,60 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +#Keep this in alphabetical sort + +PYSIDE_TEST(bug_367.py) +PYSIDE_TEST(bug_493.py) +PYSIDE_TEST(bug_606.py) +PYSIDE_TEST(bug_617.py) +PYSIDE_TEST(bug_652.py) +PYSIDE_TEST(bug_660.py) +PYSIDE_TEST(bug_716.py) +PYSIDE_TEST(bug_740.py) +PYSIDE_TEST(bug_743.py) +PYSIDE_TEST(bug_785.py) +PYSIDE_TEST(bug_991.py) +PYSIDE_TEST(bug_1091.py) +PYSIDE_TEST(bug_PYSIDE-344.py) +PYSIDE_TEST(deepcopy_test.py) +PYSIDE_TEST(event_filter_test.py) +PYSIDE_TEST(float_to_int_implicit_conversion_test.py) +PYSIDE_TEST(pyside_reload_test.py) +PYSIDE_TEST(qbrush_test.py) +PYSIDE_TEST(qcolor_test.py) +PYSIDE_TEST(qcolor_reduce_test.py) +PYSIDE_TEST(qcursor_test.py) +PYSIDE_TEST(qdatastream_gui_operators_test.py) +PYSIDE_TEST(qdesktopservices_test.py) +PYSIDE_TEST(qfont_test.py) +PYSIDE_TEST(qfontmetrics_test.py) +PYSIDE_TEST(qguiapplication_test.py) +PYSIDE_TEST(qicon_test.py) +PYSIDE_TEST(qimage_test.py) +if(WIN32) + PYSIDE_TEST(qimage_win_test.py) +endif() +PYSIDE_TEST(qitemselection_test.py) +PYSIDE_TEST(qpainter_test.py) +PYSIDE_TEST(qpen_test.py) +PYSIDE_TEST(qpdfwriter_test.py) +PYSIDE_TEST(qpixelformat_test.py) +PYSIDE_TEST(qpixmap_constructor.py) +PYSIDE_TEST(qpixmap_test.py) +PYSIDE_TEST(qpixmapcache_test.py) +PYSIDE_TEST(qpolygonf_test.py) +PYSIDE_TEST(qkeysequence_test.py) +PYSIDE_TEST(qradialgradient_test.py) +PYSIDE_TEST(qrasterwindow_test.py) +PYSIDE_TEST(qregion_test.py) +PYSIDE_TEST(qshortcut_test.py) +PYSIDE_TEST(qstandarditemmodel_test.py) +PYSIDE_TEST(qstring_qkeysequence_test.py) +PYSIDE_TEST(qstylehints_test.py) +PYSIDE_TEST(qtextdocument_functions.py) +PYSIDE_TEST(qtextdocument_undoredo_test.py) +PYSIDE_TEST(qtextdocumentwriter_test.py) +PYSIDE_TEST(qtextline_test.py) +PYSIDE_TEST(qtransform_test.py) +PYSIDE_TEST(repr_test.py) +PYSIDE_TEST(timed_app_and_patching_test.py) diff --git a/sources/pyside6/tests/QtGui/QtGui.pyproject b/sources/pyside6/tests/QtGui/QtGui.pyproject new file mode 100644 index 000000000..75b5e084f --- /dev/null +++ b/sources/pyside6/tests/QtGui/QtGui.pyproject @@ -0,0 +1,56 @@ +{ + "files": ["bug_1091.py", + "bug_367.py", + "bug_493.py", + "bug_606.py", + "bug_617.py", + "bug_652.py", + "bug_660.py", + "bug_716.py", + "bug_740.py", + "bug_743.py", + "bug_785.py", + "bug_991.py", + "bug_PYSIDE-344.py", + "deepcopy_test.py", + "event_filter_test.py", + "float_to_int_implicit_conversion_test.py", + "pyside_reload_test.py", + "qbrush_test.py", + "qcolor_reduce_test.py", + "qcolor_test.py", + "qcursor_test.py", + "qdatastream_gui_operators_test.py", + "qdesktopservices_test.py", + "qfont_test.py", + "qfontmetrics_test.py", + "qguiapplication_test.py", + "qicon_test.py", + "qimage_test.py", + "qimage_win_test.py", + "qitemselection_test.py", + "qkeysequence_test.py", + "qpainter_test.py", + "qpdfwriter_test.py", + "qpen_test.py", + "qpixelformat_test.py", + "qpixmap_constructor.py", + "qpixmap_test.py", + "qpixmapcache_test.py", + "qpolygonf_test.py", + "qradialgradient_test.py", + "qrasterwindow_test.py", + "qregion_test.py", + "qshortcut_test.py", + "qstandarditemmodel_test.py", + "qstring_qkeysequence_test.py", + "qstylehints_test.py", + "qtextdocument_functions.py", + "qtextdocument_undoredo_test.py", + "qtextdocumentwriter_test.py", + "qtextline_test.py", + "qtransform_test.py", + "repr_test.py", + "timed_app_and_patching_test.py", + "xpm_data.py"] +} diff --git a/sources/pyside6/tests/QtGui/bug_1091.py b/sources/pyside6/tests/QtGui/bug_1091.py new file mode 100644 index 000000000..9b9f35807 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_1091.py @@ -0,0 +1,25 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +''' unit test for BUG #1091 ''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QPainter + + +class QPainterTestCase(unittest.TestCase): + def testIt(self): + self.assertTrue("PixmapFragment" in dir(QPainter)) + self.assertTrue("drawPixmapFragments" in dir(QPainter)) + + +if __name__ == "__main__": + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_367.py b/sources/pyside6/tests/QtGui/bug_367.py new file mode 100644 index 000000000..771fa5a4b --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_367.py @@ -0,0 +1,35 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +''' Test bug 367: http://bugs.openbossa.org/show_bug.cgi?id=367''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtGui import QStandardItem, QStandardItemModel + + +class BugTest(UsesQApplication): + @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount") + def testCase(self): + model = QStandardItemModel() + parentItem = model.invisibleRootItem() + for i in range(10): + item = QStandardItem() + rcount = sys.getrefcount(item) + parentItem.appendRow(item) + self.assertEqual(rcount + 1, sys.getrefcount(item)) + parentItem = item + + self.assertTrue(True) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_493.py b/sources/pyside6/tests/QtGui/bug_493.py new file mode 100644 index 000000000..ba8b67bbb --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_493.py @@ -0,0 +1,32 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import Qt, QEvent +from PySide6.QtGui import QGuiApplication, QKeyEvent, QKeySequence + + +class TestBug493(unittest.TestCase): + + def testIt(self): + # We need a qapp otherwise Qt will crash when trying to detect the + # current platform + app = QGuiApplication([]) + ev1 = QKeyEvent(QEvent.KeyRelease, Qt.Key_Delete, Qt.NoModifier) + ev2 = QKeyEvent(QEvent.KeyRelease, Qt.Key_Copy, Qt.NoModifier) + ks = QKeySequence.Delete + + self.assertTrue(ev1.matches(ks)) + self.assertFalse(ev2.matches(ks)) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_606.py b/sources/pyside6/tests/QtGui/bug_606.py new file mode 100644 index 000000000..80b79f640 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_606.py @@ -0,0 +1,45 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QVector2D, QVector3D, QVector4D, qFuzzyCompare +from PySide6.QtGui import QColor + + +class testCases(unittest.TestCase): + def testQVector2DToTuple(self): + vec = QVector2D(1, 2) + self.assertEqual((1, 2), vec.toTuple()) + self.assertTrue(qFuzzyCompare(vec, vec)) + vec2 = QVector2D(1, 3) + self.assertFalse(qFuzzyCompare(vec, vec2)) + + def testQVector3DToTuple(self): + vec = QVector3D(1, 2, 3) + self.assertEqual((1, 2, 3), vec.toTuple()) + vec2 = QVector3D(1, 3, 4) + self.assertFalse(qFuzzyCompare(vec, vec2)) + + def testQVector4DToTuple(self): + vec = QVector4D(1, 2, 3, 4) + self.assertEqual((1, 2, 3, 4), vec.toTuple()) + self.assertTrue(qFuzzyCompare(vec, vec)) + vec2 = QVector4D(1, 3, 4, 5) + self.assertFalse(qFuzzyCompare(vec, vec2)) + + def testQColorToTuple(self): + c = QColor(0, 0, 255) + c.setRgb(1, 2, 3) + self.assertEqual((1, 2, 3, 255), c.toTuple()) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_617.py b/sources/pyside6/tests/QtGui/bug_617.py new file mode 100644 index 000000000..d90d1e754 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_617.py @@ -0,0 +1,34 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QEvent +from PySide6.QtGui import QColor + + +class MyEvent(QEvent): + def __init__(self): + QEvent.__init__(self, QEvent.Type(999)) + + +class Bug617(unittest.TestCase): + def testRepr(self): + c = QColor.fromRgb(1, 2, 3, 4) + s = c.spec() + self.assertEqual(repr(s), repr(QColor.Rgb)) + + def testOutOfBounds(self): + e = MyEvent() + self.assertEqual(repr(e.type()), "<Type.999: 999>") + + +if __name__ == "__main__": + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_652.py b/sources/pyside6/tests/QtGui/bug_652.py new file mode 100644 index 000000000..17d6c3b77 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_652.py @@ -0,0 +1,47 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import gc +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QTextBlockUserData, QTextCursor, QTextDocument + + +class MyData(QTextBlockUserData): + def __init__(self, data): + super().__init__() + self.data = data + + def getMyNiceData(self): + return self.data + + +class TestBug652(unittest.TestCase): + """Segfault when using QTextBlock::setUserData due to missing ownership transfer""" + def testIt(self): + td = QTextDocument() + tc = QTextCursor(td) + tc.insertText("Hello world") + heyHo = "hey ho!" + tc.block().setUserData(MyData(heyHo)) + self.assertEqual(type(tc.block().userData()), MyData) + self.assertEqual(tc.block().userData().getMyNiceData(), heyHo) + + del tc + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + tc = QTextCursor(td) + blk = tc.block() + self.assertEqual(type(blk.userData()), MyData) + self.assertEqual(blk.userData().getMyNiceData(), heyHo) + + +if __name__ == "__main__": + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_660.py b/sources/pyside6/tests/QtGui/bug_660.py new file mode 100644 index 000000000..4ab8e9f19 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_660.py @@ -0,0 +1,40 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QStandardItemModel, QStandardItem + + +class MyItemModel(QStandardItemModel): + def __init__(self, parent=None): + super().__init__(parent) + self.appendRow([QStandardItem('Item 1'),]) + + def mimeTypes(self): + mtypes = super(MyItemModel, self).mimeTypes() + mtypes.append('application/my-form') + return mtypes + + def mimeData(self, indexes): + self.__mimedata = super(MyItemModel, self).mimeData(indexes) + self.__mimedata.setData('application/my-form', bytes('hi', "UTF-8")) + return self.__mimedata + + +class TestBug660(unittest.TestCase): + '''QMimeData type deleted prematurely when overriding mime-type in QStandardItemModel drag and drop''' + def testIt(self): + model = MyItemModel() + model.mimeData([model.index(0, 0)]) # if it doesn't raise an exception it's all right! + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_716.py b/sources/pyside6/tests/QtGui/bug_716.py new file mode 100644 index 000000000..90d78ea89 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_716.py @@ -0,0 +1,20 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util")) +from init_paths import init_test_paths +init_test_paths() + +from PySide6.QtCore import Qt, QPersistentModelIndex, QStringListModel + +if __name__ == '__main__': + stringListModel = QStringListModel(['one', 'two']) + idx = stringListModel.index(1, 0) + persistentModelIndex = QPersistentModelIndex(idx) + stringListModel.data(persistentModelIndex, Qt.DisplayRole) + diff --git a/sources/pyside6/tests/QtGui/bug_740.py b/sources/pyside6/tests/QtGui/bug_740.py new file mode 100644 index 000000000..ece314cc8 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_740.py @@ -0,0 +1,25 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtCore import QSize +from PySide6.QtGui import QBitmap, QImage + + +class TestQBitmap(UsesQApplication): + def testFromDataMethod(self): + dataBits = bytes('\x38\x28\x38\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xfe\xfe\x7c\x7c\x38\x38\x10\x10', "UTF-8") + bim = QBitmap.fromData(QSize(8, 48), dataBits, QImage.Format_Mono) # missing function + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_743.py b/sources/pyside6/tests/QtGui/bug_743.py new file mode 100644 index 000000000..a870e4bf1 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_743.py @@ -0,0 +1,27 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QMatrix4x4 + + +class TestQMatrix(unittest.TestCase): + def testOperator(self): + m = QMatrix4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) + v = 1 + for x in range(4): + for y in range(4): + self.assertEqual(m[x, y], v) + v += 1 + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_785.py b/sources/pyside6/tests/QtGui/bug_785.py new file mode 100644 index 000000000..04425f063 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_785.py @@ -0,0 +1,41 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QItemSelection +from PySide6.QtGui import QStandardItemModel, QStandardItem + + +class Bug324(unittest.TestCase): + def testOperators(self): + model = QStandardItemModel() + for i in range(100): + model.appendRow(QStandardItem(f"Item: {i}")) + + first = model.index(0, 0) + second = model.index(10, 0) + third = model.index(20, 0) + fourth = model.index(30, 0) + + sel = QItemSelection(first, second) + sel2 = QItemSelection() + sel2.select(third, fourth) + + sel3 = sel + sel2 # check operator + + self.assertEqual(len(sel3), 2) + sel4 = sel + sel4 += sel2 # check operator += + self.assertEqual(len(sel4), 2) + self.assertEqual(sel4, sel3) + + +if __name__ == "__main__": + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_991.py b/sources/pyside6/tests/QtGui/bug_991.py new file mode 100644 index 000000000..e74adc198 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_991.py @@ -0,0 +1,28 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QObject +from PySide6.QtGui import QPen, QBrush + + +class TestBug991 (unittest.TestCase): + def testReprFunction(self): + reprPen = repr(QPen()) + self.assertTrue(reprPen.startswith("<PySide6.QtGui.QPen")) + reprBrush = repr(QBrush()) + self.assertTrue(reprBrush.startswith("<PySide6.QtGui.QBrush")) + reprObject = repr(QObject()) + self.assertTrue(reprObject.startswith("<PySide6.QtCore.QObject")) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/bug_PYSIDE-344.py b/sources/pyside6/tests/QtGui/bug_PYSIDE-344.py new file mode 100644 index 000000000..6519eef61 --- /dev/null +++ b/sources/pyside6/tests/QtGui/bug_PYSIDE-344.py @@ -0,0 +1,49 @@ +#!/usr/bin/python +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Test cases for PYSIDE-344, imul/idiv are used instead of mul/div, modifying the argument passed in''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QMargins, QPoint, QPointF, QSize, QSizeF +from PySide6.QtGui import (QMatrix4x4, QQuaternion, QTransform, QVector2D, + QVector3D, QVector4D) + + +def testList(): + return [QPoint(10, 10), QPointF(1, 1), QSize(10, 10), QSizeF(1, 1), + QMargins(10, 10, 10, 10), + QTransform(), QMatrix4x4(), + QVector2D(1, 1), QVector3D(1, 1, 1), QVector4D(1, 1, 1, 1), + QQuaternion(1, 1, 1, 1)] + + +class TestMulDiv(unittest.TestCase): + + def testMultiplication(self): + fails = '' + for a in testList(): + mul = (a * 2) + if a == mul: + fails += ' ' + type(a).__name__ + self.assertEqual(fails, '') + + def testDivision(self): + fails = '' + for a in testList(): + div = (a * 2) + if a == div: + fails += ' ' + type(a).__name__ + self.assertEqual(fails, '') + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/deepcopy_test.py b/sources/pyside6/tests/QtGui/deepcopy_test.py new file mode 100644 index 000000000..9a13eb485 --- /dev/null +++ b/sources/pyside6/tests/QtGui/deepcopy_test.py @@ -0,0 +1,140 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +from copy import deepcopy +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QPoint +from PySide6.QtGui import QMatrix2x2, QMatrix2x3, QMatrix2x4 +from PySide6.QtGui import QMatrix3x2, QMatrix3x3, QMatrix3x4 +from PySide6.QtGui import QMatrix4x2, QMatrix4x3, QMatrix4x4 +from PySide6.QtGui import QVector2D, QVector3D, QVector4D +from PySide6.QtGui import QColor, QTransform, QKeySequence, QQuaternion +from PySide6.QtGui import QPolygon + + +class DeepCopyHelper: + def testCopy(self): + copy = deepcopy([self.original])[0] + self.assertTrue(copy is not self.original) + self.assertEqual(copy, self.original) + + +class DeepCopyColorHelperF: + def testCopy(self): + copy = deepcopy([self.original])[0] + self.assertTrue(copy is not self.original) + self.assertEqual(copy.spec(), self.original.spec()) + # impossible to compare float point + # self.assertEqual(copy, self.original) + + +class QColorDeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QColor("red") + + +class QColorRGBDeepCopy(DeepCopyColorHelperF, unittest.TestCase): + def setUp(self): + self.original = QColor.fromRgbF(0.2, 0.3, 0.4, 0.5) + + +class QColorHSLDeepCopy(DeepCopyColorHelperF, unittest.TestCase): + def setUp(self): + self.original = QColor.fromHslF(0.2, 0.3, 0.4, 0.5) + + +class QColorHSVDeepCopy(DeepCopyColorHelperF, unittest.TestCase): + def setUp(self): + self.original = QColor.fromHsvF(0.2, 0.3, 0.4, 0.5) + + +class QColorCMYKDeepCopy(DeepCopyColorHelperF, unittest.TestCase): + def setUp(self): + self.original = QColor.fromCmykF(0.2, 0.3, 0.4, 0.5, 0.6) + + +class QTransformDeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QTransform(1, 2, 3, 4, 5, 6, 7, 8, 9) + + +class QKeySequenceDeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QKeySequence("Ctrl+P") + + +class QQuaternionDeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QQuaternion(1, 2, 3, 4) + + +class QVector2DDeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QVector2D(1, 2) + + +class QVector3DDeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QVector3D(1, 2, 3) + + +class QVector4DDeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QVector4D(1, 2, 3, 4) + + +class QPolygonDeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QPolygon([QPoint(1, 2), QPoint(3, 4), QPoint(5, 6)]) + + +# Avoid these tests until get gcc fixed +# Related bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43247 +""" +class QMatrix2x2DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix2x2([1, 2, 3, 4]) + +class QMatrix2x3DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix2x3([1, 2, 3, 4, 5, 6]) + +class QMatrix2x4DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix2x4([1, 2, 3, 4, 5, 6, 7, 8]) + +class QMatrix3x2DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix3x2([1, 2, 3, 4, 5, 6]) + +class QMatrix3x3DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix3x3([1, 2, 3, 4, 5, 6, 7, 8, 9]) + +class QMatrix3x4DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix3x4([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) + +class QMatrix4x2DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix4x2([1, 2, 3, 4, 5, 6, 7, 8]) + +class QMatrix4x3DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix4x3([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) + +class QMatrix4x4DeepCopy(DeepCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix4x4([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) +""" + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/event_filter_test.py b/sources/pyside6/tests/QtGui/event_filter_test.py new file mode 100644 index 000000000..01d8fbc02 --- /dev/null +++ b/sources/pyside6/tests/QtGui/event_filter_test.py @@ -0,0 +1,51 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtCore import QObject, QEvent +from PySide6.QtGui import QWindow + + +class MyFilter(QObject): + def eventFilter(self, obj, event): + if event.type() == QEvent.KeyPress: + pass + return QObject.eventFilter(self, obj, event) + + +class EventFilter(UsesQApplication): + @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount") + def testRefCount(self): + o = QObject() + filt = MyFilter() + o.installEventFilter(filt) + self.assertEqual(sys.getrefcount(o), 2) + + o.installEventFilter(filt) + self.assertEqual(sys.getrefcount(o), 2) + + o.removeEventFilter(filt) + self.assertEqual(sys.getrefcount(o), 2) + + def testObjectDestructorOrder(self): + w = QWindow() + filt = MyFilter() + filt.app = self.app + w.installEventFilter(filt) + w.show() + w.close() + w = None + self.assertTrue(True) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/float_to_int_implicit_conversion_test.py b/sources/pyside6/tests/QtGui/float_to_int_implicit_conversion_test.py new file mode 100644 index 000000000..ba438f8e0 --- /dev/null +++ b/sources/pyside6/tests/QtGui/float_to_int_implicit_conversion_test.py @@ -0,0 +1,45 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Test cases for QImage''' + +import gc +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QImage, qRgb + +from helper.usesqapplication 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 + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + 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/sources/pyside6/tests/QtGui/pyside_reload_test.py b/sources/pyside6/tests/QtGui/pyside_reload_test.py new file mode 100644 index 000000000..1ac65f709 --- /dev/null +++ b/sources/pyside6/tests/QtGui/pyside_reload_test.py @@ -0,0 +1,63 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import importlib +import importlib.util +import os +import shutil +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + + +orig_path = os.path.join(os.path.dirname(__file__)) +workdir = os.getcwd() +src = os.path.normpath(os.path.join(orig_path, '..', 'QtWidgets', 'test_module_template.py')) +dst = os.path.join(workdir, 'test_module.py') +shutil.copyfile(src, dst) +sys.path.append(workdir) + + +def reload_module(moduleName): + importlib.reload(moduleName) + + +def increment_module_value(): + modfile = open(dst, 'a') + modfile.write('Sentinel.value += 1' + os.linesep) + modfile.flush() + modfile.close() + if not sys.dont_write_bytecode: + import importlib.util + cacheFile = importlib.util.cache_from_source(dst) + os.remove(cacheFile) + + +class TestModuleReloading(unittest.TestCase): + + def testModuleReloading(self): + '''Test module reloading with on-the-fly modifications.''' + + import test_module + self.assertEqual(test_module.Sentinel.value, 10) + + increment_module_value() + reload_module(sys.modules['test_module']) + self.assertEqual(test_module.Sentinel.value, 11) + + reload_module(sys.modules['test_module']) + self.assertEqual(test_module.Sentinel.value, 11) + + increment_module_value() + reload_module(sys.modules['test_module']) + self.assertEqual(test_module.Sentinel.value, 12) + + +if __name__ == "__main__": + unittest.main() + + diff --git a/sources/pyside6/tests/QtGui/qbrush_test.py b/sources/pyside6/tests/QtGui/qbrush_test.py new file mode 100644 index 000000000..69262328b --- /dev/null +++ b/sources/pyside6/tests/QtGui/qbrush_test.py @@ -0,0 +1,43 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Test cases for QBrush''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import Qt +from PySide6.QtGui import QColor, QBrush, QConicalGradient + +from helper.usesqapplication 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) + + def testGradient(self): + """Test type discovery on class hierarchies with non-virtual + destructors by specifying a polymorphic-id-expression without + polymorphic-name-function.""" + gradient = QConicalGradient() + brush = QBrush(gradient) + self.assertEqual(type(brush.gradient()), type(gradient)) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qcolor_reduce_test.py b/sources/pyside6/tests/QtGui/qcolor_reduce_test.py new file mode 100644 index 000000000..609951be6 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qcolor_reduce_test.py @@ -0,0 +1,44 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import pickle +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QColor + + +class TestQColor (unittest.TestCase): + def reduceColor(self, c): + p = pickle.dumps(c) + c2 = pickle.loads(p) + self.assertEqual(c.spec(), c2.spec()) + self.assertEqual(c, c2) + + def testReduceEmpty(self): + self.reduceColor(QColor()) + + def testReduceString(self): + self.reduceColor(QColor('gray')) + + def testReduceRGB(self): + self.reduceColor(QColor.fromRgbF(0.1, 0.2, 0.3, 0.4)) + + def testReduceCMYK(self): + self.reduceColor(QColor.fromCmykF(0.1, 0.2, 0.3, 0.4, 0.5)) + + def testReduceHsl(self): + self.reduceColor(QColor.fromHslF(0.1, 0.2, 0.3, 0.4)) + + def testReduceHsv(self): + self.reduceColor(QColor.fromHsvF(0.1, 0.2, 0.3, 0.4)) + + +if __name__ == "__main__": + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qcolor_test.py b/sources/pyside6/tests/QtGui/qcolor_test.py new file mode 100644 index 000000000..bbd558f10 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qcolor_test.py @@ -0,0 +1,111 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import colorsys +import gc +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +import PySide6 +from PySide6.QtCore import Qt +from PySide6.QtGui import QColor, QColorConstants + + +class QColorGetTest(unittest.TestCase): + + def setUp(self): + self.color = QColor(20, 40, 60, 80) + + def testGetRgb(self): + self.assertEqual(self.color.getRgb(), (20, 40, 60, 80)) + + def testGetHslF(self): + hls = colorsys.rgb_to_hls(20.0 / 255, 40.0 / 255, 60.0 / 255) + hsla = hls[0], hls[2], hls[1], self.color.alphaF() + for x, y in zip(self.color.getHslF(), hsla): # Due to rounding problems + self.assertTrue(x - y < 1 / 100000.0) + + def testGetHsv(self): + hsv = colorsys.rgb_to_hsv(20.0 / 255, 40.0 / 255, 60.0 / 255) + hsva = int(hsv[0] * 360.0), int(hsv[1] * 255), int(hsv[2] * 256), self.color.alpha() + self.assertEqual(self.color.getHsv(), hsva) + + def testGetCmyk(self): # not supported by colorsys + self.assertEqual(self.color.getCmyk(), (170, 85, 0, 195, 80)) + + def testGetCmykF(self): # not supported by colorsys + for x, y in zip(self.color.getCmykF(), (170 / 255.0, 85 / 255.0, 0, 195 / 255.0, 80 / 255.0)): + self.assertTrue(x - y < 1 / 10000.0) + + +class QColorQRgbConstructor(unittest.TestCase): + '''QColor(QRgb) constructor''' + # Affected by bug #170 - QColor(QVariant) coming before QColor(uint) + # in overload sorting + + def testBasic(self): + '''QColor(QRgb)''' + color = QColor(255, 0, 0) + # QRgb format #AARRGGBB + rgb = 0x00FF0000 + self.assertEqual(QColor(rgb), color) + + +class QColorEqualGlobalColor(unittest.TestCase): + + def testEqualGlobalColor(self): + '''QColor == Qt::GlobalColor''' + self.assertEqual(QColor(255, 0, 0), Qt.red) + + +class QColorCopy(unittest.TestCase): + + def testDeepCopy(self): + '''QColor deepcopy''' + + from copy import deepcopy + + original = QColor(0, 0, 255) + copy = deepcopy([original])[0] + + self.assertTrue(original is not copy) + self.assertEqual(original, copy) + del original + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(copy, QColor(0, 0, 255)) + + def testEmptyCopy(self): + from copy import deepcopy + + original = QColor() + copy = deepcopy([original])[0] + self.assertTrue(original is not copy) + self.assertEqual(original, copy) + del original + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + self.assertEqual(copy, QColor()) + + +class QColorRepr(unittest.TestCase): + def testReprFunction(self): + # QColorConstants are disabled for MSVC/5.15, fixme: Check Qt 6 + c = QColorConstants.Yellow if sys.platform != 'win32' else QColor(100, 120, 200) + c2 = eval(c.__repr__()) + self.assertEqual(c, c2) + + def testStrFunction(self): + c = QColor('red') + c2 = eval(c.__str__()) + self.assertEqual(c, c2) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qcursor_test.py b/sources/pyside6/tests/QtGui/qcursor_test.py new file mode 100644 index 000000000..1494fe370 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qcursor_test.py @@ -0,0 +1,29 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Test for Bug 630 - Fails to resolve overload for QCursor(QBitmap, QBitmap, int, int) +http://bugs.openbossa.org/show_bug.cgi?id=630 +''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QBitmap, QCursor, QPixmap +from helper.usesqapplication import UsesQApplication + + +class TestQCursor(UsesQApplication): + def testQCursorConstructor(self): + bmp = QBitmap(16, 16) + cursor = QCursor(bmp, bmp, 16, 16) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qdatastream_gui_operators_test.py b/sources/pyside6/tests/QtGui/qdatastream_gui_operators_test.py new file mode 100644 index 000000000..f2c86abf7 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qdatastream_gui_operators_test.py @@ -0,0 +1,45 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QDataStream, QByteArray, QIODevice, Qt +from PySide6.QtGui import QPixmap, QColor + +from helper.usesqapplication import UsesQApplication + + +class QPixmapQDatastream(UsesQApplication): + '''QDataStream <<>> QPixmap''' + + def setUp(self): + super(QPixmapQDatastream, self).setUp() + self.source_pixmap = QPixmap(100, 100) + # PYSIDE-1533: Use Qt.transparent to force Format_ARGB32_Premultiplied + # when converting to QImage in any case. + self.source_pixmap.fill(Qt.transparent) + self.output_pixmap = QPixmap() + self.buffer = QByteArray() + self.read_stream = QDataStream(self.buffer, QIODevice.ReadOnly) + self.write_stream = QDataStream(self.buffer, QIODevice.WriteOnly) + + def testStream(self): + self.write_stream << self.source_pixmap + + self.read_stream >> self.output_pixmap + + image = self.output_pixmap.toImage() + pixel = image.pixel(10, 10) + self.assertEqual(pixel, QColor(Qt.transparent).rgba()) + self.assertEqual(self.source_pixmap.toImage(), image) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qdesktopservices_test.py b/sources/pyside6/tests/QtGui/qdesktopservices_test.py new file mode 100644 index 000000000..8d578152d --- /dev/null +++ b/sources/pyside6/tests/QtGui/qdesktopservices_test.py @@ -0,0 +1,27 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Unit tests for QDesktopServices''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QDesktopServices +from PySide6.QtCore import QUrl + + +class QDesktopServicesTest(unittest.TestCase): + def testOpenUrl(self): + # At the bare minimum check that they return false for invalid url's + url = QUrl() + self.assertEqual(QDesktopServices.openUrl(url), False) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qfont_test.py b/sources/pyside6/tests/QtGui/qfont_test.py new file mode 100644 index 000000000..f81d47ec6 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qfont_test.py @@ -0,0 +1,35 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QFont +from helper.usesqapplication import UsesQApplication + + +class QFontTest(UsesQApplication): + + def testStringConstruction(self): + """PYSIDE-1685: Test that passing str to QFont works after addding + QFont(QStringList) by qtbase/d8602ce58b6ef268be84b9aa0166b0c3fa6a96e8""" + font_name = 'Times Roman' + font = QFont(font_name) + families = font.families() + self.assertEqual(len(families), 1) + self.assertEqual(families[0], font_name) + + font = QFont([font_name]) + families = font.families() + self.assertEqual(len(families), 1) + self.assertEqual(families[0], font_name) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qfontmetrics_test.py b/sources/pyside6/tests/QtGui/qfontmetrics_test.py new file mode 100644 index 000000000..98c4c8f96 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qfontmetrics_test.py @@ -0,0 +1,215 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Tests for inject codes and modifications on QFontMetrics + and QFontMetricsF''' + +import gc +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QFont, QFontMetrics, QFontMetricsF +from PySide6.QtCore import QRect, QRectF, Qt, QSize, QSizeF +from helper.usesqapplication import UsesQApplication + + +class QFontMetricsTest(UsesQApplication): + '''Base class for QFontMetrics tests''' + + def setUp(self): + super(QFontMetricsTest, self).setUp() + self.font = QFont() + self.metrics = QFontMetrics(self.font) + + def tearDown(self): + del self.metrics + del self.font + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + super(QFontMetricsTest, self).tearDown() + + +class BoundingRectTest(QFontMetricsTest): + '''Tests for QFontMetrics.boundingRect inject code''' + + def testIntDefault(self): + '''QFontMetrics.boundingRect(int, int, int, int, ...) - default args''' + rect = self.metrics.boundingRect(0, 0, 0, 0, + Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT') + self.assertTrue(isinstance(rect, QRect)) + + def testIntWithArg(self): + '''QFontMetrics.boundingRect(int, int, int, int, ...) - single arg''' + rect = self.metrics.boundingRect(0, 0, 0, 0, + Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 2) + self.assertTrue(isinstance(rect, QRect)) + + def testIntWithFull(self): + '''QFontMetrics.boundingRect(int, int, int, int, ...) - all argss''' + rect = self.metrics.boundingRect(0, 0, 0, 0, + Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 20, [1, 2, 3, 4, 5]) + self.assertTrue(isinstance(rect, QRect)) + + def testIntTypeError(self): + '''QFontMetrics.boundingRect(int, int, int, int, ...) - type error''' + self.assertRaises(TypeError, self.metrics.boundingRect, 0, 0, 0, 0, + Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 20, ['aaaa', 'ase']) + + def testQRectDefault(self): + '''QFontMetrics.boundingRect(QRect, ...) - default args''' + arg = QRect(0, 0, 100, 200) + rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT') + self.assertTrue(isinstance(rect, QRect)) + + def testQRectWithArg(self): + '''QFontMetrics.boundingRect(QRect, ...) - only tabstops''' + arg = QRect(0, 0, 100, 200) + rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 2) + self.assertTrue(isinstance(rect, QRect)) + + def testQRectWithFull(self): + '''QFontMetrics.boundingRect(QRect, ...) - all arguments''' + arg = QRect(0, 0, 100, 200) + rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 20, + [1, 2, 3, 4, 5]) + self.assertTrue(isinstance(rect, QRect)) + + def testQRectTypeError(self): + '''QFontMetrics.boundingRect(QRect, ...) - type error''' + arg = QRect(0, 0, 100, 200) + self.assertRaises(TypeError, self.metrics.boundingRect, arg, + Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 20, ['aaaa', 'ase']) + + +class SizeTest(QFontMetricsTest): + '''Tests for QFontMetrics.size inject code''' + + def testDefault(self): + '''QFontMetrics.size - default arguments''' + size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine, + 'PySide by INdT') + self.assertTrue(isinstance(size, QSize)) + + def testWithTabStops(self): + '''QFontMetrics.size - only tabstops''' + size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine, + 'PySide by INdT', 2) + self.assertTrue(isinstance(size, QSize)) + + def testFull(self): + '''QFontMetrics.size - all arguments''' + size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine, + 'PySide by INdT', 2, [1, 2, 3, 4]) + self.assertTrue(isinstance(size, QSize)) + + def testTypeError(self): + '''QFontMetrics.size - type error''' + self.assertRaises(TypeError, self.metrics.size, + Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 20, ['aaaa', 'ase']) + + +class QFontMetricsFTest(UsesQApplication): + '''Base class for QFontMetrics tests''' + + def setUp(self): + super(QFontMetricsFTest, self).setUp() + self.font = QFont() + self.metrics = QFontMetricsF(self.font) + + def tearDown(self): + del self.metrics + del self.font + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + super(QFontMetricsFTest, self).tearDown() + + +class FBoundingRectTest(QFontMetricsFTest): + '''Tests for QFontMetricsF.boundingRect inject code''' + + def testQRectDefault(self): + '''QFontMetricsF.boundingRect(QRectF, ...) - default args''' + arg = QRectF(0, 0, 100, 200) + rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT') + self.assertTrue(isinstance(rect, QRectF)) + + def testQRectWithArg(self): + '''QFontMetricsF.boundingRect(QRectF, ...) - only tabstops''' + arg = QRectF(0, 0, 100, 200) + rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 2) + self.assertTrue(isinstance(rect, QRectF)) + + def testQRectWithFull(self): + '''QFontMetricsF.boundingRect(QRectF, ...) - all arguments''' + arg = QRectF(0, 0, 100, 200) + rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 20, + [1, 2, 3, 4, 5]) + self.assertTrue(isinstance(rect, QRectF)) + + def testQRectTypeError(self): + '''QFontMetricsF.boundingRect(QRectF, ...) - type error''' + arg = QRectF(0, 0, 100, 200) + self.assertRaises(TypeError, self.metrics.boundingRect, arg, + Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 20, ['aaaa', 'ase']) + + +class FSizeTest(QFontMetricsFTest): + '''Tests for QFontMetricsF.size inject code''' + + def testDefault(self): + '''QFontMetricsF.size - default arguments''' + size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine, + 'PySide by INdT') + self.assertTrue(isinstance(size, QSizeF)) + + def testWithTabStops(self): + '''QFontMetricsF.size - only tabstops''' + size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine, + 'PySide by INdT', 2) + self.assertTrue(isinstance(size, QSizeF)) + + def testFull(self): + '''QFontMetricsF.size - all arguments''' + size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine, + 'PySide by INdT', 2, [1, 2, 3, 4]) + self.assertTrue(isinstance(size, QSizeF)) + + def testTypeError(self): + '''QFontMetricsF.size - type error''' + self.assertRaises(TypeError, self.metrics.size, + Qt.TextExpandTabs | Qt.AlignLeft, + 'PySide by INdT', 20, ['aaaa', 'ase']) + + +class QCharTest(QFontMetricsFTest): + + def testBoundingRect(self): + retCh = self.metrics.boundingRectChar('a') + self.assertEqual(type(retCh), QRectF) + + def testWith(self): + retCh = self.metrics.horizontalAdvance('a') + self.assertTrue(retCh > 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qguiapplication_test.py b/sources/pyside6/tests/QtGui/qguiapplication_test.py new file mode 100644 index 000000000..a3d0942aa --- /dev/null +++ b/sources/pyside6/tests/QtGui/qguiapplication_test.py @@ -0,0 +1,23 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QGuiApplication + + +class TestQGuiApplication(unittest.TestCase): + def testNoArguments(self): + app = QGuiApplication() + self.assertIsInstance(app, QGuiApplication) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qicon_test.py b/sources/pyside6/tests/QtGui/qicon_test.py new file mode 100644 index 000000000..18ef3d815 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qicon_test.py @@ -0,0 +1,48 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.timedqguiapplication import TimedQGuiApplication +from PySide6.QtGui import QIcon + + +class QIconCtorWithNoneTest(TimedQGuiApplication): + '''Test made by seblin, see Bug #944: http://bugs.pyside.org/show_bug.cgi?id=944''' + + def testQIconCtorWithNone(self): + icon = QIcon(None) + pixmap = icon.pixmap(48, 48) + self.app.exec() + + +PIX_PATH = os.fspath(Path(__file__).resolve().parents[2] + / "doc/tutorials/basictutorial/icons.png") + + +class QIconAddPixmapTest(TimedQGuiApplication): + '''PYSIDE-1669: check that addPixmap works''' + + def testQIconSetPixmap(self): + icon = QIcon() + icon.addPixmap(PIX_PATH) + sizes = icon.availableSizes() + self.assertTrue(sizes) + + def testQIconSetPixmapPathlike(self): + icon = QIcon() + pix_path = Path(PIX_PATH) + icon.addPixmap(pix_path) + sizes = icon.availableSizes() + self.assertTrue(sizes) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qimage_test.py b/sources/pyside6/tests/QtGui/qimage_test.py new file mode 100644 index 000000000..5912bf318 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qimage_test.py @@ -0,0 +1,56 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Test cases for QImage''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QImage +from helper.usesqapplication import UsesQApplication +from xpm_data import xpm + + +class QImageTest(UsesQApplication): + '''Test case for calling setPixel with float as argument''' + + def testQImageStringBuffer(self): + '''Test if the QImage signatures receiving string buffers exist.''' + file = Path(__file__).resolve().parent / 'sample.png' + self.assertTrue(file.is_file()) + img0 = QImage(file) + + # btw let's test the bits() method + img1 = QImage(img0.bits(), img0.width(), img0.height(), img0.format()) + img1.setColorSpace(img0.colorSpace()) + self.assertEqual(img0, img1) + img2 = QImage(img0.bits(), img0.width(), img0.height(), img0.bytesPerLine(), img0.format()) + img2.setColorSpace(img0.colorSpace()) + self.assertEqual(img0, img2) + + ## test scanLine method + data1 = img0.scanLine(0) + data2 = img1.scanLine(0) + self.assertEqual(data1, data2) + + def testEmptyBuffer(self): + img = QImage(bytes('', "UTF-8"), 100, 100, QImage.Format_ARGB32) + + def testEmptyStringAsBuffer(self): + img = QImage(bytes('', "UTF-8"), 100, 100, QImage.Format_ARGB32) + + def testXpmConstructor(self): + img = QImage(xpm) + self.assertFalse(img.isNull()) + self.assertEqual(img.width(), 27) + self.assertEqual(img.height(), 22) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qimage_win_test.py b/sources/pyside6/tests/QtGui/qimage_win_test.py new file mode 100644 index 000000000..2d9cb96f1 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qimage_win_test.py @@ -0,0 +1,41 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Test cases for QImage/Windows''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import Qt +from PySide6.QtGui import QImage +from helper.usesqapplication import UsesQApplication + + +def create_image(): + result = QImage(20, 20, QImage.Format_RGB32) + result.fill(Qt.white) + return result + + +class QImageWinTest(UsesQApplication): + + def test_to_hbitmap(self): + """Test conversion to/from a Windows HBITMAP.""" + + image = create_image() + hbitmap = image.toHBITMAP() + self.assertTrue(hbitmap > 0) + + image2 = QImage.fromHBITMAP(hbitmap) + image2.setColorSpace(image.colorSpace()) + self.assertEqual(image, image2) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qitemselection_test.py b/sources/pyside6/tests/QtGui/qitemselection_test.py new file mode 100644 index 000000000..179bff745 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qitemselection_test.py @@ -0,0 +1,31 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtCore import QItemSelection +from PySide6.QtGui import QStandardItemModel + + +class QItemSelectionTest(UsesQApplication): + def testLen(self): + model = QStandardItemModel(2, 2) + model.insertRow(0) + model.insertRow(1) + model.insertColumn(0) + model.insertColumn(1) + selection = QItemSelection(model.index(0, 0), model.index(1, 1)) + self.assertEqual(len(selection), 1) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qkeysequence_test.py b/sources/pyside6/tests/QtGui/qkeysequence_test.py new file mode 100644 index 000000000..3d72fb50a --- /dev/null +++ b/sources/pyside6/tests/QtGui/qkeysequence_test.py @@ -0,0 +1,36 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import Qt +from PySide6.QtGui import QKeySequence, qt_set_sequence_auto_mnemonic + +from helper.usesqapplication import UsesQApplication + + +class QKeySequenceTest(UsesQApplication): + + def testGetItemOperator(self): + # bug #774 + # PYSIDE-1735: Remapped from Qt.Modifier to Qt.KeyboardModifier + # Note that Qt.(Keyboard)?Modifier will be no longer IntFlag. + ks = QKeySequence(Qt.ShiftModifier, Qt.ControlModifier, Qt.Key_P, Qt.Key_R) + self.assertEqual(ks[0].keyboardModifiers(), Qt.ShiftModifier) + self.assertEqual(ks[1].keyboardModifiers(), Qt.ControlModifier) + self.assertEqual(ks[2].key(), Qt.Key_P) + self.assertEqual(ks[3].key(), Qt.Key_R) + + def testAutoMnemonic(self): + qt_set_sequence_auto_mnemonic(True) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qpainter_test.py b/sources/pyside6/tests/QtGui/qpainter_test.py new file mode 100644 index 000000000..103b91ad6 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qpainter_test.py @@ -0,0 +1,115 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import gc +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtGui import QPainter, QLinearGradient, QImage +from PySide6.QtCore import QLine, QLineF, QPoint, QPointF, QRect, QRectF, Qt + + +try: + import numpy as np + HAVE_NUMPY = True +except ModuleNotFoundError: + HAVE_NUMPY = False + + +class QPainterDrawText(UsesQApplication): + def setUp(self): + super(QPainterDrawText, self).setUp() + self.image = QImage(32, 32, QImage.Format_ARGB32) + self.painter = QPainter(self.image) + self.text = 'teste!' + + def tearDown(self): + del self.text + self.painter.end() + del self.painter + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + super(QPainterDrawText, self).tearDown() + + def testDrawText(self): + # bug #254 + rect = self.painter.drawText(100, 100, 100, 100, + Qt.AlignCenter | Qt.TextWordWrap, + self.text) + self.assertTrue(isinstance(rect, QRect)) + + def testDrawTextWithRect(self): + # bug #225 + rect = QRect(100, 100, 100, 100) + newRect = self.painter.drawText(rect, Qt.AlignCenter | Qt.TextWordWrap, + self.text) + + self.assertTrue(isinstance(newRect, QRect)) + + def testDrawTextWithRectF(self): + '''QPainter.drawText(QRectF, ... ,QRectF*) inject code''' + rect = QRectF(100, 52.3, 100, 100) + newRect = self.painter.drawText(rect, Qt.AlignCenter | Qt.TextWordWrap, + self.text) + + self.assertTrue(isinstance(newRect, QRectF)) + + def testDrawOverloads(self): + '''Calls QPainter.drawLines overloads, if something is + wrong Exception and chaos ensues. Bug #395''' + self.painter.drawLines([QLine(QPoint(0, 0), QPoint(1, 1))]) + self.painter.drawLines([QPoint(0, 0), QPoint(1, 1)]) + self.painter.drawLines([QPointF(0, 0), QPointF(1, 1)]) + self.painter.drawLines([QLineF(QPointF(0, 0), QPointF(1, 1))]) + self.painter.drawPoints([QPoint(0, 0), QPoint(1, 1)]) + self.painter.drawPoints([QPointF(0, 0), QPointF(1, 1)]) + self.painter.drawConvexPolygon([QPointF(10.0, 80.0), + QPointF(20.0, 10.0), + QPointF(80.0, 30.0), + QPointF(90.0, 70.0)]) + self.painter.drawConvexPolygon([QPoint(10.0, 80.0), + QPoint(20.0, 10.0), + QPoint(80.0, 30.0), + QPoint(90.0, 70.0)]) + self.painter.drawPolygon([QPointF(10.0, 80.0), + QPointF(20.0, 10.0), + QPointF(80.0, 30.0), + QPointF(90.0, 70.0)]) + self.painter.drawPolygon([QPoint(10.0, 80.0), + QPoint(20.0, 10.0), + QPoint(80.0, 30.0), + QPoint(90.0, 70.0)]) + self.painter.drawPolyline([QPointF(10.0, 80.0), + QPointF(20.0, 10.0), + QPointF(80.0, 30.0), + QPointF(90.0, 70.0)]) + self.painter.drawPolyline([QPoint(10.0, 80.0), + QPoint(20.0, 10.0), + QPoint(80.0, 30.0), + QPoint(90.0, 70.0)]) + if HAVE_NUMPY: + x = np.array([10.0, 20.0, 80.0, 90.0]) + y = np.array([80.0, 10.0, 30.0, 70.0]) + self.painter.drawPointsNp(x, y) + + +class SetBrushWithOtherArgs(UsesQApplication): + '''Using qpainter.setBrush with args other than QBrush''' + + def testSetBrushGradient(self): + image = QImage(32, 32, QImage.Format_ARGB32) + with QPainter(image) as painter: + gradient = QLinearGradient(0, 0, 0, 0) + painter.setBrush(gradient) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qpdfwriter_test.py b/sources/pyside6/tests/QtGui/qpdfwriter_test.py new file mode 100644 index 000000000..2dca2aca2 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qpdfwriter_test.py @@ -0,0 +1,32 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtGui import QPageLayout, QPageSize, QPdfWriter, QTextDocument +from PySide6.QtCore import QDir, QMarginsF, QTemporaryFile + + +class QPdfWriterTest(UsesQApplication): + + def testWrite(self): + temporaryFile = QTemporaryFile(QDir.tempPath() + "/pdfwriter_test_XXXXXX.pdf") + self.assertTrue(temporaryFile.open()) + pdfWriter = QPdfWriter(temporaryFile) + pdfWriter.setPageLayout(QPageLayout(QPageSize(QPageSize.A4), QPageLayout.Portrait, QMarginsF(10, 10, 10, 10))) + doc = QTextDocument("Some text") + doc.print_(pdfWriter) + temporaryFile.close() + self.assertTrue(temporaryFile.size() > 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qpen_test.py b/sources/pyside6/tests/QtGui/qpen_test.py new file mode 100644 index 000000000..7e8604606 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qpen_test.py @@ -0,0 +1,57 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication + +from PySide6.QtCore import Qt, QTimer +from PySide6.QtGui import QPen, QPainter, QRasterWindow + + +class Painting(QRasterWindow): + def __init__(self): + super().__init__() + self.penFromEnum = None + self.penFromInteger = None + + def paintEvent(self, event): + with QPainter(self) as painter: + painter.setPen(Qt.NoPen) + self.penFromEnum = painter.pen() + intVal = Qt.NoPen.value + painter.setPen(intVal) + self.penFromInteger = painter.pen() + QTimer.singleShot(20, self.close) + + +class QPenTest(UsesQApplication): + + def testCtorWithCreatedEnums(self): + '''A simple case of QPen creation using created enums.''' + width = 0 + style = Qt.PenStyle(0) + cap = Qt.PenCapStyle(0) + join = Qt.PenJoinStyle(0) + pen = QPen(Qt.blue, width, style, cap, join) + + def testSetPenWithPenStyleEnum(self): + '''Calls QPainter.setPen with both enum and integer. Bug #511.''' + w = Painting() + w.show() + w.setTitle("qpen_test") + self.app.exec() + self.assertEqual(w.penFromEnum.style(), Qt.NoPen) + self.assertEqual(w.penFromInteger.style(), Qt.SolidLine) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qpixelformat_test.py b/sources/pyside6/tests/QtGui/qpixelformat_test.py new file mode 100644 index 000000000..869d15952 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qpixelformat_test.py @@ -0,0 +1,40 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Unit test for QPixelFormat''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtCore import QSize, Qt +from PySide6.QtGui import QColor, QImage, QPixelFormat, qPixelFormatRgba + + +class QPixelFormatTest(UsesQApplication): + def test(self): + image = QImage(QSize(200, 200), QImage.Format_ARGB32) + image.fill(QColor(Qt.red)) + pixelFormat = image.pixelFormat() + print(pixelFormat.greenSize()) + self.assertEqual(pixelFormat.alphaSize(), 8) + self.assertEqual(pixelFormat.redSize(), 8) + self.assertEqual(pixelFormat.greenSize(), 8) + self.assertEqual(pixelFormat.blueSize(), 8) + self.assertEqual(pixelFormat.bitsPerPixel(), 32) + + def testHelpers(self): + format = qPixelFormatRgba(8, 8, 8, 8, QPixelFormat.UsesAlpha, + QPixelFormat.AtBeginning, QPixelFormat.Premultiplied, + QPixelFormat.UnsignedByte) + self.assertEqual(format.redSize(), 8) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qpixmap_constructor.py b/sources/pyside6/tests/QtGui/qpixmap_constructor.py new file mode 100644 index 000000000..dd658af52 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qpixmap_constructor.py @@ -0,0 +1,260 @@ +#!/usr/bin/python +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QPixmap + +from helper.usesqapplication import UsesQApplication + +xpm = [ + "27 22 206 2", + " c None", + ". c #FEFEFE", + "+ c #FFFFFF", + "@ c #F9F9F9", + "# c #ECECEC", + "$ c #D5D5D5", + "% c #A0A0A0", + "& c #767676", + "* c #525252", + "= c #484848", + "- c #4E4E4E", + "; c #555555", + "> c #545454", + ", c #5A5A5A", + "' c #4B4B4B", + ") c #4A4A4A", + "! c #4F4F4F", + "~ c #585858", + "{ c #515151", + "] c #4C4C4C", + "^ c #B1B1B1", + "/ c #FCFCFC", + "( c #FDFDFD", + "_ c #C1C1C1", + ": c #848484", + "< c #616161", + "[ c #5E5E5E", + "} c #CECECE", + "| c #E2E2E2", + "1 c #E4E4E4", + "2 c #DFDFDF", + "3 c #D2D2D2", + "4 c #D8D8D8", + "5 c #D4D4D4", + "6 c #E6E6E6", + "7 c #F1F1F1", + "8 c #838383", + "9 c #8E8E8E", + "0 c #8F8F8F", + "a c #CBCBCB", + "b c #CCCCCC", + "c c #E9E9E9", + "d c #F2F2F2", + "e c #EDEDED", + "f c #B5B5B5", + "g c #A6A6A6", + "h c #ABABAB", + "i c #BBBBBB", + "j c #B0B0B0", + "k c #EAEAEA", + "l c #6C6C6C", + "m c #BCBCBC", + "n c #F5F5F5", + "o c #FAFAFA", + "p c #B6B6B6", + "q c #F3F3F3", + "r c #CFCFCF", + "s c #FBFBFB", + "t c #CDCDCD", + "u c #DDDDDD", + "v c #999999", + "w c #F0F0F0", + "x c #2B2B2B", + "y c #C3C3C3", + "z c #A4A4A4", + "A c #D7D7D7", + "B c #E7E7E7", + "C c #6E6E6E", + "D c #9D9D9D", + "E c #BABABA", + "F c #AEAEAE", + "G c #898989", + "H c #646464", + "I c #BDBDBD", + "J c #CACACA", + "K c #2A2A2A", + "L c #212121", + "M c #B7B7B7", + "N c #F4F4F4", + "O c #737373", + "P c #828282", + "Q c #4D4D4D", + "R c #000000", + "S c #151515", + "T c #B2B2B2", + "U c #D6D6D6", + "V c #D3D3D3", + "W c #2F2F2F", + "X c #636363", + "Y c #A1A1A1", + "Z c #BFBFBF", + "` c #E0E0E0", + " . c #6A6A6A", + ".. c #050505", + "+. c #A3A3A3", + "@. c #202020", + "#. c #5F5F5F", + "$. c #B9B9B9", + "%. c #C7C7C7", + "&. c #D0D0D0", + "*. c #3E3E3E", + "=. c #666666", + "-. c #DBDBDB", + ";. c #424242", + ">. c #C2C2C2", + ",. c #1A1A1A", + "'. c #2C2C2C", + "). c #F6F6F6", + "!. c #AAAAAA", + "~. c #DCDCDC", + "{. c #2D2D2D", + "]. c #2E2E2E", + "^. c #A7A7A7", + "/. c #656565", + "(. c #333333", + "_. c #464646", + ":. c #C4C4C4", + "<. c #B8B8B8", + "[. c #292929", + "}. c #979797", + "|. c #EFEFEF", + "1. c #909090", + "2. c #8A8A8A", + "3. c #575757", + "4. c #676767", + "5. c #C5C5C5", + "6. c #7A7A7A", + "7. c #797979", + "8. c #989898", + "9. c #EEEEEE", + "0. c #707070", + "a. c #C8C8C8", + "b. c #111111", + "c. c #AFAFAF", + "d. c #474747", + "e. c #565656", + "f. c #E3E3E3", + "g. c #494949", + "h. c #5B5B5B", + "i. c #222222", + "j. c #353535", + "k. c #D9D9D9", + "l. c #0A0A0A", + "m. c #858585", + "n. c #E5E5E5", + "o. c #0E0E0E", + "p. c #9A9A9A", + "q. c #6F6F6F", + "r. c #868686", + "s. c #060606", + "t. c #1E1E1E", + "u. c #E8E8E8", + "v. c #A5A5A5", + "w. c #0D0D0D", + "x. c #030303", + "y. c #272727", + "z. c #131313", + "A. c #1F1F1F", + "B. c #757575", + "C. c #F7F7F7", + "D. c #414141", + "E. c #080808", + "F. c #6B6B6B", + "G. c #313131", + "H. c #C0C0C0", + "I. c #C9C9C9", + "J. c #0B0B0B", + "K. c #232323", + "L. c #434343", + "M. c #3D3D3D", + "N. c #282828", + "O. c #7C7C7C", + "P. c #252525", + "Q. c #3A3A3A", + "R. c #F8F8F8", + "S. c #1B1B1B", + "T. c #949494", + "U. c #3B3B3B", + "V. c #242424", + "W. c #383838", + "X. c #6D6D6D", + "Y. c #818181", + "Z. c #939393", + "`. c #9E9E9E", + " + c #929292", + ".+ c #7D7D7D", + "++ c #ADADAD", + "@+ c #DADADA", + "#+ c #919191", + "$+ c #E1E1E1", + "%+ c #BEBEBE", + "&+ c #ACACAC", + "*+ c #9C9C9C", + "=+ c #B3B3B3", + "-+ c #808080", + ";+ c #A8A8A8", + ">+ c #393939", + ",+ c #747474", + "'+ c #7F7F7F", + ")+ c #D1D1D1", + "!+ c #606060", + "~+ c #5C5C5C", + "{+ c #686868", + "]+ c #7E7E7E", + "^+ c #787878", + "/+ c #595959", + ". . . + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / . . + + ", + ". ( + _ : < [ & } | 1 2 $ 3 4 5 3 6 7 + + 8 9 + . + . ", + ". + 0 9 a ( 3 a b c d e c f g h i g j $ k + l m + . + ", + "+ 2 8 n o p | ( q r s . # t + + + u ^ v e w + x + + + ", + "+ y z . @ A k B 7 n + ( s | p 8 C D 2 E 4 + + F G + . ", + "# H I $ J G K L - M N . 2 O P Q R R S T U s s V W j + ", + "X Y Z @ o ` _ g ...+.( 4 @.#.m G $.%.7 &.X *.=.-.;.&.", + "Q >.C ,.'.} e + ).!.k + . + + . ~.{.> ].x f 7 ^./.k (.", + "_.:.4 @ <.[.}.|.1.2.+ + + >.} 4 B + ( @ _ 3.4.5.6.r 7.", + "3.8.9.~ 0.+ a.Q b.+ + c.d.#.=.$ |.b #.e.z ^ ; ^. .f.g.", + "-.h.+ i.S M + # p j.% n 9.5.k.H l.m.V ^.n.o.M + M p.q.", + "7 r.N s.1.R t.<.|.| u.v.~ w.x.E + s y.z.A.B.C.+ 5 D.q ", + ").p.2 E.0.9 F.%.O {._ @.+ + i { [ i.G.H.P I.+ s q.} + ", + ").p.6 J.R b.K.L.M.A.! b.g.K [.R M k + N.I + + >.O.+ . ", + ").8.9.N.P...R R R R E.t.W n.+ Q.R.6 @.| + . + S.+ + . ", + "n }.w T.U.B.<.i.@ Y + + U.+ c u V.= B B 7 u.W.c + . + ", + "N T.# + }.X.Y.,.8.F.8 Z.[.`. +.+}.4 ++@+O.< ~.+ ( . + ", + "d #+1 + _ ~.u.$+b $.y @+| $+%+I.&+k.h W +.9.+ ( . + . ", + "w 0 |.*+. >.<.=+++++p a.p -+;+5.k.>+,+@ + . . + . + + ", + "q '+9.R.^ I.t b %.I.)+4 $+n.I.,+ .|.+ . . . + . + + + ", + ". p !+( + + + + + + E 0. .-+8.f.+ + . . + + . + + + + ", + ". ( A ~+{+]+^+l > /+D f.c q . + . . + + . + + + + + + " +] + + +class QStringSequenceTest(UsesQApplication): + def testQPixmapConstructor(self): + pixmap1 = QPixmap(xpm) + self.assertFalse(pixmap1.isNull()) + self.assertEqual(pixmap1.width(), 27) + self.assertEqual(pixmap1.height(), 22) + + +if __name__ == "__main__": + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qpixmap_test.py b/sources/pyside6/tests/QtGui/qpixmap_test.py new file mode 100644 index 000000000..b80ae2ad5 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qpixmap_test.py @@ -0,0 +1,67 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtGui import QColor, QPixmap +from PySide6.QtCore import QFile, QIODevice, QObject, QSize, Qt + + +class QPixmapTest(UsesQApplication): + def testQVariantConstructor(self): + obj = QObject() + pixmap = QPixmap() + obj.setProperty('foo', pixmap) + self.assertEqual(type(obj.property('foo')), QPixmap) + + def testQSizeConstructor(self): + pixmap = QPixmap(QSize(10, 20)) + self.assertTrue(pixmap.size().height(), 20) + + def testQStringConstructor(self): + pixmap = QPixmap("Testing!") + + def testQPixmapLoadFromDataWithQFile(self): + f = QFile(os.path.join(os.path.dirname(__file__), 'sample.png')) + self.assertTrue(f.open(QIODevice.ReadOnly)) + data = f.read(f.size()) + f.close() + pixmap = QPixmap() + self.assertTrue(pixmap.loadFromData(data)) + + def testQPixmapLoadFromDataWithPython(self): + data = open(os.path.join(os.path.dirname(__file__), 'sample.png'), 'rb').read() + pixmap = QPixmap() + self.assertTrue(pixmap.loadFromData(data)) + + +class QPixmapToImage(UsesQApplication): + + def testFilledImage(self): + '''QPixmap.fill + toImage + image.pixel''' + pixmap = QPixmap(100, 200) + pixmap.fill(Qt.red) # Default Qt.white + + self.assertEqual(pixmap.height(), 200) + self.assertEqual(pixmap.width(), 100) + + image = pixmap.toImage() + + self.assertEqual(image.height(), 200) + self.assertEqual(image.width(), 100) + + pixel = image.pixel(10, 10) + self.assertEqual(pixel, QColor(Qt.red).rgba()) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qpixmapcache_test.py b/sources/pyside6/tests/QtGui/qpixmapcache_test.py new file mode 100644 index 000000000..2ecb439d3 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qpixmapcache_test.py @@ -0,0 +1,56 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtGui import QPixmapCache, QPixmap + + +class QPixmapCacheTest(UsesQApplication): + + def testWithString(self): + pm1 = QPixmap() + ok = QPixmapCache.find('img', pm1) + self.assertFalse(ok) + + self.assertEqual(QPixmapCache.find('img'), None) + + pm2 = QPixmap() + ok = QPixmapCache.insert('img', pm2) + self.assertTrue(ok) + + pm3 = QPixmap() + ok = QPixmapCache.find('img', pm3) + self.assertTrue(ok) + b1 = QPixmapCache.find('img').toImage().bits() + b2 = pm3.toImage().bits() + self.assertEqual(QPixmapCache.find('img').toImage().bits(), pm3.toImage().bits()) + + def testWithKey(self): + pm1 = QPixmap() + ok = QPixmapCache.find(QPixmapCache.Key(), pm1) + self.assertFalse(ok) + + self.assertEqual(QPixmapCache.find(QPixmapCache.Key()), None) + + pm2 = QPixmap() + key = QPixmapCache.insert(pm2) + + pm3 = QPixmap() + ok = QPixmapCache.find(key, pm3) + self.assertTrue(ok) + + self.assertEqual(QPixmapCache.find(key).toImage().bits(), pm3.toImage().bits()) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qpolygonf_test.py b/sources/pyside6/tests/QtGui/qpolygonf_test.py new file mode 100644 index 000000000..8a283fddc --- /dev/null +++ b/sources/pyside6/tests/QtGui/qpolygonf_test.py @@ -0,0 +1,42 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QPoint, QPointF +from PySide6.QtGui import QPolygon, QPolygonF + + +class QPolygonFNotIterableTest(unittest.TestCase): + """Test if a QPolygonF is iterable""" + + def testIt(self): + points = [] + for i in range(0, 4): + points.append(QPointF(float(i), float(i))) + + p = QPolygonF(points) + self.assertEqual(len(p), 4) + + i = 0 + for point in p: + self.assertEqual(int(point.x()), i) + self.assertEqual(int(point.y()), i) + i += 1 + + def testPolygonShiftOperators(self): + p = QPolygon() + self.assertEqual(len(p), 0) + p << QPoint(10, 20) << QPoint(20, 30) << [QPoint(20, 30), QPoint(40, 50)] + self.assertEqual(len(p), 4) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qradialgradient_test.py b/sources/pyside6/tests/QtGui/qradialgradient_test.py new file mode 100644 index 000000000..ebab42b15 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qradialgradient_test.py @@ -0,0 +1,41 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QRadialGradient +from PySide6.QtCore import QPointF + + +class QRadialGradientConstructor(unittest.TestCase): + def _compare(self, qptf, tpl): + self.assertEqual((qptf.x(), qptf.y()), tpl) + + def _assertValues(self, grad): + self._compare(grad.center(), (1.0, 2.0)) + self._compare(grad.focalPoint(), (3.0, 4.0)) + self.assertEqual(grad.radius(), 5.0) + + def testAllInt(self): + grad = QRadialGradient(1, 2, 5, 3, 4) + self._assertValues(grad) + + def testQPointF(self): + grad = QRadialGradient(QPointF(1, 2), 5, QPointF(3, 4)) + self._assertValues(grad) + + def testSetQPointF(self): + grad = QRadialGradient() + grad.setCenter(QPointF(1, 2)) + self._compare(grad.center(), (1.0, 2.0)) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qrasterwindow_test.py b/sources/pyside6/tests/QtGui/qrasterwindow_test.py new file mode 100644 index 000000000..4920902d5 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qrasterwindow_test.py @@ -0,0 +1,77 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Unit test for QBackingStore, QRasterWindow and QStaticText''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtCore import QPoint, QRect, QSize, QTimer, Qt +from PySide6.QtGui import (QColor, QPainter, QRasterWindow, QStaticText, + QTextCursor, QTextDocument, QAbstractTextDocumentLayout) + + +# Window using convenience class QRasterWindow +class StaticTextRasterWindow(QRasterWindow): + def __init__(self): + super().__init__() + self.text = QStaticText("QRasterWindow") + + def paintEvent(self, event): + clientRect = QRect(QPoint(0, 0), self.size()) + with QPainter(self) as painter: + painter.fillRect(clientRect, QColor(Qt.red)) + painter.drawStaticText(QPoint(10, 10), self.text) + + +class TextDocumentWindow(QRasterWindow): + """PYSIDE-2252, drawing with QAbstractTextDocumentLayout.PaintContext""" + + def __init__(self): + super().__init__() + self.m_document = QTextDocument() + self.m_document.setPlainText("bla bla") + + def paintEvent(self, event): + with QPainter(self) as painter: + clientRect = QRect(QPoint(0, 0), self.size()) + painter.fillRect(clientRect, QColor(Qt.white)) + ctx = QAbstractTextDocumentLayout.PaintContext() + ctx.clip = clientRect + + sel = QAbstractTextDocumentLayout.Selection() + cursor = QTextCursor(self.m_document) + cursor.movePosition(QTextCursor.Start) + cursor.movePosition(QTextCursor.NextWord, QTextCursor.KeepAnchor) + sel.cursor = cursor + sel.format.setForeground(Qt.red) + ctx.selections = [sel] + + self.m_document.documentLayout().draw(painter, ctx) + + +class QRasterWindowTest(UsesQApplication): + def test(self): + rasterWindow = StaticTextRasterWindow() + rasterWindow.setFramePosition(QPoint(100, 100)) + rasterWindow.resize(QSize(400, 400)) + rasterWindow.show() + + rasterWindow2 = TextDocumentWindow() + rasterWindow2.setFramePosition(rasterWindow.frameGeometry().topRight() + QPoint(20, 0)) + rasterWindow2.resize(QSize(400, 400)) + rasterWindow2.show() + + QTimer.singleShot(100, self.app.quit) + self.app.exec() + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qregion_test.py b/sources/pyside6/tests/QtGui/qregion_test.py new file mode 100644 index 000000000..df14fc3e0 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qregion_test.py @@ -0,0 +1,40 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QRegion +from PySide6.QtCore import QPoint, QRect, QSize +from helper.usesqapplication 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.assertTrue(ru.contains(QPoint(0, 0))) + self.assertTrue(ru.contains(QPoint(5, 5))) + self.assertTrue(ru.contains(QPoint(10, 10))) + self.assertTrue(ru.contains(QPoint(14, 14))) + + def testSequence(self): + region = QRegion() + region += QRect(QPoint(0, 0), QSize(10, 10)) + region += QRect(QPoint(10, 0), QSize(20, 20)) + self.assertEqual(len(region), 2) + for r in region: + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qshortcut_test.py b/sources/pyside6/tests/QtGui/qshortcut_test.py new file mode 100644 index 000000000..f2650589a --- /dev/null +++ b/sources/pyside6/tests/QtGui/qshortcut_test.py @@ -0,0 +1,60 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +''' Test the QShortcut constructor''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import Qt, QTimer +from PySide6.QtGui import QGuiApplication, QKeySequence, QShortcut, QWindow + + +class Foo(QWindow): + def __init__(self): + super().__init__() + self.ok = False + self.copy = False + + def slot_of_foo(self): + self.ok = True + + def slot_of_copy(self): + self.copy = True + + +class MyShortcut(QShortcut): + def __init__(self, keys, wdg, slot): + QShortcut.__init__(self, keys, wdg, slot) + + def emit_signal(self): + self.activated.emit() + + +class QAppPresence(unittest.TestCase): + + def testQShortcut(self): + self.qapp = QGuiApplication([]) + f = Foo() + + self.sc = MyShortcut(QKeySequence(Qt.Key_Return), f, f.slot_of_foo) + self.scstd = MyShortcut(QKeySequence.Copy, f, f.slot_of_copy) + QTimer.singleShot(0, self.init) + self.qapp.exec() + self.assertEqual(f.ok, True) + self.assertEqual(f.copy, True) + + def init(self): + self.sc.emit_signal() + self.scstd.emit_signal() + self.qapp.quit() + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qstandarditemmodel_test.py b/sources/pyside6/tests/QtGui/qstandarditemmodel_test.py new file mode 100644 index 000000000..55aca9113 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qstandarditemmodel_test.py @@ -0,0 +1,85 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import gc +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QObject +from PySide6.QtGui import QStandardItemModel, QStandardItem +from shiboken6 import Shiboken +from helper.usesqapplication import UsesQApplication + + +class QStandardItemModelTest(UsesQApplication): + + def setUp(self): + super(QStandardItemModelTest, self).setUp() + self.parent = QObject() + self.model = QStandardItemModel(0, 3, self.parent) + + def tearDown(self): + del self.parent + del self.model + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + super(QStandardItemModelTest, self).tearDown() + + def testInsertRow(self): + # bug #227 + self.model.insertRow(0) + + def testClear(self): + + model = QStandardItemModel() + root = model.invisibleRootItem() + model.clear() + self.assertFalse(Shiboken.isValid(root)) + + +class QStandardItemModelRef(UsesQApplication): + @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount") + def testRefCount(self): + model = QStandardItemModel(5, 5) + items = [] + for r in range(5): + row = [] + for c in range(5): + row.append(QStandardItem(f"{r},{c}")) + self.assertEqual(sys.getrefcount(row[c]), 2) + + model.insertRow(r, row) + + for c in range(5): + ref_after = sys.getrefcount(row[c]) + # check if the ref count was incremented after insertRow + self.assertEqual(ref_after, 3) + + items.append(row) + row = None + + for r in range(3): + my_row = model.takeRow(0) + my_row = None + for c in range(5): + # only rest 1 reference + self.assertEqual(sys.getrefcount(items[r][c]), 2) + + my_i = model.item(0, 0) + # ref(my_i) + parent_ref + items list ref + self.assertEqual(sys.getrefcount(my_i), 4) + + model.clear() + # ref(my_i) + self.assertEqual(sys.getrefcount(my_i), 3) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qstring_qkeysequence_test.py b/sources/pyside6/tests/QtGui/qstring_qkeysequence_test.py new file mode 100644 index 000000000..f68374263 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qstring_qkeysequence_test.py @@ -0,0 +1,42 @@ +#!/usr/bin/python +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Tests conversions of QString to and from QKeySequence.''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication + +from PySide6.QtGui import QAction, QKeySequence + + +class QStringQKeySequenceTest(UsesQApplication): + '''Tests conversions of QString to and from QKeySequence.''' + + def testQStringFromQKeySequence(self): + '''Creates a QString from a QKeySequence.''' + keyseq = 'Ctrl+A' + a = QKeySequence(keyseq) + self.assertEqual(a, keyseq) + + def testPythonStringAsQKeySequence(self): + '''Passes a Python string to an argument expecting a QKeySequence.''' + keyseq = 'Ctrl+A' + action = QAction(None) + action.setShortcut(keyseq) + shortcut = action.shortcut() + self.assertTrue(isinstance(shortcut, QKeySequence)) + self.assertEqual(shortcut.toString(), keyseq) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qstylehints_test.py b/sources/pyside6/tests/QtGui/qstylehints_test.py new file mode 100644 index 000000000..d2b21d30d --- /dev/null +++ b/sources/pyside6/tests/QtGui/qstylehints_test.py @@ -0,0 +1,26 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Unit test for QStyleHints''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from helper.usesqapplication import UsesQApplication +from PySide6.QtGui import QStyleHints + + +class QStyleHintsTest(UsesQApplication): + def test(self): + styleHints = self.app.styleHints() + self.assertTrue(styleHints.startDragDistance() > 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qtextdocument_functions.py b/sources/pyside6/tests/QtGui/qtextdocument_functions.py new file mode 100644 index 000000000..2ac72df56 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qtextdocument_functions.py @@ -0,0 +1,37 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QPageRanges, Qt + + +class QTextDocumentFunctions(unittest.TestCase): + + def testFunctions(self): + self.assertFalse(Qt.mightBeRichText('bla')) + self.assertTrue(Qt.mightBeRichText('<html><head/><body><p>bla</p></body></html>')) + html = Qt.convertFromPlainText("A & B", Qt.WhiteSpaceNormal) + self.assertEqual(html, '<p>A & B</p>') + + +class QPageRangesTest(unittest.TestCase): + """PYSIDE-2237: Test that field QPageRanges.Range.from is properly mangled.""" + + def test(self): + pr = QPageRanges() + pr.addPage(1) + r0 = pr.toRangeList()[0] + self.assertEqual(r0.from_, 1) + self.assertEqual(r0.to, 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qtextdocument_undoredo_test.py b/sources/pyside6/tests/QtGui/qtextdocument_undoredo_test.py new file mode 100644 index 000000000..b74c6704f --- /dev/null +++ b/sources/pyside6/tests/QtGui/qtextdocument_undoredo_test.py @@ -0,0 +1,42 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QTextDocument, QTextCursor + + +class QTextDocumentTest(unittest.TestCase): + + def testUndoRedo(self): + text = 'foobar' + doc = QTextDocument(text) + + self.assertFalse(doc.isRedoAvailable()) + self.assertTrue(doc.isUndoAvailable()) + self.assertEqual(doc.toPlainText(), text) + + cursor = QTextCursor(doc) + doc.undo(cursor) + + self.assertTrue(doc.isRedoAvailable()) + self.assertFalse(doc.isUndoAvailable()) + self.assertEqual(doc.toPlainText(), '') + + doc.redo(cursor) + + self.assertFalse(doc.isRedoAvailable()) + self.assertTrue(doc.isUndoAvailable()) + self.assertEqual(doc.toPlainText(), text) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qtextdocumentwriter_test.py b/sources/pyside6/tests/QtGui/qtextdocumentwriter_test.py new file mode 100644 index 000000000..4f72b98e7 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qtextdocumentwriter_test.py @@ -0,0 +1,31 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QTextDocumentWriter, QTextDocument +from PySide6.QtCore import QBuffer + + +class QTextDocumentWriterTest(unittest.TestCase): + + def testWrite(self): + text = 'foobar' + doc = QTextDocument(text) + b = QBuffer() + b.open(QBuffer.ReadWrite) + writer = QTextDocumentWriter(b, bytes("plaintext", "UTF-8")) + writer.write(doc) + b.close() + self.assertEqual(b.buffer(), text) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/qtextline_test.py b/sources/pyside6/tests/QtGui/qtextline_test.py new file mode 100644 index 000000000..c34a4c98a --- /dev/null +++ b/sources/pyside6/tests/QtGui/qtextline_test.py @@ -0,0 +1,39 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtGui import QTextLayout, QTextOption +from helper.usesqapplication import UsesQApplication + + +class QTextLineTest(UsesQApplication): + + def testCursorToX(self): + textLayout = QTextLayout() + textLayout.beginLayout() + line = textLayout.createLine() + self.assertTrue(line.isValid()) + x, cursorPos = line.cursorToX(0) + self.assertEqual(type(x), float) + self.assertEqual(type(cursorPos), int) + x, cursorPos = line.cursorToX(1) + self.assertEqual(type(x), float) + self.assertEqual(type(cursorPos), int) + + def testTextOption(self): + """PYSIDE-2088, large enum values causing MSVC issues.""" + v = QTextOption.IncludeTrailingSpaces | QTextOption.ShowTabsAndSpaces + self.assertEqual(v.value, 2147483649) + + +if __name__ == '__main__': + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/qtransform_test.py b/sources/pyside6/tests/QtGui/qtransform_test.py new file mode 100644 index 000000000..dc51a74e6 --- /dev/null +++ b/sources/pyside6/tests/QtGui/qtransform_test.py @@ -0,0 +1,90 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +from PySide6.QtCore import QPointF +from PySide6.QtGui import QTransform, QPolygonF, QPolygonF, QQuaternion, QVector3D + + +class QTransformTest(unittest.TestCase): + + def testMap(self): + transform = QTransform() + values = (10.0, 20.0) + tx, ty = transform.map(*values) + self.assertTrue(isinstance(tx, float)) + self.assertTrue(isinstance(ty, float)) + self.assertEqual((tx, ty), values) + + def testquadToQuad(self): + q1 = QPolygonF() + q1.append(QPointF(10.0, 10.0)) + q1.append(QPointF(20.0, 10.0)) + q1.append(QPointF(10.0, -10.0)) + q1.append(QPointF(20.0, -10.0)) + + q2 = QPolygonF() + q2.append(QPointF(20.0, 20.0)) + q2.append(QPointF(30.0, 20.0)) + q2.append(QPointF(20.0, -20.0)) + q2.append(QPointF(30.0, -20.0)) + + t1 = QTransform() + r1 = QTransform.quadToQuad(q1, q2, t1) + r2 = QTransform.quadToQuad(q1, q2) + + self.assertTrue(r1) + self.assertTrue(r2) + + self.assertEqual(t1, r2) + + def testquadToSquare(self): + q1 = QPolygonF() + q1.append(QPointF(10.0, 10.0)) + q1.append(QPointF(20.0, 10.0)) + q1.append(QPointF(10.0, -10.0)) + q1.append(QPointF(20.0, -10.0)) + + t1 = QTransform() + r1 = QTransform.quadToSquare(q1, t1) + r2 = QTransform.quadToSquare(q1) + + self.assertTrue(r1) + self.assertTrue(r2) + + self.assertEqual(t1, r2) + + def testsquareToQuad(self): + q1 = QPolygonF() + q1.append(QPointF(10.0, 10.0)) + q1.append(QPointF(20.0, 10.0)) + q1.append(QPointF(10.0, -10.0)) + q1.append(QPointF(20.0, -10.0)) + + t1 = QTransform() + r1 = QTransform.squareToQuad(q1, t1) + r2 = QTransform.squareToQuad(q1) + + self.assertTrue(r1) + self.assertTrue(r2) + + self.assertEqual(t1, r2) + + def testQQuaternion(self): + """Test return tuples.""" + q = QQuaternion(1, 1, 1, 1) + self.assertEqual(len(q.getAxisAndAngle()), 2) + self.assertEqual(len(q.getEulerAngles()), 3) + + +if __name__ == "__main__": + unittest.main() + diff --git a/sources/pyside6/tests/QtGui/repr_test.py b/sources/pyside6/tests/QtGui/repr_test.py new file mode 100644 index 000000000..2858e7175 --- /dev/null +++ b/sources/pyside6/tests/QtGui/repr_test.py @@ -0,0 +1,96 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths +init_test_paths(False) + +import PySide6 +from PySide6.QtCore import QPoint +from PySide6.QtGui import QMatrix2x2, QMatrix2x3, QMatrix2x4 +from PySide6.QtGui import QMatrix3x2, QMatrix3x3, QMatrix3x4 +from PySide6.QtGui import QMatrix4x2, QMatrix4x3, QMatrix4x4 +from PySide6.QtGui import QVector2D, QVector3D, QVector4D +from PySide6.QtGui import QColor, QTransform, QKeySequence, QQuaternion +from PySide6.QtGui import QPolygon + + +class ReprCopyHelper: + def testCopy(self): + copy = eval(self.original.__repr__()) + self.assertTrue(copy is not self.original) + self.assertEqual(copy, self.original) + + +class QTransformReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QTransform(1, 2, 3, 4, 5, 6, 7, 8, 9) + + +class QQuaternionReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QQuaternion(1, 2, 3, 4) + + +class QVector2DReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QVector2D(1, 2) + + +class QVector3DReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QVector3D(1, 2, 3) + + +class QVector4DReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QVector4D(1, 2, 3, 4) + + +# Avoid these tests until get gcc fixed +# Related bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43247 +""" +class QMatrix2x2ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix2x2([1, 2, 3, 4]) + +class QMatrix2x3ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix2x3([1, 2, 3, 4, 5, 6]) + +class QMatrix2x4ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix2x4([1, 2, 3, 4, 5, 6, 7, 8]) + +class QMatrix3x2ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix3x2([1, 2, 3, 4, 5, 6]) + +class QMatrix3x3ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix3x3([1, 2, 3, 4, 5, 6, 7, 8, 9]) + +class QMatrix3x4ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix3x4([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) + +class QMatrix4x2ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix4x2([1, 2, 3, 4, 5, 6, 7, 8]) + +class QMatrix4x3ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix4x3([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) + +class QMatrix4x4ReprCopy(ReprCopyHelper, unittest.TestCase): + def setUp(self): + self.original = QMatrix4x4([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) +""" + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/sample.png b/sources/pyside6/tests/QtGui/sample.png Binary files differnew file mode 100644 index 000000000..60450f0dc --- /dev/null +++ b/sources/pyside6/tests/QtGui/sample.png diff --git a/sources/pyside6/tests/QtGui/timed_app_and_patching_test.py b/sources/pyside6/tests/QtGui/timed_app_and_patching_test.py new file mode 100644 index 000000000..6e9a661ce --- /dev/null +++ b/sources/pyside6/tests/QtGui/timed_app_and_patching_test.py @@ -0,0 +1,27 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from init_paths import init_test_paths # noqa: E402 +init_test_paths(False) + +from helper.timedqguiapplication import TimedQGuiApplication + + +class TestTimedApp(TimedQGuiApplication): + '''Simple test case for TimedQGuiApplication''' + + def testFoo(self): + # Simple test of TimedQGuiApplication + self.app.exec() + +# deprecated.py is no longer needed. + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside6/tests/QtGui/xpm_data.py b/sources/pyside6/tests/QtGui/xpm_data.py new file mode 100644 index 000000000..3603d8190 --- /dev/null +++ b/sources/pyside6/tests/QtGui/xpm_data.py @@ -0,0 +1,237 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +'''Test data for QImage''' + + +xpm = [ + "27 22 206 2", + " c None", + ". c #FEFEFE", + "+ c #FFFFFF", + "@ c #F9F9F9", + "# c #ECECEC", + "$ c #D5D5D5", + "% c #A0A0A0", + "& c #767676", + "* c #525252", + "= c #484848", + "- c #4E4E4E", + "; c #555555", + "> c #545454", + ", c #5A5A5A", + "' c #4B4B4B", + ") c #4A4A4A", + "! c #4F4F4F", + "~ c #585858", + "{ c #515151", + "] c #4C4C4C", + "^ c #B1B1B1", + "/ c #FCFCFC", + "( c #FDFDFD", + "_ c #C1C1C1", + ": c #848484", + "< c #616161", + "[ c #5E5E5E", + "} c #CECECE", + "| c #E2E2E2", + "1 c #E4E4E4", + "2 c #DFDFDF", + "3 c #D2D2D2", + "4 c #D8D8D8", + "5 c #D4D4D4", + "6 c #E6E6E6", + "7 c #F1F1F1", + "8 c #838383", + "9 c #8E8E8E", + "0 c #8F8F8F", + "a c #CBCBCB", + "b c #CCCCCC", + "c c #E9E9E9", + "d c #F2F2F2", + "e c #EDEDED", + "f c #B5B5B5", + "g c #A6A6A6", + "h c #ABABAB", + "i c #BBBBBB", + "j c #B0B0B0", + "k c #EAEAEA", + "l c #6C6C6C", + "m c #BCBCBC", + "n c #F5F5F5", + "o c #FAFAFA", + "p c #B6B6B6", + "q c #F3F3F3", + "r c #CFCFCF", + "s c #FBFBFB", + "t c #CDCDCD", + "u c #DDDDDD", + "v c #999999", + "w c #F0F0F0", + "x c #2B2B2B", + "y c #C3C3C3", + "z c #A4A4A4", + "A c #D7D7D7", + "B c #E7E7E7", + "C c #6E6E6E", + "D c #9D9D9D", + "E c #BABABA", + "F c #AEAEAE", + "G c #898989", + "H c #646464", + "I c #BDBDBD", + "J c #CACACA", + "K c #2A2A2A", + "L c #212121", + "M c #B7B7B7", + "N c #F4F4F4", + "O c #737373", + "P c #828282", + "Q c #4D4D4D", + "R c #000000", + "S c #151515", + "T c #B2B2B2", + "U c #D6D6D6", + "V c #D3D3D3", + "W c #2F2F2F", + "X c #636363", + "Y c #A1A1A1", + "Z c #BFBFBF", + "` c #E0E0E0", + " . c #6A6A6A", + ".. c #050505", + "+. c #A3A3A3", + "@. c #202020", + "#. c #5F5F5F", + "$. c #B9B9B9", + "%. c #C7C7C7", + "&. c #D0D0D0", + "*. c #3E3E3E", + "=. c #666666", + "-. c #DBDBDB", + ";. c #424242", + ">. c #C2C2C2", + ",. c #1A1A1A", + "'. c #2C2C2C", + "). c #F6F6F6", + "!. c #AAAAAA", + "~. c #DCDCDC", + "{. c #2D2D2D", + "]. c #2E2E2E", + "^. c #A7A7A7", + "/. c #656565", + "(. c #333333", + "_. c #464646", + ":. c #C4C4C4", + "<. c #B8B8B8", + "[. c #292929", + "}. c #979797", + "|. c #EFEFEF", + "1. c #909090", + "2. c #8A8A8A", + "3. c #575757", + "4. c #676767", + "5. c #C5C5C5", + "6. c #7A7A7A", + "7. c #797979", + "8. c #989898", + "9. c #EEEEEE", + "0. c #707070", + "a. c #C8C8C8", + "b. c #111111", + "c. c #AFAFAF", + "d. c #474747", + "e. c #565656", + "f. c #E3E3E3", + "g. c #494949", + "h. c #5B5B5B", + "i. c #222222", + "j. c #353535", + "k. c #D9D9D9", + "l. c #0A0A0A", + "m. c #858585", + "n. c #E5E5E5", + "o. c #0E0E0E", + "p. c #9A9A9A", + "q. c #6F6F6F", + "r. c #868686", + "s. c #060606", + "t. c #1E1E1E", + "u. c #E8E8E8", + "v. c #A5A5A5", + "w. c #0D0D0D", + "x. c #030303", + "y. c #272727", + "z. c #131313", + "A. c #1F1F1F", + "B. c #757575", + "C. c #F7F7F7", + "D. c #414141", + "E. c #080808", + "F. c #6B6B6B", + "G. c #313131", + "H. c #C0C0C0", + "I. c #C9C9C9", + "J. c #0B0B0B", + "K. c #232323", + "L. c #434343", + "M. c #3D3D3D", + "N. c #282828", + "O. c #7C7C7C", + "P. c #252525", + "Q. c #3A3A3A", + "R. c #F8F8F8", + "S. c #1B1B1B", + "T. c #949494", + "U. c #3B3B3B", + "V. c #242424", + "W. c #383838", + "X. c #6D6D6D", + "Y. c #818181", + "Z. c #939393", + "`. c #9E9E9E", + " + c #929292", + ".+ c #7D7D7D", + "++ c #ADADAD", + "@+ c #DADADA", + "#+ c #919191", + "$+ c #E1E1E1", + "%+ c #BEBEBE", + "&+ c #ACACAC", + "*+ c #9C9C9C", + "=+ c #B3B3B3", + "-+ c #808080", + ";+ c #A8A8A8", + ">+ c #393939", + ",+ c #747474", + "'+ c #7F7F7F", + ")+ c #D1D1D1", + "!+ c #606060", + "~+ c #5C5C5C", + "{+ c #686868", + "]+ c #7E7E7E", + "^+ c #787878", + "/+ c #595959", + ". . . + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / . . + + ", + ". ( + _ : < [ & } | 1 2 $ 3 4 5 3 6 7 + + 8 9 + . + . ", + ". + 0 9 a ( 3 a b c d e c f g h i g j $ k + l m + . + ", + "+ 2 8 n o p | ( q r s . # t + + + u ^ v e w + x + + + ", + "+ y z . @ A k B 7 n + ( s | p 8 C D 2 E 4 + + F G + . ", + "# H I $ J G K L - M N . 2 O P Q R R S T U s s V W j + ", + "X Y Z @ o ` _ g ...+.( 4 @.#.m G $.%.7 &.X *.=.-.;.&.", + "Q >.C ,.'.} e + ).!.k + . + + . ~.{.> ].x f 7 ^./.k (.", + "_.:.4 @ <.[.}.|.1.2.+ + + >.} 4 B + ( @ _ 3.4.5.6.r 7.", + "3.8.9.~ 0.+ a.Q b.+ + c.d.#.=.$ |.b #.e.z ^ ; ^. .f.g.", + "-.h.+ i.S M + # p j.% n 9.5.k.H l.m.V ^.n.o.M + M p.q.", + "7 r.N s.1.R t.<.|.| u.v.~ w.x.E + s y.z.A.B.C.+ 5 D.q ", + ").p.2 E.0.9 F.%.O {._ @.+ + i { [ i.G.H.P I.+ s q.} + ", + ").p.6 J.R b.K.L.M.A.! b.g.K [.R M k + N.I + + >.O.+ . ", + ").8.9.N.P...R R R R E.t.W n.+ Q.R.6 @.| + . + S.+ + . ", + "n }.w T.U.B.<.i.@ Y + + U.+ c u V.= B B 7 u.W.c + . + ", + "N T.# + }.X.Y.,.8.F.8 Z.[.`. +.+}.4 ++@+O.< ~.+ ( . + ", + "d #+1 + _ ~.u.$+b $.y @+| $+%+I.&+k.h W +.9.+ ( . + . ", + "w 0 |.*+. >.<.=+++++p a.p -+;+5.k.>+,+@ + . . + . + + ", + "q '+9.R.^ I.t b %.I.)+4 $+n.I.,+ .|.+ . . . + . + + + ", + ". p !+( + + + + + + E 0. .-+8.f.+ + . . + + . + + + + ", + ". ( A ~+{+]+^+l > /+D f.c q . + . . + + . + + + + + + " +] |