diff options
Diffstat (limited to 'sources/shiboken6/tests/otherbinding')
20 files changed, 838 insertions, 0 deletions
diff --git a/sources/shiboken6/tests/otherbinding/CMakeLists.txt b/sources/shiboken6/tests/otherbinding/CMakeLists.txt new file mode 100644 index 000000000..2172593d3 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/CMakeLists.txt @@ -0,0 +1,58 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +project(other) + +set(other_TYPESYSTEM +${CMAKE_CURRENT_SOURCE_DIR}/typesystem_other.xml +) + +set(other_SRC +${CMAKE_CURRENT_BINARY_DIR}/other/extendsnoimplicitconversion_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/number_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/otherderived_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/othermultiplederived_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/otherobjecttype_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/othervaluewithunituser_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/sharedptr_str_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/smartptrtester_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/other_module_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/valuewithunitintinch_wrapper.cpp +${CMAKE_CURRENT_BINARY_DIR}/other/valuewithunitintmillimeter_wrapper.cpp +) + + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/other-binding.txt.in" + "${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt" @ONLY) + +shiboken_get_tool_shell_wrapper(shiboken tool_wrapper) + +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log" + BYPRODUCTS ${other_SRC} + COMMAND + ${tool_wrapper} + $<TARGET_FILE:Shiboken6::shiboken6> + --project-file=${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt + ${GENERATOR_EXTRA_FLAGS} + DEPENDS ${other_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6 + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Running generator for 'other' test binding..." +) + +add_library(other MODULE ${other_SRC}) +target_include_directories(other PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + ${sample_BINARY_DIR}/sample + ${smart_BINARY_DIR}/smart) +target_link_libraries(other PUBLIC libother libsample libsmart libshiboken) +set_property(TARGET other PROPERTY PREFIX "") +set_property(TARGET other PROPERTY OUTPUT_NAME "other${PYTHON_EXTENSION_SUFFIX}") + +if(WIN32) + set_property(TARGET other PROPERTY SUFFIX ".pyd") +endif() + + +add_dependencies(other sample smart) +create_generator_target(other) + diff --git a/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py b/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py new file mode 100644 index 000000000..2ba21653d --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py @@ -0,0 +1,39 @@ +#!/usr/bin/env 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 Collector shift operators defined in other modules.''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from sample import Collector, ObjectType +from other import OtherObjectType + + +class CollectorOtherObjectType(unittest.TestCase): + '''Test cases for Collector << OtherObjectType''' + + def testLShiftWithExpectedType(self): + '''Collector << ObjectType # libsample << operator''' + collector = Collector() + obj = ObjectType() + collector << obj + self.assertEqual(collector.items()[0], obj.identifier()) + + def testOtherReversal(self): + '''Collector << OtherObjectType # libother << operator''' + collector = Collector() + obj = OtherObjectType() + collector << obj + self.assertEqual(collector.items()[0], obj.identifier() * 2) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py b/sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py new file mode 100644 index 000000000..bd00b5892 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py @@ -0,0 +1,61 @@ +#!/usr/bin/env 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 calling NoImplicitConversion using a ExtendsNoImplicitConversion parameter, + being that the latter defines a new conversion operator for the former, and this one + has no implicit conversions.''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from sample import NoImplicitConversion +from other import ExtendsNoImplicitConversion + + +class ConversionOperatorForClassWithoutImplicitConversionsTest(unittest.TestCase): + '''Tests calling NoImplicitConversion constructor using a + ExtendsNoImplicitConversion parameter.''' + + def testNoImplicitConversion(self): + '''Basic test to see if the NoImplicitConversion is Ok.''' + obj = NoImplicitConversion(123) + # NoImplicitConversion.receivesNoImplicitConversionByValue(NoImplicitConversion) + self.assertEqual(obj.objId(), NoImplicitConversion.receivesNoImplicitConversionByValue(obj)) + # NoImplicitConversion.receivesNoImplicitConversionByPointer(NoImplicitConversion*) + self.assertEqual(obj.objId(), + NoImplicitConversion.receivesNoImplicitConversionByPointer(obj)) + # NoImplicitConversion.receivesNoImplicitConversionByReference(NoImplicitConversion&) + self.assertEqual(obj.objId(), + NoImplicitConversion.receivesNoImplicitConversionByReference(obj)) + + def testPassingExtendsNoImplicitConversionAsNoImplicitConversionByValue(self): + '''Gives an ExtendsNoImplicitConversion object to a function expecting a + NoImplicitConversion, passing by value.''' + obj = ExtendsNoImplicitConversion(123) + self.assertEqual(obj.objId(), NoImplicitConversion.receivesNoImplicitConversionByValue(obj)) + + def testPassingExtendsNoImplicitConversionAsNoImplicitConversionByReference(self): + '''Gives an ExtendsNoImplicitConversion object to a function expecting a + NoImplicitConversion, passing by reference.''' + obj = ExtendsNoImplicitConversion(123) + self.assertEqual(obj.objId(), + NoImplicitConversion.receivesNoImplicitConversionByReference(obj)) + + def testPassingExtendsNoImplicitConversionAsNoImplicitConversionByPointer(self): + '''Gives an ExtendsNoImplicitConversion object to a function expecting + a NoImplicitConversion, passing by pointer. This should not be + accepted, since pointers should not be converted.''' + obj = ExtendsNoImplicitConversion(123) + self.assertRaises(TypeError, + NoImplicitConversion.receivesNoImplicitConversionByPointer, obj) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py b/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py new file mode 100644 index 000000000..abbef6231 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py @@ -0,0 +1,45 @@ +#!/usr/bin/env 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 libsample's Point multiply operator defined in libother module.''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from sample import Point +from other import Number + + +class PointOperationsWithNumber(unittest.TestCase): + '''Test cases for libsample's Point multiply operator defined in libother module.''' + + def testPointTimesInt(self): + '''sample.Point * int''' + pt1 = Point(2, 7) + num = 3 + pt2 = Point(pt1.x() * num, pt1.y() * num) + self.assertEqual(pt1 * num, pt2) + + def testIntTimesPoint(self): + '''int * sample.Point''' + pt1 = Point(2, 7) + num = 3 + pt2 = Point(pt1.x() * num, pt1.y() * num) + self.assertEqual(num * pt1, pt2) + + def testPointTimesNumber(self): + '''sample.Point * other.Number''' + pt = Point(2, 7) + num = Number(11) + self.assertEqual(pt * num.value(), pt * 11) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/global.h b/sources/shiboken6/tests/otherbinding/global.h new file mode 100644 index 000000000..af796734a --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/global.h @@ -0,0 +1,11 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "../samplebinding/global.h" +#include "extendsnoimplicitconversion.h" +#include "number.h" +#include "otherderived.h" +#include "otherobjecttype.h" +#include "othermultiplederived.h" +#include "othertypesystypedef.h" +#include "smartptrtester.h" diff --git a/sources/shiboken6/tests/otherbinding/module_reload_test.py b/sources/shiboken6/tests/otherbinding/module_reload_test.py new file mode 100644 index 000000000..bde2f5236 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/module_reload_test.py @@ -0,0 +1,38 @@ +#!/usr/bin/env 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 + +from importlib import reload +import os +import shutil +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + + +orig_path = Path(__file__).parent +workdir = Path.cwd() +src = orig_path / 'test_module_template.py' +dst = workdir / 'test_module.py' +shutil.copyfile(src, dst) +sys.path.append(os.fspath(workdir)) + + +class TestModuleReloading(unittest.TestCase): + + def testModuleReloading(self): + '''Test module reloading with on-the-fly modifications.''' + import test_module + for i in range(3): + oldObject = test_module.obj + self.assertTrue(oldObject is test_module.obj) + reload(test_module) + self.assertFalse(oldObject is test_module.obj) + + +if __name__ == "__main__": + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py b/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py new file mode 100644 index 000000000..d6c356436 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py @@ -0,0 +1,39 @@ +#!/usr/bin/env 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 calling Str constructor using a Number parameter, being that number defines + a cast operator to Str.''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from sample import Str +from other import Number + + +class NewCtorOperatorTest(unittest.TestCase): + '''Tests calling Str constructor using a Number parameter, being that number + defines a cast operator to Str.''' + + def testNumber(self): + '''Basic test to see if the Number class is Ok.''' + value = 123 + num = Number(value) + self.assertEqual(num.value(), value) + + def testStrCtorWithNumberArgument(self): + '''Try to build a Str from 'sample' module with a Number argument from 'other' module.''' + value = 123 + num = Number(value) + string = Str(num) # noqa: F841 + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/objtypehashes_test.py b/sources/shiboken6/tests/otherbinding/objtypehashes_test.py new file mode 100644 index 000000000..d2cd7de5b --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/objtypehashes_test.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 shiboken_paths import init_paths +init_paths() +from sample import HandleHolder +from shiboken6 import Shiboken + + +class TestHashFuncs (unittest.TestCase): + + def testIt(self): + obj1 = HandleHolder() + obj2 = HandleHolder() + + hash1 = hash(obj1) + hash2 = hash(obj2) + self.assertNotEqual(hash1, hash2) + + # Now invalidate the object and test its hash. It shouldn't segfault. + Shiboken.invalidate(obj1) + + hash1_2 = hash(obj1) + self.assertEqual(hash1_2, hash1) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/other-binding.txt.in b/sources/shiboken6/tests/otherbinding/other-binding.txt.in new file mode 100644 index 000000000..d85f6030a --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/other-binding.txt.in @@ -0,0 +1,20 @@ +[generator-project] + +generator-set = shiboken + +header-file = @CMAKE_CURRENT_SOURCE_DIR@/global.h +typesystem-file = @other_TYPESYSTEM@ + +output-directory = @CMAKE_CURRENT_BINARY_DIR@ + +include-path = @libother_SOURCE_DIR@ +include-path = @libsmart_SOURCE_DIR@ +include-path = @libsample_SOURCE_DIR@ +include-path = @libsample_SOURCE_DIR@/.. + +typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@ +typesystem-path = @sample_SOURCE_DIR@ +typesystem-path = @smart_SOURCE_DIR@ + +enable-parent-ctor-heuristic +lean-headers diff --git a/sources/shiboken6/tests/otherbinding/otherbinding.pyproject b/sources/shiboken6/tests/otherbinding/otherbinding.pyproject new file mode 100644 index 000000000..d1bbee11e --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/otherbinding.pyproject @@ -0,0 +1,17 @@ +{ + "files": ["collector_external_operator_test.py", + "conversion_operator_for_class_without_implicit_conversions_test.py", + "extended_multiply_operator_test.py", + "module_reload_test.py", + "new_ctor_operator_test.py", + "objtypehashes_test.py", + "otherderived_test.py", + "othertypesystypedef_test.py", + "signature_test.py", + "smartptr_test.py", + "test_module_template.py", + "typediscovery_test.py", + "usersprimitivefromothermodule_test.py", + "wrongctor_test.py", + "typesystem_other.xml"] +} diff --git a/sources/shiboken6/tests/otherbinding/otherderived_test.py b/sources/shiboken6/tests/otherbinding/otherderived_test.py new file mode 100644 index 000000000..459f474f1 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/otherderived_test.py @@ -0,0 +1,109 @@ +#!/usr/bin/env 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 OtherDerived class''' + +import gc +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from sample import Abstract, Derived +from other import OtherDerived, Number + + +class Multiple(Derived, Number): + def __init__(self): + Derived.__init__(self, 42) + Number.__init__(self, 42) + + def testCall(self): + return True + + +class OtherDeviant(OtherDerived): + def __init__(self): + OtherDerived.__init__(self) + self.pure_virtual_called = False + self.unpure_virtual_called = False + + def pureVirtual(self): + self.pure_virtual_called = True + + def unpureVirtual(self): + self.unpure_virtual_called = True + + def className(self): + return 'OtherDeviant' + + +class MultipleTest(unittest.TestCase): + '''Test case for Multiple derived class''' + + def testConstructor(self): + o = Multiple() + self.assertTrue(isinstance(o, Multiple)) + self.assertTrue(isinstance(o, Number)) + self.assertTrue(isinstance(o, Derived)) + del o + # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion + gc.collect() + + def testMethodCall(self): + o = Multiple() + self.assertTrue(o.id_(), 42) + self.assertTrue(o.value(), 42) + self.assertTrue(o.testCall()) + + +class OtherDerivedTest(unittest.TestCase): + '''Test case for OtherDerived class''' + + def testParentClassMethodsAvailability(self): + '''Test if OtherDerived class really inherits its methods from parent.''' + inherited_methods = set(['callPureVirtual', 'callUnpureVirtual', + 'id_', 'pureVirtual', 'unpureVirtual']) + self.assertTrue(inherited_methods.issubset(dir(OtherDerived))) + + def testReimplementedPureVirtualMethodCall(self): + '''Test if a Python override of a implemented pure virtual method is + correctly called from C++.''' + d = OtherDeviant() + d.callPureVirtual() + self.assertTrue(d.pure_virtual_called) + + def testReimplementedVirtualMethodCall(self): + '''Test if a Python override of a reimplemented virtual method is + correctly called from C++.''' + d = OtherDeviant() + d.callUnpureVirtual() + self.assertTrue(d.unpure_virtual_called) + + def testVirtualMethodCallString(self): + '''Test virtual method call returning string.''' + d = OtherDerived() + self.assertEqual(d.className(), 'OtherDerived') + self.assertEqual(d.getClassName(), 'OtherDerived') + + def testReimplementedVirtualMethodCallReturningString(self): + '''Test if a Python override of a reimplemented virtual method is + correctly called from C++.''' + d = OtherDeviant() + self.assertEqual(d.className(), 'OtherDeviant') + self.assertEqual(d.getClassName(), 'OtherDeviant') + + def testCallToMethodWithAbstractArgument(self): + '''Call to method that expects an Abstract argument.''' + objId = 123 + d = OtherDerived(objId) + self.assertEqual(Abstract.getObjectId(d), objId) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py b/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py new file mode 100644 index 000000000..198c71693 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py @@ -0,0 +1,35 @@ +#!/usr/bin/env 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 case for a class that holds a void pointer.''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from other import (OtherValueWithUnitUser, ValueWithUnitIntMillimeter) +from sample import (ValueWithUnitDoubleMillimeter) + + +class OtherTypeSysTypeDefTest(unittest.TestCase): + '''Test case type system typedefs across modules.''' + + def test(self): + # Exercise existing typedefs from "sample" + mm_value = ValueWithUnitDoubleMillimeter(2540) + inch_value = OtherValueWithUnitUser.doubleMillimeterToInch(mm_value) + self.assertEqual(int(inch_value.value()), 10) + # Exercise typedefs in "other" + mm_value = ValueWithUnitIntMillimeter(2540) + inch_value = OtherValueWithUnitUser.intMillimeterToInch(mm_value) + self.assertEqual(inch_value.value(), 10) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/signature_test.py b/sources/shiboken6/tests/otherbinding/signature_test.py new file mode 100644 index 000000000..8db3e566b --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/signature_test.py @@ -0,0 +1,34 @@ +#!/usr/bin/env 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 functions signature''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from other import OtherObjectType +from shiboken_test_helper import objectFullname + +from shibokensupport.signature import get_signature + + +class SignatureTest(unittest.TestCase): + + # Check if the argument of + # 'OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value)' + # has the correct representation + def testNamespaceFromOtherModule(self): + argType = get_signature(OtherObjectType.enumAsInt).parameters["value"].annotation + self.assertEqual(objectFullname(argType), + "sample.SampleNamespace.SomeClass.PublicScopedEnum") + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/smartptr_test.py b/sources/shiboken6/tests/otherbinding/smartptr_test.py new file mode 100644 index 000000000..fd5c7fa09 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/smartptr_test.py @@ -0,0 +1,33 @@ +#!/usr/bin/env 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 the SmartPtrTester class''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from other import SmartPtrTester + + +class SmartPtrTest(unittest.TestCase): + '''Test case for the SmartPtrTester class''' + + def test(self): + tester = SmartPtrTester() + + integerPtr = tester.createSharedPtrInteger(42) + self.assertEqual(tester.valueOfSharedPtrInteger(integerPtr), 42) + + strPtr = tester.createSharedPtrStr('hello') + self.assertEqual(tester.valueOfSharedPtrStr(strPtr), 'hello') + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/star_import_test.py b/sources/shiboken6/tests/otherbinding/star_import_test.py new file mode 100644 index 000000000..4b5f1d270 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/star_import_test.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +"""PYSIDE-2404: Test whether star imports work as they require special handling + by the lazy initialization.""" + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +SHIBOKEN_NAME = "shiboken6.Shiboken" +MINIMAL_NAME = "minimal" +OTHER_NAME = "other" + +shiboken_loaded = 1 if sys.modules.get(SHIBOKEN_NAME) else 0 +minimal_loaded = 1 if sys.modules.get(MINIMAL_NAME) else 0 +other_loaded = 1 if sys.modules.get(OTHER_NAME) else 0 + +from minimal import * # noqa: F403 + +shiboken_loaded += 2 if sys.modules.get(SHIBOKEN_NAME) else 0 +minimal_loaded += 2 if sys.modules.get(MINIMAL_NAME) else 0 +other_loaded += 2 if sys.modules.get(OTHER_NAME) else 0 + +from other import Number # noqa: F403 +from other import * # noqa: F403 + +shiboken_loaded += 4 if sys.modules.get(SHIBOKEN_NAME) else 0 +minimal_loaded += 4 if sys.modules.get(MINIMAL_NAME) else 0 +other_loaded = +4 if sys.modules.get(OTHER_NAME) else 0 + +import shiboken6.Shiboken # noqa: F401 F403 + +shiboken_loaded += 8 if sys.modules.get(SHIBOKEN_NAME) else 0 + + +class ValTest(unittest.TestCase): + + def test(self): + val_id = 123 + val = Val(val_id) # noqa: F405 + self.assertEqual(val.valId(), val_id) + + +class Simple(Number): + + def __init__(self): + Number.__init__(self, 42) + + +class OtherTest(unittest.TestCase): + + def testConstructor(self): + o = Simple() + self.assertTrue(isinstance(o, Number)) + + +class StarImportTest(unittest.TestCase): + """ + This test is meant for Lazy Init. + We explicitly choose modules which are able to lazy load. + + The ValTest: + ------------ + We load something with `import *`. + There is no module from our known ones imported. + This means we need stack introspection to find out that this was + a star import and we must disable lazyness. + + The OtherTest: + -------------- + We load something normally that should be lazy. + After that, we follow with a star import. + Now the stack introspection does not work, because the loading is + cached. The first import did a lazy load. The following star import + needs to undo the lazyness. But now we have a redirected import. + + All tests simply check if the objects are real and not just names. + The <module>_loaded tests prevend upcoming internal dependencies. + + To make sure that Shiboken is really not involved, it is checked + and really imported afterwards (ensuring nothing is misspelled). + """ + + def testStar(self): + self.assertEqual(other_loaded, 4) + self.assertEqual(minimal_loaded, 6) + self.assertEqual(shiboken_loaded, 14) + # Interesting effect: Did not expect that shiboken is loaded at all. + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/test_module_template.py b/sources/shiboken6/tests/otherbinding/test_module_template.py new file mode 100644 index 000000000..36ab43ae3 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/test_module_template.py @@ -0,0 +1,24 @@ +# 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])) +from shiboken_paths import init_paths +init_paths() + +from other import OtherObjectType +from sample import ObjectType + + +class MyObjectType(ObjectType): + pass + + +class MyOtherObjectType(OtherObjectType): + value = 10 + + +obj = MyObjectType() diff --git a/sources/shiboken6/tests/otherbinding/typediscovery_test.py b/sources/shiboken6/tests/otherbinding/typediscovery_test.py new file mode 100644 index 000000000..39dc5cf0f --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/typediscovery_test.py @@ -0,0 +1,53 @@ +#!/usr/bin/env 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 type discovery''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() + +from sample import (Abstract, Base1, Derived, + MDerived1, SonOfMDerived1, MDerived3) +from other import OtherMultipleDerived + + +class TypeDiscoveryTest(unittest.TestCase): + + def testPureVirtualsOfImpossibleTypeDiscovery(self): + a = Derived.triggerImpossibleTypeDiscovery() + self.assertEqual(type(a), Abstract) + # call some pure virtual method + a.pureVirtual() + + def testAnotherImpossibleTypeDiscovery(self): + a = Derived.triggerAnotherImpossibleTypeDiscovery() + self.assertEqual(type(a), Derived) + + def testMultipleInheritance(self): + obj = OtherMultipleDerived.createObject("Base1") + self.assertEqual(type(obj), Base1) + # PYSIDE-868: In case of single line direct inheritance, + # a factory function will return the class wrapper + # of the derived class. + obj = OtherMultipleDerived.createObject("MDerived1") + self.assertEqual(type(obj), MDerived1) + obj = OtherMultipleDerived.createObject("SonOfMDerived1") + self.assertEqual(type(obj), SonOfMDerived1) + obj = OtherMultipleDerived.createObject("MDerived3") + self.assertEqual(type(obj), MDerived3) + # PYSIDE-868: OtherMultipleDerived inherits + # OtherBase, Base1. In this case, a factory + # function will return the base class wrapper. + obj = OtherMultipleDerived.createObject("OtherMultipleDerived") + self.assertEqual(type(obj), Base1) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/typesystem_other.xml b/sources/shiboken6/tests/otherbinding/typesystem_other.xml new file mode 100644 index 000000000..ade1c8bad --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/typesystem_other.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<typesystem package="other"> + <load-typesystem name="typesystem_sample.xml" generate="no" /> + <load-typesystem name="typesystem_smart.xml" generate="no" /> + + <object-type name="OtherObjectType" /> + <object-type name="OtherDerived" /> + <object-type name="OtherMultipleDerived" /> + + <value-type name="ExtendsNoImplicitConversion" /> + <value-type name="Number" /> + + <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount" + instantiations="Str"/> + <value-type name="SmartPtrTester"/> + + <typedef-type name="ValueWithUnitIntInch" source="ValueWithUnit<int,LengthUnit::Inch>"/> + <typedef-type name="ValueWithUnitIntMillimeter" source="ValueWithUnit<int,LengthUnit::Millimeter>"/> + <value-type name="OtherValueWithUnitUser"/> +</typesystem> diff --git a/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py b/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py new file mode 100644 index 000000000..15a988326 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py @@ -0,0 +1,34 @@ +#!/usr/bin/env 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 user defined primitive type from a required module.''' + +import os +import sys +import unittest + +from pathlib import Path +sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) +from shiboken_paths import init_paths +init_paths() +from other import Number + + +class UserDefinedPrimitiveTypeFromRequiredModuleTest(unittest.TestCase): + + def testUsersPrimitiveFromRequiredModuleAsArgument(self): + '''static Number Number::fromComplex(Complex)''' + cpx = complex(3.0, 1.2) + number = Number.fromComplex(cpx) + self.assertEqual(number.value(), int(cpx.real)) + + def testUsersPrimitiveFromRequiredModuleAsReturnValue(self): + '''Complex Number::toComplex()''' + number = Number(12) + cpx = number.toComplex() + self.assertEqual(number.value(), int(cpx.real)) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/shiboken6/tests/otherbinding/wrongctor_test.py b/sources/shiboken6/tests/otherbinding/wrongctor_test.py new file mode 100644 index 000000000..b9251b428 --- /dev/null +++ b/sources/shiboken6/tests/otherbinding/wrongctor_test.py @@ -0,0 +1,35 @@ +#!/usr/bin/env 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 shiboken_paths import init_paths +init_paths() +from sample import Abstract, ObjectType +from other import OtherDerived + + +class Foo(OtherDerived): + def __init__(self): + Abstract.__init__(self, 2) # this should raise an exception + + +class Foo2(ObjectType, OtherDerived): + def __init__(self): + ObjectType.__init__(self) + Abstract.__init__(self, 2) # this should raise an exception + + +class WrongCtorTest(unittest.TestCase): + def testIt(self): + self.assertRaises(TypeError, Foo) + self.assertRaises(TypeError, Foo2) + + +if __name__ == '__main__': + unittest.main() |