aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/tests
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/tests')
-rw-r--r--sources/shiboken6/tests/CMakeLists.txt92
-rw-r--r--sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt16
-rw-r--r--sources/shiboken6/tests/dumpcodemodel/main.cpp260
-rw-r--r--sources/shiboken6/tests/libminimal/CMakeLists.txt21
-rw-r--r--sources/shiboken6/tests/libminimal/containeruser.cpp55
-rw-r--r--sources/shiboken6/tests/libminimal/containeruser.h36
-rw-r--r--sources/shiboken6/tests/libminimal/libminimalmacros.h49
-rw-r--r--sources/shiboken6/tests/libminimal/listuser.cpp133
-rw-r--r--sources/shiboken6/tests/libminimal/listuser.h72
-rw-r--r--sources/shiboken6/tests/libminimal/minbool.h48
-rw-r--r--sources/shiboken6/tests/libminimal/obj.cpp16
-rw-r--r--sources/shiboken6/tests/libminimal/obj.h34
-rw-r--r--sources/shiboken6/tests/libminimal/spanuser.cpp58
-rw-r--r--sources/shiboken6/tests/libminimal/spanuser.h35
-rw-r--r--sources/shiboken6/tests/libminimal/typedef.cpp50
-rw-r--r--sources/shiboken6/tests/libminimal/typedef.h29
-rw-r--r--sources/shiboken6/tests/libminimal/val.h36
-rw-r--r--sources/shiboken6/tests/libother/CMakeLists.txt23
-rw-r--r--sources/shiboken6/tests/libother/extendsnoimplicitconversion.h21
-rw-r--r--sources/shiboken6/tests/libother/libothermacros.h18
-rw-r--r--sources/shiboken6/tests/libother/number.cpp28
-rw-r--r--sources/shiboken6/tests/libother/number.h32
-rw-r--r--sources/shiboken6/tests/libother/otherderived.cpp33
-rw-r--r--sources/shiboken6/tests/libother/otherderived.h43
-rw-r--r--sources/shiboken6/tests/libother/othermultiplederived.cpp24
-rw-r--r--sources/shiboken6/tests/libother/othermultiplederived.h22
-rw-r--r--sources/shiboken6/tests/libother/otherobjecttype.cpp20
-rw-r--r--sources/shiboken6/tests/libother/otherobjecttype.h22
-rw-r--r--sources/shiboken6/tests/libother/othertypesystypedef.cpp19
-rw-r--r--sources/shiboken6/tests/libother/othertypesystypedef.h21
-rw-r--r--sources/shiboken6/tests/libother/smartptrtester.cpp30
-rw-r--r--sources/shiboken6/tests/libother/smartptrtester.h24
-rw-r--r--sources/shiboken6/tests/libsample/CMakeLists.txt95
-rw-r--r--sources/shiboken6/tests/libsample/abstract.cpp71
-rw-r--r--sources/shiboken6/tests/libsample/abstract.h91
-rw-r--r--sources/shiboken6/tests/libsample/blackbox.cpp81
-rw-r--r--sources/shiboken6/tests/libsample/blackbox.h44
-rw-r--r--sources/shiboken6/tests/libsample/bucket.cpp59
-rw-r--r--sources/shiboken6/tests/libsample/bucket.h34
-rw-r--r--sources/shiboken6/tests/libsample/bytearray.cpp166
-rw-r--r--sources/shiboken6/tests/libsample/bytearray.h64
-rw-r--r--sources/shiboken6/tests/libsample/collector.cpp37
-rw-r--r--sources/shiboken6/tests/libsample/collector.h37
-rw-r--r--sources/shiboken6/tests/libsample/complex.cpp24
-rw-r--r--sources/shiboken6/tests/libsample/complex.h32
-rw-r--r--sources/shiboken6/tests/libsample/ctorconvrule.h22
-rw-r--r--sources/shiboken6/tests/libsample/ctparam.cpp20
-rw-r--r--sources/shiboken6/tests/libsample/ctparam.h26
-rw-r--r--sources/shiboken6/tests/libsample/cvlist.h28
-rw-r--r--sources/shiboken6/tests/libsample/derived.cpp88
-rw-r--r--sources/shiboken6/tests/libsample/derived.h72
-rw-r--r--sources/shiboken6/tests/libsample/derivedusingct.cpp9
-rw-r--r--sources/shiboken6/tests/libsample/derivedusingct.h17
-rw-r--r--sources/shiboken6/tests/libsample/echo.cpp4
-rw-r--r--sources/shiboken6/tests/libsample/echo.h60
-rw-r--r--sources/shiboken6/tests/libsample/exceptiontest.cpp46
-rw-r--r--sources/shiboken6/tests/libsample/exceptiontest.h25
-rw-r--r--sources/shiboken6/tests/libsample/expression.cpp79
-rw-r--r--sources/shiboken6/tests/libsample/expression.h40
-rw-r--r--sources/shiboken6/tests/libsample/filter.cpp38
-rw-r--r--sources/shiboken6/tests/libsample/filter.h70
-rw-r--r--sources/shiboken6/tests/libsample/functions.cpp232
-rw-r--r--sources/shiboken6/tests/libsample/functions.h91
-rw-r--r--sources/shiboken6/tests/libsample/handle.cpp19
-rw-r--r--sources/shiboken6/tests/libsample/handle.h53
-rw-r--r--sources/shiboken6/tests/libsample/implicitconv.cpp39
-rw-r--r--sources/shiboken6/tests/libsample/implicitconv.h60
-rw-r--r--sources/shiboken6/tests/libsample/injectcode.cpp78
-rw-r--r--sources/shiboken6/tests/libsample/injectcode.h44
-rw-r--r--sources/shiboken6/tests/libsample/intwrapper.cpp36
-rw-r--r--sources/shiboken6/tests/libsample/intwrapper.h62
-rw-r--r--sources/shiboken6/tests/libsample/libsamplemacros.h18
-rw-r--r--sources/shiboken6/tests/libsample/list.h99
-rw-r--r--sources/shiboken6/tests/libsample/listuser.cpp63
-rw-r--r--sources/shiboken6/tests/libsample/listuser.h53
-rw-r--r--sources/shiboken6/tests/libsample/main.cpp209
-rw-r--r--sources/shiboken6/tests/libsample/mapuser.cpp48
-rw-r--r--sources/shiboken6/tests/libsample/mapuser.h45
-rw-r--r--sources/shiboken6/tests/libsample/modelindex.h50
-rw-r--r--sources/shiboken6/tests/libsample/modifications.cpp207
-rw-r--r--sources/shiboken6/tests/libsample/modifications.h145
-rw-r--r--sources/shiboken6/tests/libsample/modified_constructor.cpp16
-rw-r--r--sources/shiboken6/tests/libsample/modified_constructor.h21
-rw-r--r--sources/shiboken6/tests/libsample/multiple_derived.cpp24
-rw-r--r--sources/shiboken6/tests/libsample/multiple_derived.h202
-rw-r--r--sources/shiboken6/tests/libsample/noimplicitconversion.h27
-rw-r--r--sources/shiboken6/tests/libsample/nondefaultctor.h54
-rw-r--r--sources/shiboken6/tests/libsample/nontypetemplate.h27
-rw-r--r--sources/shiboken6/tests/libsample/null.h19
-rw-r--r--sources/shiboken6/tests/libsample/objectmodel.cpp24
-rw-r--r--sources/shiboken6/tests/libsample/objectmodel.h31
-rw-r--r--sources/shiboken6/tests/libsample/objecttype.cpp264
-rw-r--r--sources/shiboken6/tests/libsample/objecttype.h166
-rw-r--r--sources/shiboken6/tests/libsample/objecttypebyvalue.h31
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeholder.cpp31
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeholder.h29
-rw-r--r--sources/shiboken6/tests/libsample/objecttypelayout.cpp40
-rw-r--r--sources/shiboken6/tests/libsample/objecttypelayout.h32
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeoperators.cpp38
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeoperators.h36
-rw-r--r--sources/shiboken6/tests/libsample/objectview.cpp24
-rw-r--r--sources/shiboken6/tests/libsample/objectview.h31
-rw-r--r--sources/shiboken6/tests/libsample/oddbool.cpp27
-rw-r--r--sources/shiboken6/tests/libsample/oddbool.h106
-rw-r--r--sources/shiboken6/tests/libsample/onlycopy.cpp36
-rw-r--r--sources/shiboken6/tests/libsample/onlycopy.h42
-rw-r--r--sources/shiboken6/tests/libsample/overload.cpp203
-rw-r--r--sources/shiboken6/tests/libsample/overload.h121
-rw-r--r--sources/shiboken6/tests/libsample/overloadsort.cpp49
-rw-r--r--sources/shiboken6/tests/libsample/overloadsort.h54
-rw-r--r--sources/shiboken6/tests/libsample/pairuser.cpp24
-rw-r--r--sources/shiboken6/tests/libsample/pairuser.h32
-rw-r--r--sources/shiboken6/tests/libsample/pen.cpp83
-rw-r--r--sources/shiboken6/tests/libsample/pen.h72
-rw-r--r--sources/shiboken6/tests/libsample/photon.cpp31
-rw-r--r--sources/shiboken6/tests/libsample/photon.h110
-rw-r--r--sources/shiboken6/tests/libsample/point.cpp111
-rw-r--r--sources/shiboken6/tests/libsample/point.h76
-rw-r--r--sources/shiboken6/tests/libsample/pointerholder.h23
-rw-r--r--sources/shiboken6/tests/libsample/pointf.cpp86
-rw-r--r--sources/shiboken6/tests/libsample/pointf.h65
-rw-r--r--sources/shiboken6/tests/libsample/polygon.cpp39
-rw-r--r--sources/shiboken6/tests/libsample/polygon.h39
-rw-r--r--sources/shiboken6/tests/libsample/privatector.h42
-rw-r--r--sources/shiboken6/tests/libsample/privatedtor.h36
-rw-r--r--sources/shiboken6/tests/libsample/protected.cpp16
-rw-r--r--sources/shiboken6/tests/libsample/protected.h139
-rw-r--r--sources/shiboken6/tests/libsample/rect.h54
-rw-r--r--sources/shiboken6/tests/libsample/reference.cpp53
-rw-r--r--sources/shiboken6/tests/libsample/reference.h62
-rw-r--r--sources/shiboken6/tests/libsample/removednamespaces.h48
-rw-r--r--sources/shiboken6/tests/libsample/renaming.cpp21
-rw-r--r--sources/shiboken6/tests/libsample/renaming.h25
-rw-r--r--sources/shiboken6/tests/libsample/sample.cpp22
-rw-r--r--sources/shiboken6/tests/libsample/sample.h28
-rw-r--r--sources/shiboken6/tests/libsample/samplenamespace.cpp101
-rw-r--r--sources/shiboken6/tests/libsample/samplenamespace.h164
-rw-r--r--sources/shiboken6/tests/libsample/sbkdate.cpp23
-rw-r--r--sources/shiboken6/tests/libsample/sbkdate.h24
-rw-r--r--sources/shiboken6/tests/libsample/simplefile.cpp73
-rw-r--r--sources/shiboken6/tests/libsample/simplefile.h34
-rw-r--r--sources/shiboken6/tests/libsample/size.cpp11
-rw-r--r--sources/shiboken6/tests/libsample/size.h185
-rw-r--r--sources/shiboken6/tests/libsample/snakecasetest.cpp44
-rw-r--r--sources/shiboken6/tests/libsample/snakecasetest.h40
-rw-r--r--sources/shiboken6/tests/libsample/sometime.cpp67
-rw-r--r--sources/shiboken6/tests/libsample/sometime.h66
-rw-r--r--sources/shiboken6/tests/libsample/stdcomplex.cpp32
-rw-r--r--sources/shiboken6/tests/libsample/stdcomplex.h55
-rw-r--r--sources/shiboken6/tests/libsample/str.cpp137
-rw-r--r--sources/shiboken6/tests/libsample/str.h52
-rw-r--r--sources/shiboken6/tests/libsample/strlist.cpp25
-rw-r--r--sources/shiboken6/tests/libsample/strlist.h49
-rw-r--r--sources/shiboken6/tests/libsample/templateptr.cpp8
-rw-r--r--sources/shiboken6/tests/libsample/templateptr.h19
-rw-r--r--sources/shiboken6/tests/libsample/transform.cpp28
-rw-r--r--sources/shiboken6/tests/libsample/transform.h18
-rw-r--r--sources/shiboken6/tests/libsample/typesystypedef.cpp12
-rw-r--r--sources/shiboken6/tests/libsample/typesystypedef.h32
-rw-r--r--sources/shiboken6/tests/libsample/valueandvirtual.h25
-rw-r--r--sources/shiboken6/tests/libsample/virtualmethods.cpp66
-rw-r--r--sources/shiboken6/tests/libsample/virtualmethods.h145
-rw-r--r--sources/shiboken6/tests/libsample/voidholder.h32
-rw-r--r--sources/shiboken6/tests/libsmart/CMakeLists.txt23
-rw-r--r--sources/shiboken6/tests/libsmart/libsmartmacros.h18
-rw-r--r--sources/shiboken6/tests/libsmart/smart.cpp272
-rw-r--r--sources/shiboken6/tests/libsmart/smart.h16
-rw-r--r--sources/shiboken6/tests/libsmart/smart_integer.h69
-rw-r--r--sources/shiboken6/tests/libsmart/smart_obj.h45
-rw-r--r--sources/shiboken6/tests/libsmart/smart_registry.h43
-rw-r--r--sources/shiboken6/tests/libsmart/smart_sharedptr.h94
-rw-r--r--sources/shiboken6/tests/libsmart/smart_test.h13
-rw-r--r--sources/shiboken6/tests/libsmart/stdoptionaltestbench.cpp58
-rw-r--r--sources/shiboken6/tests/libsmart/stdoptionaltestbench.h30
-rw-r--r--sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp106
-rw-r--r--sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h49
-rw-r--r--sources/shiboken6/tests/libsmart/stduniqueptrtestbench.cpp133
-rw-r--r--sources/shiboken6/tests/libsmart/stduniqueptrtestbench.h50
-rw-r--r--sources/shiboken6/tests/minimalbinding/CMakeLists.txt47
-rw-r--r--sources/shiboken6/tests/minimalbinding/brace_pattern_test.py87
-rw-r--r--sources/shiboken6/tests/minimalbinding/containeruser_test.py44
-rw-r--r--sources/shiboken6/tests/minimalbinding/global.h10
-rw-r--r--sources/shiboken6/tests/minimalbinding/listuser_test.py376
-rw-r--r--sources/shiboken6/tests/minimalbinding/minbool_test.py46
-rw-r--r--sources/shiboken6/tests/minimalbinding/minimal-binding.txt.in16
-rw-r--r--sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject10
-rw-r--r--sources/shiboken6/tests/minimalbinding/obj_test.py94
-rw-r--r--sources/shiboken6/tests/minimalbinding/spanuser_test.py42
-rw-r--r--sources/shiboken6/tests/minimalbinding/typedef_test.py107
-rw-r--r--sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml86
-rw-r--r--sources/shiboken6/tests/minimalbinding/val_test.py94
-rw-r--r--sources/shiboken6/tests/otherbinding/CMakeLists.txt58
-rw-r--r--sources/shiboken6/tests/otherbinding/collector_external_operator_test.py39
-rw-r--r--sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py61
-rw-r--r--sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py45
-rw-r--r--sources/shiboken6/tests/otherbinding/global.h11
-rw-r--r--sources/shiboken6/tests/otherbinding/module_reload_test.py38
-rw-r--r--sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py39
-rw-r--r--sources/shiboken6/tests/otherbinding/objtypehashes_test.py34
-rw-r--r--sources/shiboken6/tests/otherbinding/other-binding.txt.in20
-rw-r--r--sources/shiboken6/tests/otherbinding/otherbinding.pyproject17
-rw-r--r--sources/shiboken6/tests/otherbinding/otherderived_test.py109
-rw-r--r--sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py35
-rw-r--r--sources/shiboken6/tests/otherbinding/signature_test.py34
-rw-r--r--sources/shiboken6/tests/otherbinding/smartptr_test.py33
-rw-r--r--sources/shiboken6/tests/otherbinding/star_import_test.py99
-rw-r--r--sources/shiboken6/tests/otherbinding/test_module_template.py24
-rw-r--r--sources/shiboken6/tests/otherbinding/typediscovery_test.py53
-rw-r--r--sources/shiboken6/tests/otherbinding/typesystem_other.xml20
-rw-r--r--sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py34
-rw-r--r--sources/shiboken6/tests/otherbinding/wrongctor_test.py35
-rw-r--r--sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt32
-rw-r--r--sources/shiboken6/tests/qtxmltosphinx/main.cpp115
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt38
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp517
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h40
-rw-r--r--sources/shiboken6/tests/samplebinding/CMakeLists.txt176
-rw-r--r--sources/shiboken6/tests/samplebinding/__del___test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/abstract_test.py87
-rw-r--r--sources/shiboken6/tests/samplebinding/addedfunction_test.py44
-rw-r--r--sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/argumentmodifications_test.py98
-rw-r--r--sources/shiboken6/tests/samplebinding/array_numpy_test.py47
-rw-r--r--sources/shiboken6/tests/samplebinding/array_sequence_test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/bug_554_test.py25
-rw-r--r--sources/shiboken6/tests/samplebinding/bug_704_test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/bytearray_test.py129
-rw-r--r--sources/shiboken6/tests/samplebinding/child_return_test.py43
-rw-r--r--sources/shiboken6/tests/samplebinding/class_fields_test.py173
-rw-r--r--sources/shiboken6/tests/samplebinding/collector_test.py60
-rw-r--r--sources/shiboken6/tests/samplebinding/complex_test.py66
-rw-r--r--sources/shiboken6/tests/samplebinding/conversion_operator_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/copy_test.py65
-rw-r--r--sources/shiboken6/tests/samplebinding/ctorconvrule_test.py30
-rw-r--r--sources/shiboken6/tests/samplebinding/cyclic_test.py89
-rw-r--r--sources/shiboken6/tests/samplebinding/date_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/decisor_test.py52
-rw-r--r--sources/shiboken6/tests/samplebinding/delete_test.py28
-rw-r--r--sources/shiboken6/tests/samplebinding/deprecated_test.py26
-rw-r--r--sources/shiboken6/tests/samplebinding/derived_test.py143
-rw-r--r--sources/shiboken6/tests/samplebinding/duck_punching_test.py158
-rw-r--r--sources/shiboken6/tests/samplebinding/echo_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/enum_test.py138
-rw-r--r--sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py51
-rw-r--r--sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py49
-rw-r--r--sources/shiboken6/tests/samplebinding/event_loop_thread_test.py77
-rw-r--r--sources/shiboken6/tests/samplebinding/exception_test.py71
-rw-r--r--sources/shiboken6/tests/samplebinding/filter_test.py29
-rw-r--r--sources/shiboken6/tests/samplebinding/global.h73
-rw-r--r--sources/shiboken6/tests/samplebinding/handleholder_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/hashabletype_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/ignorederefop_test.py22
-rw-r--r--sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py136
-rw-r--r--sources/shiboken6/tests/samplebinding/implicitconv_test.py46
-rw-r--r--sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py30
-rw-r--r--sources/shiboken6/tests/samplebinding/injectcode_test.py119
-rw-r--r--sources/shiboken6/tests/samplebinding/innerclass_test.py23
-rw-r--r--sources/shiboken6/tests/samplebinding/intlist_test.py80
-rw-r--r--sources/shiboken6/tests/samplebinding/intwrapper_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py45
-rw-r--r--sources/shiboken6/tests/samplebinding/keep_reference_test.py63
-rw-r--r--sources/shiboken6/tests/samplebinding/list_test.py104
-rw-r--r--sources/shiboken6/tests/samplebinding/lock_test.py78
-rw-r--r--sources/shiboken6/tests/samplebinding/map_test.py63
-rw-r--r--sources/shiboken6/tests/samplebinding/metaclass_test.py52
-rw-r--r--sources/shiboken6/tests/samplebinding/mi_virtual_methods_test.py68
-rw-r--r--sources/shiboken6/tests/samplebinding/mixed_mi_test.py54
-rw-r--r--sources/shiboken6/tests/samplebinding/modelindex_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/modelview_test.py61
-rw-r--r--sources/shiboken6/tests/samplebinding/modifications_test.py224
-rw-r--r--sources/shiboken6/tests/samplebinding/modified_constructor_test.py28
-rw-r--r--sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py233
-rw-r--r--sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py97
-rw-r--r--sources/shiboken6/tests/samplebinding/multiple_derived_test.py223
-rw-r--r--sources/shiboken6/tests/samplebinding/namespace_test.py68
-rw-r--r--sources/shiboken6/tests/samplebinding/newdivision_test.py25
-rw-r--r--sources/shiboken6/tests/samplebinding/nondefaultctor_test.py53
-rw-r--r--sources/shiboken6/tests/samplebinding/nontypetemplate_test.py41
-rw-r--r--sources/shiboken6/tests/samplebinding/nonzero_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/numericaltypedef_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/numpy_test.py41
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttype_test.py110
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py50
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py27
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypelayout_test.py301
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py42
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py31
-rw-r--r--sources/shiboken6/tests/samplebinding/oddbool_test.py79
-rw-r--r--sources/shiboken6/tests/samplebinding/onlycopyclass_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/overflow_test.py75
-rw-r--r--sources/shiboken6/tests/samplebinding/overload_sorting_test.py85
-rw-r--r--sources/shiboken6/tests/samplebinding/overload_test.py189
-rw-r--r--sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py44
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py44
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py71
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py95
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py54
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py48
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py111
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_transference_test.py71
-rw-r--r--sources/shiboken6/tests/samplebinding/pair_test.py89
-rw-r--r--sources/shiboken6/tests/samplebinding/pen_test.py58
-rw-r--r--sources/shiboken6/tests/samplebinding/point_test.py98
-rw-r--r--sources/shiboken6/tests/samplebinding/pointerholder_test.py41
-rw-r--r--sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py56
-rw-r--r--sources/shiboken6/tests/samplebinding/pointf_test.py51
-rw-r--r--sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/privatector_test.py69
-rw-r--r--sources/shiboken6/tests/samplebinding/privatedtor_test.py85
-rw-r--r--sources/shiboken6/tests/samplebinding/protected_test.py401
-rw-r--r--sources/shiboken6/tests/samplebinding/pstrlist_test.py32
-rw-r--r--sources/shiboken6/tests/samplebinding/pystr_test.py29
-rw-r--r--sources/shiboken6/tests/samplebinding/python_thread_test.py96
-rw-r--r--sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/reference_test.py107
-rw-r--r--sources/shiboken6/tests/samplebinding/referencetopointer_test.py78
-rw-r--r--sources/shiboken6/tests/samplebinding/renaming_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/return_null_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/richcompare_test.py28
-rw-r--r--sources/shiboken6/tests/samplebinding/sample-binding.txt.in16
-rw-r--r--sources/shiboken6/tests/samplebinding/sample_test.py76
-rw-r--r--sources/shiboken6/tests/samplebinding/samplebinding.pyproject131
-rw-r--r--sources/shiboken6/tests/samplebinding/samplesnippets.cpp54
-rw-r--r--sources/shiboken6/tests/samplebinding/simplefile_glue.cpp9
-rw-r--r--sources/shiboken6/tests/samplebinding/simplefile_test.py60
-rw-r--r--sources/shiboken6/tests/samplebinding/size_test.py100
-rw-r--r--sources/shiboken6/tests/samplebinding/snakecase_test.py60
-rw-r--r--sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py91
-rw-r--r--sources/shiboken6/tests/samplebinding/stdcomplex_test.py71
-rw-r--r--sources/shiboken6/tests/samplebinding/str_test.py97
-rw-r--r--sources/shiboken6/tests/samplebinding/strlist_test.py94
-rw-r--r--sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py63
-rw-r--r--sources/shiboken6/tests/samplebinding/time_test.py120
-rw-r--r--sources/shiboken6/tests/samplebinding/transform_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/typeconverters_test.py190
-rw-r--r--sources/shiboken6/tests/samplebinding/typedealloc_test.py60
-rw-r--r--sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystem_sample.xml2457
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystypedef_test.py29
-rw-r--r--sources/shiboken6/tests/samplebinding/unsafe_parent_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/useraddedctor_test.py26
-rw-r--r--sources/shiboken6/tests/samplebinding/virtualdtor_test.py63
-rw-r--r--sources/shiboken6/tests/samplebinding/virtualmethods_test.py130
-rw-r--r--sources/shiboken6/tests/samplebinding/visibilitychange_test.py27
-rw-r--r--sources/shiboken6/tests/samplebinding/voidholder_test.py50
-rw-r--r--sources/shiboken6/tests/samplebinding/weakref_test.py50
-rw-r--r--sources/shiboken6/tests/samplebinding/writableclassdict_test.py37
-rw-r--r--sources/shiboken6/tests/shiboken_paths.py109
-rw-r--r--sources/shiboken6/tests/shiboken_test_helper.py13
-rw-r--r--sources/shiboken6/tests/shibokenmodule/module_test.py112
-rw-r--r--sources/shiboken6/tests/smartbinding/CMakeLists.txt65
-rw-r--r--sources/shiboken6/tests/smartbinding/global.h4
-rw-r--r--sources/shiboken6/tests/smartbinding/smart-binding.txt.in16
-rw-r--r--sources/shiboken6/tests/smartbinding/smart_pointer_test.py302
-rw-r--r--sources/shiboken6/tests/smartbinding/smartbinding.pyproject7
-rw-r--r--sources/shiboken6/tests/smartbinding/std_optional_test.py69
-rw-r--r--sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py87
-rw-r--r--sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py94
-rw-r--r--sources/shiboken6/tests/smartbinding/typesystem_smart.xml81
-rw-r--r--sources/shiboken6/tests/test_generator/CMakeLists.txt65
-rw-r--r--sources/shiboken6/tests/test_generator/dummygenerator.cpp45
-rw-r--r--sources/shiboken6/tests/test_generator/dummygenerator.h24
-rw-r--r--sources/shiboken6/tests/test_generator/dummygentest-project.txt.in20
-rw-r--r--sources/shiboken6/tests/test_generator/dummygentest.cpp114
-rw-r--r--sources/shiboken6/tests/test_generator/dummygentest.h31
-rw-r--r--sources/shiboken6/tests/test_generator/dummygentestconfig.h.in15
-rw-r--r--sources/shiboken6/tests/test_generator/main.cpp14
-rw-r--r--sources/shiboken6/tests/test_generator/run_test.cmake14
-rw-r--r--sources/shiboken6/tests/test_generator/test_global.h1
-rw-r--r--sources/shiboken6/tests/test_generator/test_typesystem.xml3
373 files changed, 26209 insertions, 0 deletions
diff --git a/sources/shiboken6/tests/CMakeLists.txt b/sources/shiboken6/tests/CMakeLists.txt
new file mode 100644
index 000000000..05f6e9e60
--- /dev/null
+++ b/sources/shiboken6/tests/CMakeLists.txt
@@ -0,0 +1,92 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+
+if(BUILD_TESTS)
+ find_package(Qt${QT_MAJOR_VERSION}Test 6.0 REQUIRED)
+endif()
+
+add_subdirectory(libminimal)
+if(NOT DEFINED MINIMAL_TESTS)
+ add_subdirectory(libsample)
+ add_subdirectory(libsmart)
+ add_subdirectory(libother)
+endif()
+
+shiboken_get_debug_level(debug_level)
+
+if(WIN32 OR DEFINED AVOID_PROTECTED_HACK)
+ message(STATUS "Tests will be generated avoiding the protected hack!")
+ set(GENERATOR_EXTRA_FLAGS --avoid-protected-hack)
+else()
+ message(STATUS "Tests will be generated using the protected hack!")
+ set(GENERATOR_EXTRA_FLAGS )
+endif()
+list(APPEND GENERATOR_EXTRA_FLAGS ${SHIBOKEN_GENERATOR_EXTRA_FLAGS} ${debug_level})
+
+add_subdirectory(minimalbinding)
+if(NOT DEFINED MINIMAL_TESTS)
+ add_subdirectory(samplebinding)
+ add_subdirectory(smartbinding)
+ add_subdirectory(otherbinding)
+endif()
+
+if(DEFINED MINIMAL_TESTS)
+ file(GLOB TEST_FILES minimalbinding/*_test.py)
+else()
+ file(GLOB TEST_FILES minimalbinding/*_test.py
+ samplebinding/*_test.py
+ otherbinding/*_test.py
+ smartbinding/*_test.py
+ shibokenmodule/*_test.py)
+endif()
+list(SORT TEST_FILES)
+
+set(test_blacklist "")
+
+if(SHIBOKEN_IS_CROSS_BUILD)
+ # Python_EXECUTABLE will be empty when cross-building.
+ message(WARNING
+ "Running tests when cross-compiling is not supported because it would require running "
+ "a target python interpreter which might have a different architecture than the host."
+ )
+else()
+ find_package(
+ Python
+ ${USE_PYTHON_VERSION}
+ REQUIRED
+ COMPONENTS Interpreter Development
+ )
+endif()
+
+if(NOT CTEST_TESTING_TIMEOUT)
+ set(CTEST_TESTING_TIMEOUT 60)
+endif()
+
+get_filename_component(BUILD_DIR "${libminimal_BINARY_DIR}" DIRECTORY)
+get_filename_component(BUILD_DIR "${BUILD_DIR}" DIRECTORY)
+get_filename_component(BUILD_DIR "${BUILD_DIR}" DIRECTORY)
+foreach(test_file ${TEST_FILES})
+ string(REGEX MATCH "/([^/]+)(binding|module)/([^/]+)_test.py" tmp ${test_file})
+ set(test_name "${CMAKE_MATCH_1}_${CMAKE_MATCH_3}")
+ list(FIND test_blacklist ${test_name} expect_fail)
+ add_test(${test_name} ${Python_EXECUTABLE} ${test_file})
+ set_tests_properties(${test_name} PROPERTIES ENVIRONMENT "BUILD_DIR=${BUILD_DIR}")
+ set_tests_properties(${test_name} PROPERTIES TIMEOUT ${CTEST_TESTING_TIMEOUT})
+ if (${expect_fail} GREATER -1)
+ set_tests_properties(${test_name} PROPERTIES WILL_FAIL TRUE)
+ endif()
+endforeach()
+
+# dumpcodemodel depends on apiextractor which is not cross-built.
+if(SHIBOKEN_BUILD_TOOLS)
+ add_subdirectory(dumpcodemodel)
+endif()
+
+# FIXME Skipped until add an option to choose the generator
+# add_subdirectory(test_generator)
+
+if (NOT APIEXTRACTOR_DOCSTRINGS_DISABLED)
+ add_subdirectory(qtxmltosphinxtest)
+endif()
diff --git a/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt b/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt
new file mode 100644
index 000000000..e7dbef961
--- /dev/null
+++ b/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+add_executable(dumpcodemodel main.cpp)
+
+target_include_directories(dumpcodemodel
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../ApiExtractor
+)
+
+target_link_libraries(dumpcodemodel
+ PRIVATE
+ apiextractor
+ Qt::Core
+)
diff --git a/sources/shiboken6/tests/dumpcodemodel/main.cpp b/sources/shiboken6/tests/dumpcodemodel/main.cpp
new file mode 100644
index 000000000..eb876634c
--- /dev/null
+++ b/sources/shiboken6/tests/dumpcodemodel/main.cpp
@@ -0,0 +1,260 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <abstractmetabuilder_p.h>
+#include <parser/codemodel.h>
+#include <clangparser/compilersupport.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QCommandLineOption>
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QDateTime>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QVersionNumber>
+#include <QtCore/QXmlStreamWriter>
+
+#include <iostream>
+#include <algorithm>
+#include <iterator>
+
+using namespace Qt::StringLiterals;
+
+static bool optJoinNamespaces = false;
+
+static inline QString languageLevelDescription()
+{
+ return u"C++ Language level (c++11..c++20, default="_s
+ + QLatin1StringView(clang::languageLevelOption(clang::emulatedCompilerLanguageLevel()))
+ + u')';
+}
+
+static void formatDebugOutput(const FileModelItem &dom, bool verbose)
+{
+ QString output;
+ {
+ QDebug debug(&output);
+ if (verbose)
+ debug.setVerbosity(3);
+ debug << dom.get();
+ }
+ std::cout << qPrintable(output) << '\n';
+}
+
+static const char *primitiveTypes[] = {
+ "int", "unsigned", "short", "unsigned short", "long", "unsigned long",
+ "float", "double"
+};
+
+constexpr auto nameAttribute = "name"_L1;
+
+static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass);
+
+static void formatXmlEnum(QXmlStreamWriter &writer, const EnumModelItem &en)
+{
+ writer.writeStartElement(u"enum-type"_s);
+ writer.writeAttribute(nameAttribute, en->name());
+ writer.writeEndElement();
+}
+
+static bool useClass(const ClassModelItem &c)
+{
+ return c->classType() != CodeModel::Union && c->templateParameters().isEmpty()
+ && !c->name().isEmpty(); // No anonymous structs
+}
+
+static void formatXmlScopeMembers(QXmlStreamWriter &writer, const ScopeModelItem &nsp)
+{
+ for (const auto &klass : nsp->classes()) {
+ if (useClass(klass))
+ formatXmlClass(writer, klass);
+ }
+ for (const auto &en : nsp->enums())
+ formatXmlEnum(writer, en);
+}
+
+static bool isPublicCopyConstructor(const FunctionModelItem &f)
+{
+ return f->functionType() == CodeModel::CopyConstructor
+ && f->accessPolicy() == Access::Public && !f->isDeleted();
+}
+
+static void formatXmlLocationComment(QXmlStreamWriter &writer, const CodeModelItem &i)
+{
+ QString comment;
+ QTextStream(&comment) << ' ' << i->fileName() << ':' << i->startLine() << ' ';
+ writer.writeComment(comment);
+}
+
+static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass)
+{
+ // Heuristics for value types: check on public copy constructors.
+ const auto functions = klass->functions();
+ const bool isValueType = std::any_of(functions.cbegin(), functions.cend(),
+ isPublicCopyConstructor);
+ formatXmlLocationComment(writer, klass);
+ writer.writeStartElement(isValueType ? u"value-type"_s
+ : u"object-type"_s);
+ writer.writeAttribute(nameAttribute, klass->name());
+ formatXmlScopeMembers(writer, klass);
+ writer.writeEndElement();
+}
+
+// Check whether a namespace is relevant for type system
+// output, that is, has non template classes, functions or enumerations.
+static bool hasMembers(const NamespaceModelItem &nsp)
+{
+ if (!nsp->namespaces().isEmpty() || !nsp->enums().isEmpty()
+ || !nsp->functions().isEmpty()) {
+ return true;
+ }
+ const auto classes = nsp->classes();
+ return std::any_of(classes.cbegin(), classes.cend(), useClass);
+}
+
+static void startXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem &nsp)
+{
+ formatXmlLocationComment(writer, nsp);
+ writer.writeStartElement(u"namespace-type"_s);
+ writer.writeAttribute(nameAttribute, nsp->name());
+}
+
+static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceModelItem &nsp)
+{
+ auto nestedNamespaces = nsp->namespaces();
+ for (auto i = nestedNamespaces.size() - 1; i >= 0; --i) {
+ if (!hasMembers(nestedNamespaces.at(i)))
+ nestedNamespaces.removeAt(i);
+ }
+ while (!nestedNamespaces.isEmpty()) {
+ auto current = nestedNamespaces.takeFirst();
+ startXmlNamespace(writer, current);
+ formatXmlNamespaceMembers(writer, current);
+ if (optJoinNamespaces) {
+ // Write out members of identical namespaces and remove
+ const QString name = current->name();
+ for (qsizetype i = 0; i < nestedNamespaces.size(); ) {
+ if (nestedNamespaces.at(i)->name() == name) {
+ formatXmlNamespaceMembers(writer, nestedNamespaces.at(i));
+ nestedNamespaces.removeAt(i);
+ } else {
+ ++i;
+ }
+ }
+ }
+ writer.writeEndElement();
+ }
+
+ for (const auto &func : nsp->functions()) {
+ const QString signature = func->typeSystemSignature();
+ if (!signature.contains(u"operator")) { // Skip free operators
+ writer.writeStartElement(u"function"_s);
+ writer.writeAttribute(u"signature"_s, signature);
+ writer.writeEndElement();
+ }
+ }
+ formatXmlScopeMembers(writer, nsp);
+}
+
+static void formatXmlOutput(const FileModelItem &dom)
+{
+ QString output;
+ QXmlStreamWriter writer(&output);
+ writer.setAutoFormatting(true);
+ writer.writeStartDocument();
+ writer.writeStartElement(u"typesystem"_s);
+ writer.writeAttribute(u"package"_s, u"insert_name"_s);
+ writer.writeComment(u"Auto-generated "_s +
+ QDateTime::currentDateTime().toString(Qt::ISODate));
+ for (auto p : primitiveTypes) {
+ writer.writeStartElement(u"primitive-type"_s);
+ writer.writeAttribute(nameAttribute, QLatin1StringView(p));
+ writer.writeEndElement();
+ }
+ formatXmlNamespaceMembers(writer, dom);
+ writer.writeEndElement();
+ writer.writeEndDocument();
+ std::cout << qPrintable(output) << '\n';
+}
+
+static const char descriptionFormat[] = R"(
+Type system dumper
+
+Parses a C++ header and dumps out the classes found in typesystem XML syntax.
+Arguments are arguments to the compiler the last of which should be the header
+or source file.
+It is recommended to create a .hh include file including the desired headers
+and pass that along with the required include paths.
+
+Based on Qt %1 and LibClang v%2.)";
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+
+ QCommandLineParser parser;
+ parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
+ parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments);
+ const QString description =
+ QString::fromLatin1(descriptionFormat).arg(QLatin1StringView(qVersion()),
+ clang::libClangVersion().toString());
+ parser.setApplicationDescription(description);
+ parser.addHelpOption();
+ parser.addVersionOption();
+ QCommandLineOption verboseOption(u"verbose"_s,
+ u"Display verbose output about types"_s);
+ parser.addOption(verboseOption);
+ QCommandLineOption debugOption(u"debug"_s,
+ u"Display debug output"_s);
+ parser.addOption(debugOption);
+
+ QCommandLineOption joinNamespacesOption({u"j"_s, u"join-namespaces"_s},
+ u"Join namespaces"_s);
+ parser.addOption(joinNamespacesOption);
+
+ QCommandLineOption languageLevelOption(u"std"_s,
+ languageLevelDescription(),
+ u"level"_s);
+ parser.addOption(languageLevelOption);
+ parser.addPositionalArgument(u"argument"_s,
+ u"C++ compiler argument"_s,
+ u"argument(s)"_s);
+
+ parser.process(app);
+ const QStringList &positionalArguments = parser.positionalArguments();
+ if (positionalArguments.isEmpty())
+ parser.showHelp(1);
+
+ QByteArrayList arguments;
+ std::transform(positionalArguments.cbegin(), positionalArguments.cend(),
+ std::back_inserter(arguments), QFile::encodeName);
+
+ LanguageLevel level = LanguageLevel::Default;
+ if (parser.isSet(languageLevelOption)) {
+ const QByteArray value = parser.value(languageLevelOption).toLatin1();
+ level = clang::languageLevelFromOption(value.constData());
+ if (level == LanguageLevel::Default) {
+ std::cerr << "Invalid value \"" << value.constData()
+ << "\" for language level option.\n";
+ return -2;
+ }
+ }
+
+ optJoinNamespaces = parser.isSet(joinNamespacesOption);
+
+ const FileModelItem dom = AbstractMetaBuilderPrivate::buildDom(arguments, true, level, 0);
+ if (!dom) {
+ QString message = u"Unable to parse "_s + positionalArguments.join(u' ');
+ std::cerr << qPrintable(message) << '\n';
+ return -2;
+ }
+
+ if (parser.isSet(debugOption))
+ formatDebugOutput(dom, parser.isSet(verboseOption));
+ else
+ formatXmlOutput(dom);
+
+ return 0;
+}
diff --git a/sources/shiboken6/tests/libminimal/CMakeLists.txt b/sources/shiboken6/tests/libminimal/CMakeLists.txt
new file mode 100644
index 000000000..4a10f96bf
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(libminimal)
+
+set(libminimal_SRC
+containeruser.cpp containeruser.h
+libminimalmacros.h
+listuser.cpp listuser.h
+minbool.h
+obj.cpp obj.h
+spanuser.cpp spanuser.h
+typedef.cpp typedef.h
+val.h
+)
+
+add_library(libminimal SHARED ${libminimal_SRC})
+target_include_directories(libminimal PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libminimal PRIVATE LIBMINIMAL_BUILD)
+set_property(TARGET libminimal PROPERTY PREFIX "")
+
diff --git a/sources/shiboken6/tests/libminimal/containeruser.cpp b/sources/shiboken6/tests/libminimal/containeruser.cpp
new file mode 100644
index 000000000..29af52aef
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/containeruser.cpp
@@ -0,0 +1,55 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "containeruser.h"
+
+#include <algorithm>
+#include <numeric>
+
+ContainerUser::ContainerUser() : m_intVector{1, 2, 3}, m_intArray{1, 2, 3}
+{
+}
+
+ContainerUser::~ContainerUser() = default;
+
+std::vector<int> ContainerUser::createIntVector(int num)
+{
+ std::vector<int> retval(num);
+ std::iota(retval.begin(), retval.end(), 0);
+ return retval;
+}
+
+int ContainerUser::sumIntVector(const std::vector<int> &intVector)
+{
+ return std::accumulate(intVector.cbegin(), intVector.cend(), 0);
+}
+
+std::vector<int> &ContainerUser::intVector()
+{
+ return m_intVector;
+}
+
+void ContainerUser::setIntVector(const std::vector<int> &v)
+{
+ m_intVector = v;
+}
+
+std::array<int, 3> ContainerUser::createIntArray()
+{
+ return {1, 2, 3};
+}
+
+int ContainerUser::sumIntArray(const std::array<int, 3> &intArray)
+{
+ return std::accumulate(intArray.cbegin(), intArray.cend(), 0);
+}
+
+std::array<int, 3> &ContainerUser::intArray()
+{
+ return m_intArray;
+}
+
+void ContainerUser::setIntArray(const std::array<int, 3> &a)
+{
+ m_intArray = a;
+}
diff --git a/sources/shiboken6/tests/libminimal/containeruser.h b/sources/shiboken6/tests/libminimal/containeruser.h
new file mode 100644
index 000000000..55e4020ec
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/containeruser.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CONTAINERUSER_H
+#define CONTAINERUSER_H
+
+#include "libminimalmacros.h"
+
+#include <array>
+#include <vector>
+
+/// Exercise simple, sequential containers. More advanced tests are in ListUser
+class LIBMINIMAL_API ContainerUser
+{
+public:
+ ContainerUser();
+ ~ContainerUser();
+
+ static std::vector<int> createIntVector(int num);
+ static int sumIntVector(const std::vector<int> &intVector);
+
+ std::vector<int> &intVector();
+ void setIntVector(const std::vector<int> &);
+
+ static std::array<int, 3> createIntArray();
+ static int sumIntArray(const std::array<int, 3> &intArray);
+
+ std::array<int, 3> &intArray();
+ void setIntArray(const std::array<int, 3> &);
+
+private:
+ std::vector<int> m_intVector;
+ std::array<int, 3> m_intArray;
+};
+
+#endif // CONTAINERUSER_H
diff --git a/sources/shiboken6/tests/libminimal/libminimalmacros.h b/sources/shiboken6/tests/libminimal/libminimalmacros.h
new file mode 100644
index 000000000..099c1f1de
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/libminimalmacros.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef LIBMINIMALMACROS_H
+#define LIBMINIMALMACROS_H
+
+#if defined _WIN32
+# define LIBMINIMAL_EXPORT __declspec(dllexport)
+# ifdef _MSC_VER
+# define LIBMINIMAL_IMPORT __declspec(dllimport)
+# else
+# define LIBMINIMAL_IMPORT
+# endif
+#else
+# define LIBMINIMAL_EXPORT __attribute__ ((visibility("default")))
+# define LIBMINIMAL_IMPORT
+#endif
+
+#ifdef LIBMINIMAL_BUILD
+# define LIBMINIMAL_API LIBMINIMAL_EXPORT
+#else
+# define LIBMINIMAL_API LIBMINIMAL_IMPORT
+#endif
+
+#define LIBMINIMAL_DEFAULT_COPY(Class) \
+ Class(const Class &) noexcept = default; \
+ Class &operator=(const Class &) noexcept = default;
+
+#define LIBMINIMAL_DISABLE_COPY(Class) \
+ Class(const Class &) = delete;\
+ Class &operator=(const Class &) = delete;
+
+#define LIBMINIMAL_DEFAULT_MOVE(Class) \
+ Class(Class &&) noexcept = default; \
+ Class &operator=(Class &&) noexcept = default;
+
+#define LIBMINIMAL_DEFAULT_COPY_MOVE(Class) \
+ LIBMINIMAL_DEFAULT_COPY(Class) \
+ LIBMINIMAL_DEFAULT_MOVE(Class)
+
+#define LIBMINIMAL_DISABLE_MOVE(Class) \
+ Class(Class &&) = delete; \
+ Class &operator=(Class &&) = delete;
+
+#define LIBMINIMAL_DISABLE_COPY_MOVE(Class) \
+ LIBMINIMAL_DISABLE_COPY(Class) \
+ LIBMINIMAL_DISABLE_MOVE(Class)
+
+#endif // LIBMINIMALMACROS_H
diff --git a/sources/shiboken6/tests/libminimal/listuser.cpp b/sources/shiboken6/tests/libminimal/listuser.cpp
new file mode 100644
index 000000000..93c399542
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/listuser.cpp
@@ -0,0 +1,133 @@
+// 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 "listuser.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <numeric>
+
+std::list<int> ListUser::createIntList(int num)
+{
+ std::list<int> retval(num);
+ std::iota(retval.begin(), retval.end(), 0);
+ return retval;
+}
+
+int ListUser::sumIntList(std::list<int> intList)
+{
+ return std::accumulate(intList.begin(), intList.end(), 0);
+}
+
+int ListUser::sumIntListDefaultParamConstRef(const std::list<int> &intList)
+{
+ return sumIntList(intList);
+}
+
+int ListUser::sumIntListDefaultParam(std::list<int> intList)
+{
+ return sumIntList(intList);
+}
+
+std::list<MinBool> ListUser::createMinBoolList(MinBool mb1, MinBool mb2)
+{
+ std::list<MinBool> retval;
+ retval.push_back(mb1);
+ retval.push_back(mb2);
+ return retval;
+}
+
+MinBool ListUser::oredMinBoolList(std::list<MinBool> minBoolList)
+{
+ MinBool result(false);
+ for (const auto &m : minBoolList)
+ result |= m;
+ return result;
+}
+
+std::list<Val> ListUser::createValList(int num)
+{
+ std::list<Val> retval;
+ for (int i = 0; i < num; ++i)
+ retval.push_back(Val(i));
+ return retval;
+}
+
+int ListUser::sumValList(std::list<Val> valList)
+{
+ int total = 0;
+ for (const auto &v : valList)
+ total += v.valId();
+ return total;
+}
+std::list<Obj*> ListUser::createObjList(Obj* o1, Obj* o2)
+{
+ std::list<Obj*> retval;
+ retval.push_back(o1);
+ retval.push_back(o2);
+ return retval;
+}
+
+int ListUser::sumObjList(std::list<Obj*> objList)
+{
+ int total = 0;
+ for (const auto *obj : objList)
+ total += obj->objId();
+ return total;
+}
+
+std::list<std::list<int> > ListUser::createListOfIntLists(int num)
+{
+ std::list<std::list<int> > retval;
+ for (int i = 0; i < num; ++i)
+ retval.push_back(createIntList(num));
+ return retval;
+}
+
+int ListUser::sumListOfIntLists(std::list<std::list<int> > intListList)
+{
+ int total = 0;
+ for (const auto &list : intListList)
+ total += std::accumulate(list.begin(), list.end(), 0);
+ return total;
+}
+
+void ListUser::setStdIntList(const std::list<int> &l)
+{
+ m_stdIntList = l;
+}
+
+std::list<int> &ListUser::getIntList()
+{
+ return m_stdIntList;
+}
+
+const std::list<int> &ListUser::getConstIntList() const
+{
+ return m_stdIntList;
+}
+
+int ListUser::modifyIntListPtr(std::list<int> *list) const
+{
+ const int oldSize = int(list->size());
+ list->push_back(42);
+ return oldSize;
+}
+
+std::list<int> *ListUser::returnIntListByPtr() const
+{
+ return nullptr;
+}
+
+int ListUser::callReturnIntListByPtr() const
+{
+ auto *list = returnIntListByPtr();
+ return list != nullptr ? int(list->size()) : 0;
+}
+
+int ListUser::modifyDoubleListPtr(std::list<double> *list) const
+{
+ const int oldSize = int(list->size());
+ list->push_back(42);
+ return oldSize;
+}
diff --git a/sources/shiboken6/tests/libminimal/listuser.h b/sources/shiboken6/tests/libminimal/listuser.h
new file mode 100644
index 000000000..9904ef27d
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/listuser.h
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef LISTUSER_H
+#define LISTUSER_H
+
+#include "obj.h"
+#include "val.h"
+#include "minbool.h"
+
+#include "libminimalmacros.h"
+
+#include <list>
+
+struct LIBMINIMAL_API ListUser
+{
+ LIBMINIMAL_DEFAULT_COPY(ListUser)
+ LIBMINIMAL_DISABLE_MOVE(ListUser)
+
+ ListUser() noexcept = default;
+ virtual ~ListUser() = default;
+
+ // List of C++ primitive type items
+ virtual std::list<int> createIntList(int num);
+ std::list<int> callCreateIntList(int num) { return createIntList(num); }
+ virtual int sumIntList(std::list<int> intList);
+ int callSumIntList(std::list<int> intList) { return sumIntList(intList); }
+
+ int sumIntListDefaultParamConstRef(const std::list<int> &intList = {1, 2, 3});
+ int sumIntListDefaultParam(std::list<int> intList = {1, 2, 3});
+
+ // List of C++ MinBool objects used as primitives in Python
+ virtual std::list<MinBool> createMinBoolList(MinBool mb1, MinBool mb2);
+ std::list<MinBool> callCreateMinBoolList(MinBool mb1, MinBool mb2) { return createMinBoolList(mb1, mb2); }
+ virtual MinBool oredMinBoolList(std::list<MinBool> minBoolList);
+ MinBool callOredMinBoolList(std::list<MinBool> minBoolList) { return oredMinBoolList(minBoolList); }
+
+ // List of C++ value types
+ virtual std::list<Val> createValList(int num);
+ std::list<Val> callCreateValList(int num) { return createValList(num); }
+ virtual int sumValList(std::list<Val> valList);
+ int callSumValList(std::list<Val> valList) { return sumValList(valList); }
+
+ // List of C++ object types
+ virtual std::list<Obj*> createObjList(Obj* o1, Obj* o2);
+ std::list<Obj*> callCreateObjList(Obj* o1, Obj* o2) { return createObjList(o1, o2); }
+ virtual int sumObjList(std::list<Obj*> objList);
+ int callSumObjList(std::list<Obj*> objList) { return sumObjList(objList); }
+
+ // List of lists of C++ primitive type items
+ virtual std::list<std::list<int> > createListOfIntLists(int num);
+ std::list<std::list<int> > callCreateListOfIntLists(int num) { return createListOfIntLists(num); }
+ virtual int sumListOfIntLists(std::list<std::list<int> > intListList);
+ int callSumListOfIntLists(std::list<std::list<int> > intListList) { return sumListOfIntLists(intListList); }
+
+ void setStdIntList(const std::list<int> &l);
+ std::list<int> &getIntList();
+ const std::list<int> &getConstIntList() const;
+
+ int modifyIntListPtr(std::list<int> *list) const;
+
+ virtual std::list<int> *returnIntListByPtr() const;
+
+ int callReturnIntListByPtr() const;
+
+ int modifyDoubleListPtr(std::list<double> *list) const;
+
+ std::list<int> m_stdIntList;
+};
+
+#endif // LISTUSER_H
+
diff --git a/sources/shiboken6/tests/libminimal/minbool.h b/sources/shiboken6/tests/libminimal/minbool.h
new file mode 100644
index 000000000..e460f466b
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/minbool.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef MINBOOL_H
+#define MINBOOL_H
+
+#include "libminimalmacros.h"
+
+class LIBMINIMAL_API MinBool
+{
+public:
+ inline explicit MinBool(bool b) : m_value(b) {}
+ bool value() const { return m_value; }
+ inline MinBool operator!() const { return MinBool(!m_value); }
+ inline MinBool& operator|=(const MinBool& other) {
+ m_value |= other.m_value;
+ return *this;
+ }
+
+private:
+ bool m_value;
+};
+
+inline bool operator==(MinBool b1, bool b2) { return (!b1).value() == !b2; }
+inline bool operator==(bool b1, MinBool b2) { return (!b1) == (!b2).value(); }
+inline bool operator==(MinBool b1, MinBool b2) { return (!b1).value() == (!b2).value(); }
+inline bool operator!=(MinBool b1, bool b2) { return (!b1).value() != !b2; }
+inline bool operator!=(bool b1, MinBool b2) { return (!b1) != (!b2).value(); }
+inline bool operator!=(MinBool b1, MinBool b2) { return (!b1).value() != (!b2).value(); }
+
+class LIBMINIMAL_API MinBoolUser
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY(MinBoolUser)
+ LIBMINIMAL_DISABLE_MOVE(MinBoolUser)
+
+ MinBoolUser() noexcept : m_minbool(MinBool(false)) {}
+ virtual ~MinBoolUser() = default;
+ inline MinBool minBool() { return m_minbool; }
+ inline void setMinBool(MinBool minBool) { m_minbool = minBool; }
+ virtual MinBool invertedMinBool() { return !m_minbool; }
+ inline MinBool callInvertedMinBool() { return invertedMinBool(); }
+
+private:
+ MinBool m_minbool;
+};
+
+#endif
diff --git a/sources/shiboken6/tests/libminimal/obj.cpp b/sources/shiboken6/tests/libminimal/obj.cpp
new file mode 100644
index 000000000..a63a9c3c9
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/obj.cpp
@@ -0,0 +1,16 @@
+// 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 "obj.h"
+
+Obj::Obj(int objId) noexcept : m_objId(objId)
+{
+}
+
+Obj::~Obj() = default;
+
+bool Obj::virtualMethod(int val)
+{
+ return !bool(val%2);
+}
+
diff --git a/sources/shiboken6/tests/libminimal/obj.h b/sources/shiboken6/tests/libminimal/obj.h
new file mode 100644
index 000000000..be0bfb52b
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/obj.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OBJ_H
+#define OBJ_H
+
+#include "libminimalmacros.h"
+
+class LIBMINIMAL_API Obj
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Obj)
+
+ explicit Obj(int objId) noexcept;
+ virtual ~Obj();
+
+ int objId() const { return m_objId; }
+ void setObjId(int objId) { m_objId = objId; }
+
+ virtual bool virtualMethod(int val);
+ bool callVirtualMethod(int val) { return virtualMethod(val); }
+
+ virtual Obj* passObjectType(Obj* obj) { return obj; }
+ Obj* callPassObjectType(Obj* obj) { return passObjectType(obj); }
+
+ virtual Obj* passObjectTypeReference(Obj& obj) { return &obj; }
+ Obj* callPassObjectTypeReference(Obj& obj) { return passObjectTypeReference(obj); }
+
+private:
+ int m_objId;
+};
+
+#endif // OBJ_H
+
diff --git a/sources/shiboken6/tests/libminimal/spanuser.cpp b/sources/shiboken6/tests/libminimal/spanuser.cpp
new file mode 100644
index 000000000..fea9cd68e
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/spanuser.cpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "spanuser.h"
+
+#include <numeric>
+
+SpanUser::SpanUser() = default;
+
+bool SpanUser::enabled()
+{
+#if __cplusplus >= 202002L
+ return true;
+#else
+ return false;
+#endif
+}
+
+#if __cplusplus >= 202002L
+IntSpan3 SpanUser::getIntSpan3()
+{
+ static int iv[] = {1, 2, 3};
+ return IntSpan3(iv);
+}
+
+IntSpan SpanUser::getIntSpan()
+{
+ static int iv[] = {1, 2, 3};
+ return IntSpan(iv);
+}
+
+ConstIntSpan3 SpanUser::getConstIntSpan3()
+{
+ static const int civ[] = {1, 2, 3};
+ return ConstIntSpan3(civ);
+}
+
+IntSpan3 SpanUser::getIntSpan3_OpaqueContainer()
+{
+ static int iv[] = {1, 2, 3};
+ return IntSpan3(iv);
+}
+
+int SpanUser::sumIntSpan3(IntSpan3 isp3)
+{
+ return std::accumulate(isp3.begin(), isp3.end(), 0);
+}
+
+int SpanUser::sumIntSpan(IntSpan isp)
+{
+ return std::accumulate(isp.begin(), isp.end(), 0);
+}
+
+int SpanUser::sumConstIntSpan3(ConstIntSpan3 ispc3)
+{
+ return std::accumulate(ispc3.begin(), ispc3.end(), 0);
+}
+#endif // C++ 20
diff --git a/sources/shiboken6/tests/libminimal/spanuser.h b/sources/shiboken6/tests/libminimal/spanuser.h
new file mode 100644
index 000000000..c78ba35e7
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/spanuser.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SPANUSER_H
+#define SPANUSER_H
+
+#include "libminimalmacros.h"
+
+#if __cplusplus >= 202002L
+# include <span>
+
+using IntSpan3 = std::span<int, 3>;
+using IntSpan = std::span<int>;
+using ConstIntSpan3 = std::span<const int, 3>;
+#endif
+
+struct LIBMINIMAL_API SpanUser
+{
+ SpanUser();
+
+ static bool enabled();
+
+#if __cplusplus >= 202002L
+ static IntSpan3 getIntSpan3();
+ static IntSpan getIntSpan();
+ static ConstIntSpan3 getConstIntSpan3();
+ static IntSpan3 getIntSpan3_OpaqueContainer();
+
+ static int sumIntSpan3(IntSpan3 isp3);
+ static int sumIntSpan(IntSpan isp);
+ static int sumConstIntSpan3(ConstIntSpan3 ispc3);
+#endif // C++ 20
+};
+
+#endif // SPANUSER_H
diff --git a/sources/shiboken6/tests/libminimal/typedef.cpp b/sources/shiboken6/tests/libminimal/typedef.cpp
new file mode 100644
index 000000000..115b7be0a
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/typedef.cpp
@@ -0,0 +1,50 @@
+// 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 "typedef.h"
+
+//
+// Test wrapping of a typedef
+//
+bool arrayFuncInt(std::vector<int> a)
+{
+ return a.empty();
+}
+
+bool arrayFuncIntTypedef(MyArray a)
+{
+ return arrayFuncInt(a);
+}
+
+std::vector<int> arrayFuncIntReturn(int size)
+{
+ return std::vector<int>(size);
+}
+
+MyArray arrayFuncIntReturnTypedef(int size)
+{
+ return arrayFuncIntReturn(size);
+}
+
+//
+// Test wrapping of a typedef of a typedef
+//
+bool arrayFunc(std::vector<int> a)
+{
+ return a.empty();
+}
+
+bool arrayFuncTypedef(MyArray a)
+{
+ return arrayFunc(a);
+}
+
+std::vector<int> arrayFuncReturn(int size)
+{
+ return std::vector<int>(size);
+}
+
+MyArray arrayFuncReturnTypedef(int size)
+{
+ return arrayFuncReturn(size);
+}
diff --git a/sources/shiboken6/tests/libminimal/typedef.h b/sources/shiboken6/tests/libminimal/typedef.h
new file mode 100644
index 000000000..7116db1b8
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/typedef.h
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TYPEDEF_H
+#define TYPEDEF_H
+
+#include "libminimalmacros.h"
+
+#include <vector>
+
+// Test wrapping of a typedef
+using MyArrayInt = std::vector<int>;
+
+LIBMINIMAL_API bool arrayFuncInt(std::vector<int> a);
+LIBMINIMAL_API bool arrayFuncIntTypedef(MyArrayInt a);
+
+LIBMINIMAL_API std::vector<int> arrayFuncIntReturn(int size);
+LIBMINIMAL_API MyArrayInt arrayFuncIntReturnTypedef(int size);
+
+// Test wrapping of a typedef of a typedef
+using MyArray = MyArrayInt;
+
+LIBMINIMAL_API bool arrayFunc(std::vector<int> a);
+LIBMINIMAL_API bool arrayFuncTypedef(MyArray a);
+
+LIBMINIMAL_API std::vector<int> arrayFuncReturn(int size);
+LIBMINIMAL_API MyArray arrayFuncReturnTypedef(int size);
+
+#endif
diff --git a/sources/shiboken6/tests/libminimal/val.h b/sources/shiboken6/tests/libminimal/val.h
new file mode 100644
index 000000000..50f090a7d
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/val.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef VAL_H
+#define VAL_H
+
+#include "libminimalmacros.h"
+
+class LIBMINIMAL_API Val
+{
+public:
+ explicit Val(int valId) noexcept : m_valId(valId) {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Val)
+
+ virtual ~Val() = default;
+
+ int valId() const { return m_valId; }
+ void setValId(int valId) { m_valId = valId; }
+
+ virtual Val passValueType(Val val) { return val; }
+ Val callPassValueType(Val val) { return passValueType(val); }
+
+ virtual Val* passValueTypePointer(Val* val) { return val; }
+ Val* callPassValueTypePointer(Val* val) { return passValueTypePointer(val); }
+
+ virtual Val* passValueTypeReference(Val& val) { return &val; }
+ Val* callPassValueTypeReference(Val& val) { return passValueTypeReference(val); }
+
+ enum ValEnum { One, Other };
+ ValEnum oneOrTheOtherEnumValue(ValEnum enumValue) { return enumValue == One ? Other : One; }
+private:
+ int m_valId;
+};
+
+#endif // VAL_H
+
diff --git a/sources/shiboken6/tests/libother/CMakeLists.txt b/sources/shiboken6/tests/libother/CMakeLists.txt
new file mode 100644
index 000000000..0379d740b
--- /dev/null
+++ b/sources/shiboken6/tests/libother/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(libother)
+
+set(libother_SRC
+extendsnoimplicitconversion.h
+libothermacros.h
+number.cpp number.h
+otherderived.cpp otherderived.h
+othermultiplederived.cpp othermultiplederived.h
+otherobjecttype.cpp otherobjecttype.h
+othertypesystypedef.cpp othertypesystypedef.h
+smartptrtester.cpp smartptrtester.h
+)
+
+add_library(libother SHARED ${libother_SRC})
+target_include_directories(libother PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libother PRIVATE LIBOTHER_BUILD)
+target_link_libraries(libother PUBLIC libsample libsmart)
+set_property(TARGET libother PROPERTY PREFIX "")
+
+
diff --git a/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h b/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h
new file mode 100644
index 000000000..36d503fe8
--- /dev/null
+++ b/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef EXTENDSNOIMPLICITCONVERSION_H
+#define EXTENDSNOIMPLICITCONVERSION_H
+
+#include "libothermacros.h"
+#include "noimplicitconversion.h"
+
+class ExtendsNoImplicitConversion
+{
+public:
+ explicit ExtendsNoImplicitConversion(int objId) : m_objId(objId) {};
+ inline int objId() const { return m_objId; }
+ inline operator NoImplicitConversion() const { return NoImplicitConversion(m_objId); }
+
+private:
+ int m_objId;
+};
+
+#endif // EXTENDSNOIMPLICITCONVERSION_H
diff --git a/sources/shiboken6/tests/libother/libothermacros.h b/sources/shiboken6/tests/libother/libothermacros.h
new file mode 100644
index 000000000..567757abd
--- /dev/null
+++ b/sources/shiboken6/tests/libother/libothermacros.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef LIBOTHERMACROS_H
+#define LIBOTHERMACROS_H
+
+#include "../libminimal/libminimalmacros.h"
+
+#define LIBOTHER_EXPORT LIBMINIMAL_EXPORT
+#define LIBOTHER_IMPORT LIBMINIMAL_IMPORT
+
+#ifdef LIBOTHER_BUILD
+# define LIBOTHER_API LIBOTHER_EXPORT
+#else
+# define LIBOTHER_API LIBOTHER_IMPORT
+#endif
+
+#endif // LIBOTHERMACROS_H
diff --git a/sources/shiboken6/tests/libother/number.cpp b/sources/shiboken6/tests/libother/number.cpp
new file mode 100644
index 000000000..fbf50dc4a
--- /dev/null
+++ b/sources/shiboken6/tests/libother/number.cpp
@@ -0,0 +1,28 @@
+// 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 "number.h"
+
+#include <sstream>
+
+Str Number::toStr() const
+{
+ std::ostringstream in;
+ in << m_value;
+ return in.str().c_str();
+}
+
+Point operator*(const Point &p, const Number &n)
+{
+ return {p.x() * n.value(), p.y() * n.value()};
+}
+
+Complex Number::toComplex() const
+{
+ return Complex(m_value);
+}
+
+Number Number::fromComplex(Complex cpx)
+{
+ return Number(cpx.real());
+}
diff --git a/sources/shiboken6/tests/libother/number.h b/sources/shiboken6/tests/libother/number.h
new file mode 100644
index 000000000..2c480e7f2
--- /dev/null
+++ b/sources/shiboken6/tests/libother/number.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef NUMBER_H
+#define NUMBER_H
+
+#include "libothermacros.h"
+#include "str.h"
+#include "point.h"
+#include "complex.h"
+
+class LIBOTHER_API Number
+{
+public:
+ explicit Number(int value) : m_value(value) {};
+ inline int value() const { return m_value; }
+
+ Str toStr() const;
+ inline operator Str() const { return toStr(); }
+
+ friend LIBOTHER_API Point operator*(const Point &, const Number &);
+
+ Complex toComplex() const;
+ static Number fromComplex(Complex cpx);
+
+private:
+ int m_value;
+};
+
+LIBOTHER_API Point operator*(const Point &, const Number &);
+
+#endif // NUMBER_H
diff --git a/sources/shiboken6/tests/libother/otherderived.cpp b/sources/shiboken6/tests/libother/otherderived.cpp
new file mode 100644
index 000000000..93a18876e
--- /dev/null
+++ b/sources/shiboken6/tests/libother/otherderived.cpp
@@ -0,0 +1,33 @@
+// 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 "otherderived.h"
+
+OtherDerived::OtherDerived(int id) : Abstract(id)
+{
+}
+
+OtherDerived::~OtherDerived() = default;
+
+Abstract *OtherDerived::createObject()
+{
+ static int id = 100;
+ return new OtherDerived(id++);
+}
+
+void OtherDerived::pureVirtual()
+{
+}
+
+void *OtherDerived::pureVirtualReturningVoidPtr()
+{
+ return nullptr;
+}
+
+void OtherDerived::unpureVirtual()
+{
+}
+
+void OtherDerived::pureVirtualPrivate()
+{
+}
diff --git a/sources/shiboken6/tests/libother/otherderived.h b/sources/shiboken6/tests/libother/otherderived.h
new file mode 100644
index 000000000..d6bde8808
--- /dev/null
+++ b/sources/shiboken6/tests/libother/otherderived.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OTHERDERIVED_H
+#define OTHERDERIVED_H
+
+#include "libothermacros.h"
+#include "abstract.h"
+#include "derived.h"
+#include "objecttype.h"
+#include "complex.h"
+
+class ObjectType;
+
+class LIBOTHER_API OtherDerived : public Abstract
+{
+public:
+ OtherDerived(int id = -1);
+ ~OtherDerived() override;
+ void pureVirtual() override;
+ void *pureVirtualReturningVoidPtr() override;
+ void unpureVirtual() override;
+ PrintFormat returnAnEnum() override { return Short; }
+
+ inline void useObjectTypeFromOtherModule(ObjectType *) {}
+ inline Event useValueTypeFromOtherModule(const Event &e) { return e; }
+ inline Complex useValueTypeFromOtherModule(const Complex &c) { return c; }
+ inline void useEnumTypeFromOtherModule(OverloadedFuncEnum) {}
+
+ // factory method
+ static Abstract *createObject();
+
+ void hideFunction(HideType*) override {}
+
+protected:
+ inline const char *getClassName() { return className(); }
+ const char *className() const override { return "OtherDerived"; }
+
+private:
+ void pureVirtualPrivate() override;
+};
+
+#endif // OTHERDERIVED_H
diff --git a/sources/shiboken6/tests/libother/othermultiplederived.cpp b/sources/shiboken6/tests/libother/othermultiplederived.cpp
new file mode 100644
index 000000000..cfbbfb2c2
--- /dev/null
+++ b/sources/shiboken6/tests/libother/othermultiplederived.cpp
@@ -0,0 +1,24 @@
+// 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 "othermultiplederived.h"
+
+VirtualMethods OtherMultipleDerived::returnUselessClass()
+{
+ return VirtualMethods();
+}
+
+Base1 *OtherMultipleDerived::createObject(const std::string &objName)
+{
+ if (objName == "Base1")
+ return new Base1;
+ if (objName == "MDerived1")
+ return new MDerived1;
+ if (objName == "SonOfMDerived1")
+ return new SonOfMDerived1;
+ if (objName == "MDerived3")
+ return new MDerived3;
+ if (objName == "OtherMultipleDerived")
+ return new OtherMultipleDerived;
+ return nullptr;
+}
diff --git a/sources/shiboken6/tests/libother/othermultiplederived.h b/sources/shiboken6/tests/libother/othermultiplederived.h
new file mode 100644
index 000000000..9f90c43a7
--- /dev/null
+++ b/sources/shiboken6/tests/libother/othermultiplederived.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OTHERMULTIPLEDERIVED_H
+#define OTHERMULTIPLEDERIVED_H
+
+#include "libothermacros.h"
+#include "multiple_derived.h"
+#include "objecttype.h"
+#include "virtualmethods.h"
+
+class ObjectType;
+
+class LIBOTHER_API OtherMultipleDerived : public OtherBase, public MDerived1
+{
+public:
+ // this will use CppCopier from other module (bug#142)
+ VirtualMethods returnUselessClass();
+ static Base1 *createObject(const std::string &objName);
+};
+
+#endif // OTHERMULTIPLEDERIVED_H
diff --git a/sources/shiboken6/tests/libother/otherobjecttype.cpp b/sources/shiboken6/tests/libother/otherobjecttype.cpp
new file mode 100644
index 000000000..eaaa231be
--- /dev/null
+++ b/sources/shiboken6/tests/libother/otherobjecttype.cpp
@@ -0,0 +1,20 @@
+// 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 "otherobjecttype.h"
+
+Collector &operator<<(Collector &collector, const OtherObjectType &obj)
+{
+ collector << obj.identifier() * 2;
+ return collector;
+}
+
+int OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value)
+{
+ return static_cast<int>(value);
+}
+
+int OtherObjectType::enumAsIntForInvisibleNamespace(RemovedNamespace1::RemovedNamespace1_Enum value)
+{
+ return static_cast<int>(value);
+}
diff --git a/sources/shiboken6/tests/libother/otherobjecttype.h b/sources/shiboken6/tests/libother/otherobjecttype.h
new file mode 100644
index 000000000..844795118
--- /dev/null
+++ b/sources/shiboken6/tests/libother/otherobjecttype.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OTHEROBJECTTYPE_H
+#define OTHEROBJECTTYPE_H
+
+#include "libothermacros.h"
+#include "objecttype.h"
+#include "collector.h"
+#include "samplenamespace.h"
+#include "removednamespaces.h"
+
+class LIBOTHER_API OtherObjectType : public ObjectType
+{
+public:
+ static int enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value);
+ static int enumAsIntForInvisibleNamespace(RemovedNamespace1::RemovedNamespace1_Enum value);
+};
+
+LIBOTHER_API Collector &operator<<(Collector &, const OtherObjectType &);
+
+#endif // OTHEROBJECTTYPE_H
diff --git a/sources/shiboken6/tests/libother/othertypesystypedef.cpp b/sources/shiboken6/tests/libother/othertypesystypedef.cpp
new file mode 100644
index 000000000..1a50c4edf
--- /dev/null
+++ b/sources/shiboken6/tests/libother/othertypesystypedef.cpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "othertypesystypedef.h"
+
+OtherValueWithUnitUser::OtherValueWithUnitUser() = default;
+
+
+ValueWithUnit<double, LengthUnit::Inch>
+ OtherValueWithUnitUser::doubleMillimeterToInch(ValueWithUnit<double, LengthUnit::Millimeter> v)
+{
+ return ValueWithUnit<double, LengthUnit::Inch>(v.value() / 254);
+}
+
+ValueWithUnit<int, LengthUnit::Inch>
+ OtherValueWithUnitUser::intMillimeterToInch(ValueWithUnit<int, LengthUnit::Millimeter> v)
+{
+ return ValueWithUnit<int, LengthUnit::Inch>(v.value() / 254);
+}
diff --git a/sources/shiboken6/tests/libother/othertypesystypedef.h b/sources/shiboken6/tests/libother/othertypesystypedef.h
new file mode 100644
index 000000000..999b71fd3
--- /dev/null
+++ b/sources/shiboken6/tests/libother/othertypesystypedef.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OTHERTYPESYSTYPEDEF_H
+#define OTHERTYPESYSTYPEDEF_H
+
+#include "libothermacros.h"
+
+#include <typesystypedef.h>
+
+class LIBOTHER_API OtherValueWithUnitUser
+{
+public:
+ OtherValueWithUnitUser();
+
+ static ValueWithUnit<double, LengthUnit::Inch> doubleMillimeterToInch(ValueWithUnit<double, LengthUnit::Millimeter>);
+
+ static ValueWithUnit<int, LengthUnit::Inch> intMillimeterToInch(ValueWithUnit<int, LengthUnit::Millimeter>);
+};
+
+#endif // OTHERTYPESYSTYPEDEF_H
diff --git a/sources/shiboken6/tests/libother/smartptrtester.cpp b/sources/shiboken6/tests/libother/smartptrtester.cpp
new file mode 100644
index 000000000..1c6496b1a
--- /dev/null
+++ b/sources/shiboken6/tests/libother/smartptrtester.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "smartptrtester.h"
+
+SharedPtr<Str> SmartPtrTester::createSharedPtrStr(const char *what)
+{
+ return {new Str(what)};
+}
+
+std::string SmartPtrTester::valueOfSharedPtrStr(const SharedPtr<Str> &str)
+{
+ return str->cstring();
+}
+
+SharedPtr<Integer> SmartPtrTester::createSharedPtrInteger(int v)
+{
+ auto i = SharedPtr<Integer>(new Integer);
+ i->m_int = v;
+ return i;
+}
+
+int SmartPtrTester::valueOfSharedPtrInteger(const SharedPtr<Integer> &v)
+{
+ return v->m_int;
+}
+
+void SmartPtrTester::fiddleInt(const SharedPtr<int> &) // no binding, should not cause errors
+{
+}
diff --git a/sources/shiboken6/tests/libother/smartptrtester.h b/sources/shiboken6/tests/libother/smartptrtester.h
new file mode 100644
index 000000000..6d7991c06
--- /dev/null
+++ b/sources/shiboken6/tests/libother/smartptrtester.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SMARTPTRTESTER_H
+#define SMARTPTRTESTER_H
+
+#include "libothermacros.h"
+
+#include <smart.h>
+#include <str.h>
+
+class LIBOTHER_API SmartPtrTester
+{
+public:
+ SharedPtr<Str> createSharedPtrStr(const char *what);
+ std::string valueOfSharedPtrStr(const SharedPtr<Str> &);
+
+ SharedPtr<Integer> createSharedPtrInteger(int v);
+ int valueOfSharedPtrInteger(const SharedPtr<Integer> &);
+
+ void fiddleInt(const SharedPtr<int> &);
+};
+
+#endif // SMARTPTRTESTER_H
diff --git a/sources/shiboken6/tests/libsample/CMakeLists.txt b/sources/shiboken6/tests/libsample/CMakeLists.txt
new file mode 100644
index 000000000..926972340
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/CMakeLists.txt
@@ -0,0 +1,95 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(libsample)
+
+set(libsample_SRC
+abstract.cpp abstract.h
+blackbox.cpp blackbox.h
+bucket.cpp bucket.h
+bytearray.cpp bytearray.h
+collector.cpp collector.h
+complex.cpp complex.h
+ctorconvrule.h
+ctparam.cpp ctparam.h
+cvlist.h
+derived.cpp derived.h
+derivedusingct.cpp derivedusingct.h
+echo.cpp echo.h
+exceptiontest.cpp exceptiontest.h
+expression.cpp expression.h
+filter.cpp filter.h
+functions.cpp functions.h
+handle.cpp handle.h
+implicitconv.cpp implicitconv.h
+injectcode.cpp injectcode.h
+intwrapper.cpp intwrapper.h
+libsamplemacros.h
+list.h
+listuser.cpp listuser.h
+mapuser.cpp mapuser.h
+modelindex.h
+modifications.cpp modifications.h
+modified_constructor.cpp modified_constructor.h
+multiple_derived.cpp multiple_derived.h
+noimplicitconversion.h
+nondefaultctor.h
+nontypetemplate.h
+null.h
+objectmodel.cpp objectmodel.h
+objecttype.cpp objecttype.h
+objecttypebyvalue.h
+objecttypeholder.cpp objecttypeholder.h
+objecttypelayout.cpp objecttypelayout.h
+objecttypeoperators.cpp objecttypeoperators.h
+objectview.cpp objectview.h
+oddbool.cpp oddbool.h
+onlycopy.cpp onlycopy.h
+overload.cpp overload.h
+overloadsort.cpp overloadsort.h
+pairuser.cpp pairuser.h
+pen.cpp pen.h
+photon.cpp photon.h
+point.cpp point.h
+pointerholder.h
+pointf.cpp pointf.h
+polygon.cpp polygon.h
+privatector.h
+privatedtor.h
+protected.cpp protected.h
+rect.h
+reference.cpp reference.h
+removednamespaces.h
+renaming.cpp renaming.h
+sample.cpp sample.h
+samplenamespace.cpp samplenamespace.h
+sbkdate.cpp sbkdate.h
+stdcomplex.cpp stdcomplex.h
+simplefile.cpp simplefile.h
+size.cpp size.h
+snakecasetest.cpp snakecasetest.h
+sometime.cpp sometime.h
+str.cpp str.h
+strlist.cpp strlist.h
+templateptr.cpp templateptr.h
+transform.cpp transform.h
+typesystypedef.cpp typesystypedef.h
+valueandvirtual.h
+virtualmethods.cpp virtualmethods.h
+voidholder.h
+)
+
+# Includes windows.h which is causing clashes between class Polygon and
+# wingdi.h's Polygon() function.
+
+if(WIN32)
+ set_source_files_properties(
+ bucket.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON
+ )
+endif()
+
+add_library(libsample SHARED ${libsample_SRC})
+target_include_directories(libsample PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libsample PRIVATE LIBSAMPLE_BUILD)
+set_property(TARGET libsample PROPERTY PREFIX "")
+
diff --git a/sources/shiboken6/tests/libsample/abstract.cpp b/sources/shiboken6/tests/libsample/abstract.cpp
new file mode 100644
index 000000000..0d67d8630
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/abstract.cpp
@@ -0,0 +1,71 @@
+// 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 "abstract.h"
+
+#include <iostream>
+
+const int Abstract::staticPrimitiveField = 0;
+
+Abstract::Abstract(int id) noexcept : m_id(id)
+{
+ bitField = 0;
+}
+
+Abstract::~Abstract() = default;
+
+void Abstract::unpureVirtual()
+{
+}
+
+void Abstract::callUnpureVirtual()
+{
+ this->unpureVirtual();
+}
+
+void Abstract::callPureVirtual()
+{
+ this->pureVirtual();
+}
+
+void Abstract::show(PrintFormat format) const
+{
+ std::cout << '<';
+ switch(format) {
+ case Short:
+ std::cout << this;
+ break;
+ case Verbose:
+ std::cout << "class " << className() << " | cptr: " << this
+ << ", id: " << m_id;
+ break;
+ case OnlyId:
+ std::cout << "id: " << m_id;
+ break;
+ case ClassNameAndId:
+ std::cout << className() << " - id: " << m_id;
+ break;
+ }
+ std::cout << '>';
+}
+
+void Abstract::virtualWithOutParameter(int &x) const
+{
+ x = 42;
+}
+
+int Abstract::callVirtualWithOutParameter() const
+{
+ int x;
+ virtualWithOutParameter(x);
+ return x;
+}
+
+void Abstract::callVirtualGettingEnum(PrintFormat p)
+{
+ virtualGettingAEnum(p);
+}
+
+void Abstract::virtualGettingAEnum(Abstract::PrintFormat)
+{
+}
diff --git a/sources/shiboken6/tests/libsample/abstract.h b/sources/shiboken6/tests/libsample/abstract.h
new file mode 100644
index 000000000..4c1b98d90
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/abstract.h
@@ -0,0 +1,91 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef ABSTRACT_H
+#define ABSTRACT_H
+
+#include "libsamplemacros.h"
+#include "point.h"
+#include "complex.h"
+
+class ObjectType;
+
+// this class is not exported to python
+class HideType
+{
+};
+
+class LIBSAMPLE_API Abstract
+{
+private:
+ enum PrivateEnum {
+ PrivValue0,
+ PrivValue1,
+ PrivValue2 = PrivValue1 + 2
+ };
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Abstract)
+
+ enum PrintFormat {
+ Short,
+ Verbose,
+ OnlyId,
+ ClassNameAndId,
+ DummyItemToTestPrivateEnum1 = Abstract::PrivValue1,
+ DummyItemToTestPrivateEnum2 = PrivValue2,
+ };
+
+ enum Type {
+ TpAbstract, TpDerived
+ };
+
+ static const int staticPrimitiveField;
+ int primitiveField = 123;
+ Complex userPrimitiveField;
+ Point valueTypeField{12, 34};
+ ObjectType *objectTypeField = nullptr;
+ int toBeRenamedField = 123;
+ int readOnlyField = 123;
+
+ explicit Abstract(int id = -1) noexcept;
+ virtual ~Abstract();
+
+ inline int id() const { return m_id; }
+
+ // factory method
+ inline static Abstract *createObject() { return nullptr; }
+
+ // method that receives an Object Type
+ inline static int getObjectId(Abstract *obj) { return obj->id(); }
+
+ virtual void pureVirtual() = 0;
+ virtual void *pureVirtualReturningVoidPtr() = 0;
+ virtual void unpureVirtual();
+
+ virtual PrintFormat returnAnEnum() = 0;
+ void callVirtualGettingEnum(PrintFormat p);
+ virtual void virtualGettingAEnum(PrintFormat p);
+
+ void callPureVirtual();
+ void callUnpureVirtual();
+
+ void show(PrintFormat format = Verbose) const;
+ virtual Type type() const { return TpAbstract; }
+
+ virtual void hideFunction(HideType *arg) = 0;
+
+ virtual void virtualWithOutParameter(int &x) const;
+ int callVirtualWithOutParameter() const;
+
+protected:
+ virtual const char *className() const { return "Abstract"; }
+
+ // Protected bit-field structure member.
+ unsigned int bitField: 1;
+
+private:
+ virtual void pureVirtualPrivate() = 0;
+ int m_id;
+};
+
+#endif // ABSTRACT_H
diff --git a/sources/shiboken6/tests/libsample/blackbox.cpp b/sources/shiboken6/tests/libsample/blackbox.cpp
new file mode 100644
index 000000000..2ac435d3d
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/blackbox.cpp
@@ -0,0 +1,81 @@
+// 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 "blackbox.h"
+
+BlackBox::~BlackBox()
+{
+ // Free all maps.
+ for (const auto &p :m_objects)
+ delete p.second;
+ for (const auto &p : m_points)
+ delete p.second;
+}
+
+int BlackBox::keepObjectType(ObjectType *object)
+{
+ ++m_ticket;
+ m_objects.insert({m_ticket, object});
+ object->setParent(nullptr);
+
+ return m_ticket;
+}
+
+ObjectType *BlackBox::retrieveObjectType(int ticket)
+{
+ const auto it = m_objects.find(ticket);
+ if (it != m_objects.end()) {
+ ObjectType *second = it->second;
+ m_objects.erase(it);
+ return second;
+ }
+ return nullptr;
+}
+
+void BlackBox::disposeObjectType(int ticket)
+{
+ delete retrieveObjectType(ticket);
+}
+
+int BlackBox::keepPoint(Point *point)
+{
+ ++m_ticket;
+ m_points.insert({m_ticket, point});
+ return m_ticket;
+}
+
+Point *BlackBox::retrievePoint(int ticket)
+{
+ const auto it = m_points.find(ticket);
+ if (it != m_points.end()) {
+ Point *second = it->second;
+ m_points.erase(it);
+ return second;
+ }
+ return nullptr;
+}
+
+void BlackBox::disposePoint(int ticket)
+{
+ delete retrievePoint(ticket);
+}
+
+std::list<ObjectType*> BlackBox::objects()
+{
+ std::list<ObjectType*> l;
+
+ for (const auto &p : m_objects)
+ l.push_back(p.second);
+
+ return l;
+}
+
+std::list<Point*> BlackBox::points()
+{
+ std::list<Point*> l;
+
+ for (const auto &p : m_points)
+ l.push_back(p.second);
+
+ return l;
+}
diff --git a/sources/shiboken6/tests/libsample/blackbox.h b/sources/shiboken6/tests/libsample/blackbox.h
new file mode 100644
index 000000000..9d32670dd
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/blackbox.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef BLACKBOX_H
+#define BLACKBOX_H
+
+#include "libsamplemacros.h"
+#include "objecttype.h"
+#include "point.h"
+
+#include <list>
+#include <map>
+
+class LIBSAMPLE_API BlackBox
+{
+public:
+ using ObjectTypeMap = std::map<int, ObjectType*>;
+ using PointMap = std::map<int, Point*>;
+
+ LIBMINIMAL_DEFAULT_COPY_MOVE(BlackBox)
+ BlackBox() noexcept = default;
+ ~BlackBox();
+
+ int keepObjectType(ObjectType *object);
+ ObjectType *retrieveObjectType(int ticket);
+ void disposeObjectType(int ticket);
+
+ int keepPoint(Point *point);
+ Point *retrievePoint(int ticket);
+ void disposePoint(int ticket);
+
+ std::list<ObjectType*> objects();
+ std::list<Point*> points();
+
+ inline void referenceToValuePointer(Point*&) {}
+ inline void referenceToObjectPointer(ObjectType*&) {}
+
+private:
+ ObjectTypeMap m_objects;
+ PointMap m_points;
+ int m_ticket = -1;
+};
+
+#endif // BLACKBOX_H
diff --git a/sources/shiboken6/tests/libsample/bucket.cpp b/sources/shiboken6/tests/libsample/bucket.cpp
new file mode 100644
index 000000000..cafd382a9
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/bucket.cpp
@@ -0,0 +1,59 @@
+// 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 "bucket.h"
+
+#include <iostream>
+
+#ifdef _WIN32 // _WIN32 is defined by all Windows 32 and 64 bit compilers, but not by others.
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# define SLEEP(x) Sleep(x)
+#else
+# include <unistd.h>
+# define SLEEP(x) usleep(x)
+#endif
+
+void Bucket::push(int x)
+{
+ m_data.push_back(x);
+}
+
+int Bucket::pop(void)
+{
+ int x = 0;
+
+ if (!m_data.empty()) {
+ x = m_data.front();
+ m_data.pop_front();
+ }
+
+ return x;
+}
+
+bool Bucket::empty()
+{
+ return m_data.empty();
+}
+
+void Bucket::lock()
+{
+ m_locked = true;
+ while (m_locked) {
+ SLEEP(300);
+ }
+}
+
+void Bucket::unlock()
+{
+ m_locked = false;
+}
+
+bool Bucket::virtualBlockerMethod()
+{
+ lock();
+ // The return value was added just for diversity sake.
+ return true;
+}
diff --git a/sources/shiboken6/tests/libsample/bucket.h b/sources/shiboken6/tests/libsample/bucket.h
new file mode 100644
index 000000000..73e8edd78
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/bucket.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef BUCKET_H
+#define BUCKET_H
+
+#include "libsamplemacros.h"
+#include "objecttype.h"
+
+#include <list>
+
+class ObjectType;
+
+class LIBSAMPLE_API Bucket : public ObjectType
+{
+public:
+ Bucket() = default;
+ void push(int);
+ int pop();
+ bool empty();
+ void lock();
+ inline bool locked() { return m_locked; }
+ void unlock();
+
+ virtual bool virtualBlockerMethod();
+ inline bool callVirtualBlockerMethodButYouDontKnowThis() { return virtualBlockerMethod(); }
+
+private:
+ std::list<int> m_data;
+
+ volatile bool m_locked = false;
+};
+
+#endif // BUCKET_H
diff --git a/sources/shiboken6/tests/libsample/bytearray.cpp b/sources/shiboken6/tests/libsample/bytearray.cpp
new file mode 100644
index 000000000..78d5162b0
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/bytearray.cpp
@@ -0,0 +1,166 @@
+// 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 "bytearray.h"
+
+#include <algorithm>
+#include <iterator>
+#include <cstring>
+
+ByteArray::ByteArray() : m_data(1, '\0')
+{
+}
+
+ByteArray::ByteArray(char c)
+{
+ m_data = std::vector<char>(2);
+ m_data[0] = c;
+ m_data[1] = '\0';
+}
+
+ByteArray::ByteArray(const char *data)
+{
+ size_t len = std::strlen(data);
+ m_data = std::vector<char>(len + 1);
+ memcpy(&m_data[0], data, len);
+ m_data[len] = '\0';
+}
+
+ByteArray::ByteArray(const char *data, int len)
+{
+ m_data = std::vector<char>(len + 1);
+ memcpy(&m_data[0], data, len);
+ m_data[len] = '\0';
+}
+
+int ByteArray::size() const
+{
+ return m_data.size() - 1;
+}
+
+char ByteArray::at(int pos) const
+{
+ return m_data[pos];
+}
+
+const char *ByteArray::data() const
+{
+ return &(m_data[0]);
+}
+
+ByteArray &ByteArray::append(char c)
+{
+ m_data.pop_back();
+ m_data.push_back(c);
+ m_data.push_back('\0');
+ return *this;
+}
+
+ByteArray &ByteArray::append(const char *data)
+{
+ m_data.pop_back();
+ std::copy(data, data + strlen(data), std::back_inserter(m_data));
+ m_data.push_back('\0');
+ return *this;
+}
+
+ByteArray &ByteArray::append(const char *data, int len)
+{
+ m_data.pop_back();
+ std::copy(data, data + len, std::back_inserter(m_data));
+ m_data.push_back('\0');
+ return *this;
+}
+
+ByteArray &ByteArray::append(const ByteArray &other)
+{
+ m_data.pop_back();
+ std::copy(other.m_data.begin(), other.m_data.end(), std::back_inserter(m_data));
+ return *this;
+}
+
+static bool compare(const std::vector<char> &mine, const char *other)
+{
+ for (int i = 0; i < (int)mine.size() - 1; ++i) {
+ if (mine[i] != other[i])
+ return false;
+ }
+ return true;
+}
+
+bool ByteArray::operator==(const ByteArray &other) const
+{
+ return m_data == other.m_data;
+}
+bool operator==(const ByteArray &ba1, const char *ba2)
+{
+ return compare(ba1.m_data, ba2);
+}
+
+bool operator==(const char *ba1, const ByteArray &ba2)
+{
+ return compare(ba2.m_data, ba1);
+}
+
+bool ByteArray::operator!=(const ByteArray &other) const
+{
+ return m_data != other.m_data;
+}
+
+bool operator!=(const ByteArray &ba1, const char *ba2)
+{
+ return !(ba1 == ba2);
+}
+
+bool operator!=(const char *ba1, const ByteArray &ba2)
+{
+ return !(ba1 == ba2);
+}
+
+ByteArray &ByteArray::operator+=(char c)
+{
+ return append(c);
+}
+
+ByteArray &ByteArray::operator+=(const char *data)
+{
+ return append(data);
+}
+
+ByteArray &ByteArray::operator+=(const ByteArray &other)
+{
+ return append(other);
+}
+
+ByteArray operator+(const ByteArray &ba1, const ByteArray &ba2)
+{
+ return ByteArray(ba1) += ba2;
+}
+
+ByteArray operator+(const ByteArray &ba1, const char *ba2)
+{
+ return ByteArray(ba1) += ByteArray(ba2);
+}
+
+ByteArray operator+(const char *ba1, const ByteArray &ba2)
+{
+ return ByteArray(ba1) += ba2;
+}
+
+ByteArray operator+(const ByteArray &ba1, char ba2)
+{
+ return ByteArray(ba1) += ByteArray(ba2);
+}
+
+ByteArray operator+(char ba1, const ByteArray &ba2)
+{
+ return ByteArray(ba1) += ba2;
+}
+
+unsigned int ByteArray::hash(const ByteArray &byteArray)
+{
+ unsigned int result = 0;
+ for (char c : byteArray.m_data)
+ result = 5U * result + unsigned(c);
+ return result;
+}
diff --git a/sources/shiboken6/tests/libsample/bytearray.h b/sources/shiboken6/tests/libsample/bytearray.h
new file mode 100644
index 000000000..35ff22367
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/bytearray.h
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef BYTEARRAY_H
+#define BYTEARRAY_H
+
+#include "str.h"
+#include "libsamplemacros.h"
+
+#include <vector>
+
+class LIBSAMPLE_API ByteArray
+{
+public:
+ ByteArray();
+ explicit ByteArray(char data);
+ explicit ByteArray(const char *data);
+ explicit ByteArray(const char *data, int len);
+
+ int size() const;
+ char at(int i) const;
+ char operator[](int i) const;
+
+ const char *data() const;
+
+ ByteArray &append(char c);
+ ByteArray &append(const char *data);
+ ByteArray &append(const char *data, int len);
+ ByteArray &append(const ByteArray &other);
+
+ bool operator==(const ByteArray &other) const;
+ bool operator!=(const ByteArray &other) const;
+
+ ByteArray &operator+=(char c);
+ ByteArray &operator+=(const char *data);
+ ByteArray &operator+=(const ByteArray &other);
+
+ static unsigned int hash(const ByteArray &byteArray);
+private:
+ std::vector<char> m_data;
+ friend LIBSAMPLE_API bool operator==(const ByteArray &ba1, const char *ba2);
+ friend LIBSAMPLE_API bool operator==(const char *ba1, const ByteArray &ba2);
+ friend LIBSAMPLE_API bool operator!=(const ByteArray &ba1, const char *ba2);
+ friend LIBSAMPLE_API bool operator!=(const char *ba1, const ByteArray &ba2);
+
+ friend LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, const ByteArray &ba2);
+ friend LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, const char *ba2);
+ friend LIBSAMPLE_API ByteArray operator+(const char *ba1, const ByteArray &ba2);
+ friend LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, char ba2);
+ friend LIBSAMPLE_API ByteArray operator+(char ba1, const ByteArray &ba2);
+};
+
+LIBSAMPLE_API bool operator==(const ByteArray &ba1, const char *ba2);
+LIBSAMPLE_API bool operator==(const char *ba1, const ByteArray &ba2);
+LIBSAMPLE_API bool operator!=(const ByteArray &ba1, const char *ba2);
+LIBSAMPLE_API bool operator!=(const char *ba1, const ByteArray &ba2);
+
+LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, const ByteArray &ba2);
+LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, const char *ba2);
+LIBSAMPLE_API ByteArray operator+(const char *ba1, const ByteArray &ba2);
+LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, char ba2);
+LIBSAMPLE_API ByteArray operator+(char ba1, const ByteArray &ba2);
+
+#endif // BYTEARRAY_H
diff --git a/sources/shiboken6/tests/libsample/collector.cpp b/sources/shiboken6/tests/libsample/collector.cpp
new file mode 100644
index 000000000..579239bcb
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/collector.cpp
@@ -0,0 +1,37 @@
+// 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 "collector.h"
+
+void Collector::clear()
+{
+ m_items.clear();
+}
+
+Collector &Collector::operator<<(ObjectType::Identifier item)
+{
+ m_items.push_back(item);
+ return *this;
+}
+
+Collector &Collector::operator<<(const ObjectType *obj)
+{
+ m_items.push_back(obj->identifier());
+ return *this;
+}
+
+std::list<ObjectType::Identifier> Collector::items()
+{
+ return m_items;
+}
+
+int Collector::size() const
+{
+ return int(m_items.size());
+}
+
+Collector &operator<<(Collector &s, const IntWrapper &w)
+{
+ s << w.toInt();
+ return s;
+}
diff --git a/sources/shiboken6/tests/libsample/collector.h b/sources/shiboken6/tests/libsample/collector.h
new file mode 100644
index 000000000..26766847a
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/collector.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef COLLECTOR_H
+#define COLLECTOR_H
+
+#include "libsamplemacros.h"
+#include "intwrapper.h"
+#include "objecttype.h"
+
+#include <list>
+
+class LIBSAMPLE_API Collector
+{
+public:
+ Collector() noexcept = default;
+ virtual ~Collector() = default;
+ LIBMINIMAL_DISABLE_COPY_MOVE(Collector)
+
+ void clear();
+
+ Collector &operator<<(ObjectType::Identifier item);
+
+ Collector &operator<<(const ObjectType *);
+
+ std::list<ObjectType::Identifier> items();
+ int size() const;
+
+private:
+ std::list<ObjectType::Identifier> m_items;
+};
+
+/* Helper for testing external operators */
+LIBSAMPLE_API Collector &operator<<(Collector &, const IntWrapper &);
+
+#endif // COLLECTOR_H
+
diff --git a/sources/shiboken6/tests/libsample/complex.cpp b/sources/shiboken6/tests/libsample/complex.cpp
new file mode 100644
index 000000000..e3bec9aae
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/complex.cpp
@@ -0,0 +1,24 @@
+// 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 "complex.h"
+
+#include <iostream>
+
+Complex::Complex(double real, double imag) noexcept
+ : m_real(real), m_imag(imag)
+{
+}
+
+Complex Complex::operator+(const Complex &other)
+{
+ Complex result;
+ result.setReal(m_real + other.real());
+ result.setImaginary(m_imag + other.imag());
+ return result;
+}
+
+void Complex::show() const
+{
+ std::cout << "(real: " << m_real << ", imag: " << m_imag << ")";
+}
diff --git a/sources/shiboken6/tests/libsample/complex.h b/sources/shiboken6/tests/libsample/complex.h
new file mode 100644
index 000000000..168fe5c44
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/complex.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef COMPLEX_H
+#define COMPLEX_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API Complex
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Complex)
+
+ explicit Complex(double real = 0.0, double imag = 0.0) noexcept;
+ ~Complex() = default;
+
+ inline double real() const { return m_real; }
+ inline void setReal(double real) { m_real = real; }
+ inline double imag() const { return m_imag; }
+ inline void setImaginary(double imag) { m_imag = imag; }
+
+ Complex operator+(const Complex &other);
+
+ void show() const;
+
+private:
+ double m_real;
+ double m_imag;
+};
+
+#endif // COMPLEX_H
+
diff --git a/sources/shiboken6/tests/libsample/ctorconvrule.h b/sources/shiboken6/tests/libsample/ctorconvrule.h
new file mode 100644
index 000000000..a5411b749
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/ctorconvrule.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CTORCONVRULE_H
+#define CTORCONVRULE_H
+
+#include "libsamplemacros.h"
+
+class CtorConvRule
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(CtorConvRule)
+
+ explicit CtorConvRule(long value) noexcept : m_value(value) {}
+ virtual ~CtorConvRule() = default;
+ virtual void dummyVirtualMethod() {}
+ long value() { return m_value; }
+private:
+ long m_value;
+};
+
+#endif
diff --git a/sources/shiboken6/tests/libsample/ctparam.cpp b/sources/shiboken6/tests/libsample/ctparam.cpp
new file mode 100644
index 000000000..9bbbcfc3f
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/ctparam.cpp
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "ctparam.h"
+
+namespace SampleNamespace
+{
+
+CtParam::CtParam(int value) : m_value(value)
+{
+}
+
+CtParam::~CtParam() = default;
+
+int CtParam::value() const
+{
+ return m_value;
+}
+
+} // namespace SampleNamespace
diff --git a/sources/shiboken6/tests/libsample/ctparam.h b/sources/shiboken6/tests/libsample/ctparam.h
new file mode 100644
index 000000000..fa241b587
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/ctparam.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CTPARAM_H
+#define CTPARAM_H
+
+#include "libsamplemacros.h"
+
+namespace SampleNamespace
+{
+
+class LIBSAMPLE_API CtParam
+{
+public:
+ explicit CtParam(int value);
+ virtual ~CtParam();
+
+ int value() const;
+
+private:
+ int m_value;
+};
+
+} // namespace SampleNamespace
+
+#endif // CTPARAM_H
diff --git a/sources/shiboken6/tests/libsample/cvlist.h b/sources/shiboken6/tests/libsample/cvlist.h
new file mode 100644
index 000000000..e09c7d943
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/cvlist.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CONSTVALUELIST_H
+#define CONSTVALUELIST_H
+
+#include <list>
+#include "libsamplemacros.h"
+
+class CVValueType
+{
+ CVValueType();
+};
+
+using const_ptr_value_list = std::list<const CVValueType*>;
+
+// This tests binding generation for a container of a const value type. The
+// class doesn't need to do anything; this is just to verify that the generated
+// binding code (the container conversion in particular) is const-valid.
+
+class CVListUser
+{
+public:
+ static const_ptr_value_list produce() { return {}; }
+ static void consume(const const_ptr_value_list &l) { (void)l; }
+};
+
+#endif // LIST_H
diff --git a/sources/shiboken6/tests/libsample/derived.cpp b/sources/shiboken6/tests/libsample/derived.cpp
new file mode 100644
index 000000000..d20880431
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/derived.cpp
@@ -0,0 +1,88 @@
+// 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 "derived.h"
+
+#include <iostream>
+
+Derived::Derived(int id) noexcept : Abstract(id)
+{
+}
+
+Derived::~Derived() = default;
+
+Abstract *Derived::createObject()
+{
+ static int id = 100;
+ return new Derived(id++);
+}
+
+void Derived::pureVirtual()
+{
+}
+
+void *Derived::pureVirtualReturningVoidPtr()
+{
+ return nullptr;
+}
+
+void Derived::unpureVirtual()
+{
+}
+
+bool Derived::singleArgument(bool b)
+{
+ return !b;
+}
+
+double
+Derived::defaultValue(int n)
+{
+ return ((double) n) + 0.1;
+}
+
+OverloadedFuncEnum Derived::overloaded(int, int)
+{
+ return OverloadedFunc_ii;
+}
+
+OverloadedFuncEnum Derived::overloaded(double)
+{
+ return OverloadedFunc_d;
+}
+
+Derived::OtherOverloadedFuncEnum Derived::otherOverloaded(int, int, bool, double)
+{
+ return OtherOverloadedFunc_iibd;
+}
+
+Derived::OtherOverloadedFuncEnum Derived::otherOverloaded(int, double)
+{
+ return OtherOverloadedFunc_id;
+}
+
+struct SecretClass : public Abstract {
+ void pureVirtual() override {}
+ void *pureVirtualReturningVoidPtr() override { return nullptr; }
+ PrintFormat returnAnEnum() override { return Short; }
+ void hideFunction(HideType*) override {};
+private:
+ void pureVirtualPrivate() override {}
+};
+
+Abstract *Derived::triggerImpossibleTypeDiscovery()
+{
+ return new SecretClass;
+}
+
+struct AnotherSecretClass : public Derived {
+};
+
+Abstract *Derived::triggerAnotherImpossibleTypeDiscovery()
+{
+ return new AnotherSecretClass;
+}
+
+void Derived::pureVirtualPrivate()
+{
+}
diff --git a/sources/shiboken6/tests/libsample/derived.h b/sources/shiboken6/tests/libsample/derived.h
new file mode 100644
index 000000000..cf95cb601
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/derived.h
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef DERIVED_H
+#define DERIVED_H
+
+#include "libsamplemacros.h"
+#include "abstract.h"
+
+enum OverloadedFuncEnum {
+ OverloadedFunc_ii,
+ OverloadedFunc_d
+};
+
+class LIBSAMPLE_API Derived : public Abstract
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Derived)
+
+ enum OtherOverloadedFuncEnum {
+ OtherOverloadedFunc_iibd,
+ OtherOverloadedFunc_id
+ };
+
+ class SomeInnerClass {
+ public:
+ void uselessMethod() {}
+ SomeInnerClass operator+(const SomeInnerClass &other) { return other; }
+ bool operator==(const SomeInnerClass &) const { return true; }
+ };
+
+ explicit Derived(int id = -1) noexcept;
+ ~Derived() override;
+ void pureVirtual() override;
+ void *pureVirtualReturningVoidPtr() override;
+ void unpureVirtual() override;
+
+ PrintFormat returnAnEnum() override { return Short; }
+ Type type() const override { return TpDerived; }
+
+ // factory method
+ static Abstract *createObject();
+
+ // single argument
+ bool singleArgument(bool b);
+
+ // method with default value
+ double defaultValue(int n = 0);
+
+ // overloads
+ OverloadedFuncEnum overloaded(int i = 0, int d = 0);
+ OverloadedFuncEnum overloaded(double n);
+
+ // more overloads
+ OtherOverloadedFuncEnum otherOverloaded(int a, int b, bool c, double d);
+ OtherOverloadedFuncEnum otherOverloaded(int a, double b);
+
+ inline SomeInnerClass returnMyParameter(const SomeInnerClass &s) { return s; }
+
+ static Abstract *triggerImpossibleTypeDiscovery();
+ static Abstract *triggerAnotherImpossibleTypeDiscovery();
+
+ void hideFunction(HideType*) override {}
+protected:
+ const char *getClassName() { return className(); }
+ virtual const char *className() const override { return "Derived"; }
+
+private:
+ void pureVirtualPrivate() override;
+};
+#endif // DERIVED_H
+
diff --git a/sources/shiboken6/tests/libsample/derivedusingct.cpp b/sources/shiboken6/tests/libsample/derivedusingct.cpp
new file mode 100644
index 000000000..720d0ed96
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/derivedusingct.cpp
@@ -0,0 +1,9 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "derivedusingct.h"
+
+void DerivedUsingCt::foo()
+{
+ delete new DerivedUsingCt(42);
+}
diff --git a/sources/shiboken6/tests/libsample/derivedusingct.h b/sources/shiboken6/tests/libsample/derivedusingct.h
new file mode 100644
index 000000000..6bc026d08
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/derivedusingct.h
@@ -0,0 +1,17 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef DERIVEDUSINGCT_H
+#define DERIVEDUSINGCT_H
+
+#include "libsamplemacros.h"
+#include "ctparam.h"
+
+class LIBSAMPLE_API DerivedUsingCt : public SampleNamespace::CtParam
+{
+public:
+ using CtParam::CtParam;
+
+ void foo();
+};
+#endif // DERIVEDUSINGCT_H
diff --git a/sources/shiboken6/tests/libsample/echo.cpp b/sources/shiboken6/tests/libsample/echo.cpp
new file mode 100644
index 000000000..7fa8433d3
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/echo.cpp
@@ -0,0 +1,4 @@
+// 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 "echo.h"
diff --git a/sources/shiboken6/tests/libsample/echo.h b/sources/shiboken6/tests/libsample/echo.h
new file mode 100644
index 000000000..01b11a4a6
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/echo.h
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef ECHO_H
+#define ECHO_H
+
+#include "libsamplemacros.h"
+#include "str.h"
+
+class ObjectType;
+
+class Echo
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Echo)
+
+ Echo() noexcept = default;
+ ~Echo() = default;
+
+ void doNothingWithConstBool(const bool hi);
+ void methodWithNamedArg(const Str &string = Str{});
+
+ Str operator()(const Str &s, const int i) { return s + i; }
+
+ // These method are here just for compilation test purposes
+ Echo &operator<<(unsigned int item);
+ Echo &operator<<(signed int item);
+ Echo &operator<<(const ObjectType *item);
+ Echo &operator<<(Str str);
+};
+
+inline void Echo::doNothingWithConstBool(const bool)
+{
+}
+
+inline void Echo::methodWithNamedArg(const Str &)
+{
+}
+
+inline Echo &Echo::operator<<(unsigned int)
+{
+ return *this;
+}
+
+inline Echo &Echo::operator<<(signed int)
+{
+ return *this;
+}
+
+inline Echo &Echo::operator<<(const ObjectType *)
+{
+ return *this;
+}
+
+inline Echo &Echo::operator<<(Str)
+{
+ return *this;
+}
+
+#endif // ECHO_H
diff --git a/sources/shiboken6/tests/libsample/exceptiontest.cpp b/sources/shiboken6/tests/libsample/exceptiontest.cpp
new file mode 100644
index 000000000..56144e086
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/exceptiontest.cpp
@@ -0,0 +1,46 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "exceptiontest.h"
+
+class TestException : public std::exception
+{
+public:
+ const char *what() const noexcept override
+ { return "TestException"; }
+};
+
+ExceptionTest::ExceptionTest() = default;
+
+int ExceptionTest::intThrowStdException(bool doThrow)
+{
+ if (doThrow)
+ throw TestException();
+ return 1;
+}
+
+void ExceptionTest::voidThrowStdException(bool doThrow)
+{
+ if (doThrow)
+ throw TestException();
+}
+
+int ExceptionTest::intThrowInt(bool doThrow)
+{
+ if (doThrow)
+ throw 42;
+ return 1;
+}
+
+void ExceptionTest::voidThrowInt(bool doThrow)
+{
+ if (doThrow)
+ throw 42;
+}
+
+ExceptionTest *ExceptionTest::create(bool doThrow)
+{
+ if (doThrow)
+ throw TestException();
+ return new ExceptionTest;
+}
diff --git a/sources/shiboken6/tests/libsample/exceptiontest.h b/sources/shiboken6/tests/libsample/exceptiontest.h
new file mode 100644
index 000000000..b5812a090
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/exceptiontest.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef EXCEPTIONTEST_H
+#define EXCEPTIONTEST_H
+
+#include "libsamplemacros.h"
+
+#include <exception>
+
+class LIBSAMPLE_API ExceptionTest
+{
+ public:
+ ExceptionTest();
+
+ int intThrowStdException(bool doThrow);
+ void voidThrowStdException(bool doThrow);
+
+ int intThrowInt(bool doThrow);
+ void voidThrowInt(bool doThrow);
+
+ static ExceptionTest *create(bool doThrow);
+};
+
+#endif // EXCEPTIONTEST_H
diff --git a/sources/shiboken6/tests/libsample/expression.cpp b/sources/shiboken6/tests/libsample/expression.cpp
new file mode 100644
index 000000000..6f3c5fdc5
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/expression.cpp
@@ -0,0 +1,79 @@
+// 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 "expression.h"
+
+#include <sstream>
+
+Expression::Expression() noexcept = default;
+
+Expression::Expression(int number) noexcept : m_value(number)
+{
+}
+
+Expression Expression::operator+(const Expression &other)
+{
+ Expression expr;
+ expr.m_operation = Add;
+ expr.m_operand1 = std::make_shared<Expression>(*this);
+ expr.m_operand2 = std::make_shared<Expression>(other);
+ return expr;
+}
+
+Expression Expression::operator-(const Expression &other)
+{
+ Expression expr;
+ expr.m_operation = Add;
+ expr.m_operand1 = std::make_shared<Expression>(*this);
+ expr.m_operand2 = std::make_shared<Expression>(other);
+ return expr;
+}
+
+Expression Expression::operator<(const Expression &other)
+{
+ Expression expr;
+ expr.m_operation = LessThan;
+ expr.m_operand1 = std::make_shared<Expression>(*this);
+ expr.m_operand2 = std::make_shared<Expression>(other);
+ return expr;
+}
+
+Expression Expression::operator>(const Expression &other)
+{
+ Expression expr;
+ expr.m_operation = GreaterThan;
+ expr.m_operand1 = std::make_shared<Expression>(*this);
+ expr.m_operand2 = std::make_shared<Expression>(other);
+ return expr;
+}
+
+std::string Expression::toString() const
+{
+ std::ostringstream s;
+ if (m_operation == None) {
+ s << m_value;
+ return s.str();
+ }
+
+ s << '(' << m_operand1->toString();
+ switch (m_operation) {
+ case Add:
+ s << '+';
+ break;
+ case Sub:
+ s << '-';
+ break;
+ case LessThan:
+ s << '<';
+ break;
+ case GreaterThan:
+ s << '<';
+ break;
+ default:
+ s << '?';
+ break;
+ }
+ s << m_operand2->toString() << ')';
+ return s.str();
+}
diff --git a/sources/shiboken6/tests/libsample/expression.h b/sources/shiboken6/tests/libsample/expression.h
new file mode 100644
index 000000000..e7c5b7306
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/expression.h
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+
+#ifndef EXPRESSION_H
+#define EXPRESSION_H
+
+#include "libsamplemacros.h"
+
+#include <memory>
+#include <string>
+
+class LIBSAMPLE_API Expression
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Expression)
+
+ enum Operation {
+ None, Add, Sub, LessThan, GreaterThan
+ };
+
+ explicit Expression(int number) noexcept;
+ ~Expression() = default;
+
+ Expression operator>(const Expression &other);
+ Expression operator<(const Expression &other);
+ Expression operator+(const Expression &other);
+ Expression operator-(const Expression &other);
+
+ std::string toString() const;
+private:
+ int m_value = 0;
+ Operation m_operation = None;
+ std::shared_ptr<Expression> m_operand1;
+ std::shared_ptr<Expression> m_operand2;
+
+ Expression() noexcept;
+};
+
+#endif // EXPRESSION_H
diff --git a/sources/shiboken6/tests/libsample/filter.cpp b/sources/shiboken6/tests/libsample/filter.cpp
new file mode 100644
index 000000000..950847985
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/filter.cpp
@@ -0,0 +1,38 @@
+// 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 "filter.h"
+
+Data::Data(Field field, std::string value)
+ : m_field(field), m_value(value)
+{
+}
+
+Union::Union(const Data &filter)
+{
+ m_filters.push_back(filter);
+}
+
+Union::Union(const Intersection &filter)
+{
+ m_filters.push_back(filter);
+}
+
+Intersection::Intersection(const Data &filter)
+{
+ m_filters.push_back(filter);
+}
+
+Intersection::Intersection(const Union &filter)
+{
+ m_filters.push_back(filter);
+}
+
+Intersection operator&(const Intersection &a, const Intersection &b)
+{
+ Intersection filter;
+ filter.addFilter(a);
+ filter.addFilter(b);
+
+ return filter;
+}
diff --git a/sources/shiboken6/tests/libsample/filter.h b/sources/shiboken6/tests/libsample/filter.h
new file mode 100644
index 000000000..d82d38eb8
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/filter.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef FILTER_H
+#define FILTER_H
+
+#include "libsamplemacros.h"
+
+#include <string>
+#include <list>
+
+class Intersection;
+
+class LIBSAMPLE_API Filter
+{
+};
+
+class LIBSAMPLE_API Data : public Filter
+{
+public:
+ enum Field {
+ Name,
+ Album,
+ Year
+ };
+
+ explicit Data(Field field, std::string value);
+
+ Field field() const { return m_field; }
+ std::string value() const { return m_value; }
+
+private:
+ Field m_field;
+ std::string m_value;
+};
+
+class LIBSAMPLE_API Union : public Filter
+{
+public:
+
+ Union(const Data &);
+ Union(const Intersection &);
+ Union() = default;
+
+ std::list<Filter> filters() const { return m_filters; }
+ void addFilter(const Filter &data) { m_filters.push_back(data); }
+
+private:
+ std::list<Filter> m_filters;
+};
+
+class LIBSAMPLE_API Intersection : public Filter
+{
+public:
+ Intersection(const Data &);
+ Intersection(const Union &);
+ Intersection() = default;
+
+ std::list<Filter> filters() const { return m_filters; }
+ void addFilter(const Filter &data) { m_filters.push_back(data); }
+
+private:
+ std::list<Filter> m_filters;
+};
+
+LIBSAMPLE_API Intersection operator&(const Intersection &a, const Intersection &b);
+
+#endif // FILTER_H
+
+
diff --git a/sources/shiboken6/tests/libsample/functions.cpp b/sources/shiboken6/tests/libsample/functions.cpp
new file mode 100644
index 000000000..ad2f4dd5a
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/functions.cpp
@@ -0,0 +1,232 @@
+// 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 "functions.h"
+#include "polygon.h"
+
+#include <cstring>
+#include <algorithm>
+#include <iostream>
+#include <numeric>
+
+void printSomething()
+{
+ std::cout << __FUNCTION__ << std::endl;
+}
+
+int gimmeInt()
+{
+ static int val = 2;
+ val = val * 1.3;
+ return val;
+}
+
+double gimmeDouble()
+{
+ static double val = 7.77;
+ val = val * 1.3;
+ return val;
+}
+
+std::list<Complex> gimmeComplexList()
+{
+ std::list<Complex> lst;
+ lst.push_back(Complex());
+ lst.push_back(Complex(1.1, 2.2));
+ lst.push_back(Complex(1.3, 2.4));
+ return lst;
+}
+
+Complex sumComplexPair(std::pair<Complex, Complex> cpx_pair)
+{
+ return cpx_pair.first + cpx_pair.second;
+}
+
+double multiplyPair(std::pair<double, double> pair)
+{
+ return pair.first * pair.second;
+}
+
+int countCharacters(const char *text)
+{
+ return text != nullptr ? int(std::strlen(text)) : -1;
+}
+
+char *makeCString()
+{
+ char *string = new char[std::strlen(__FUNCTION__) + 1];
+ std::strcpy(string, __FUNCTION__);
+ return string;
+}
+
+const char *returnCString()
+{
+ return __FUNCTION__;
+}
+
+GlobalOverloadFuncEnum overloadedFunc(int)
+{
+ return GlobalOverloadFunc_i;
+}
+
+GlobalOverloadFuncEnum overloadedFunc(double)
+{
+ return GlobalOverloadFunc_d;
+}
+
+char *returnNullPrimitivePointer()
+{
+ return nullptr;
+}
+
+ObjectType *returnNullObjectTypePointer()
+{
+ return nullptr;
+}
+
+Event *returnNullValueTypePointer()
+{
+ return nullptr;
+}
+
+unsigned int doubleUnsignedInt(unsigned int value)
+{
+ return value * 2;
+}
+
+long long doubleLongLong(long long value)
+{
+ return value * 2;
+}
+
+unsigned long long doubleUnsignedLongLong(unsigned long long value)
+{
+ return value * 2;
+}
+
+short doubleShort(short value)
+{
+ return value * 2;
+}
+
+int acceptInt(int x)
+{
+ return x;
+}
+
+const int *acceptIntReturnPtr(int x)
+{
+ return new int(x);
+}
+
+unsigned int acceptUInt(unsigned int x)
+{
+ return x;
+}
+
+long acceptLong(long x)
+{
+ return x;
+}
+
+unsigned long acceptULong(unsigned long x)
+{
+ return x;
+}
+
+double acceptDouble(double x)
+{
+ return x;
+}
+
+int acceptIntReference(int &x)
+{
+ return x;
+}
+
+OddBool acceptOddBoolReference(OddBool &x)
+{
+ return x;
+}
+
+int sumIntArray(int array[4])
+{
+ return std::accumulate(array, array + 4, 0);
+}
+
+double sumDoubleArray(double array[4])
+{
+ return std::accumulate(array, array + 4, double(0));
+}
+
+int sumIntMatrix(int m[2][3])
+{
+ int result = 0;
+ for (int r = 0; r < 2; ++r) {
+ for (int c = 0; c < 3; ++c)
+ result += m[r][c];
+ }
+ return result;
+}
+
+double sumDoubleMatrix(double m[2][3])
+{
+ double result = 0;
+ for (int r = 0; r < 2; ++r) {
+ for (int c = 0; c < 3; ++c)
+ result += m[r][c];
+ }
+ return result;
+}
+
+ArrayModifyTest::ArrayModifyTest() = default;
+
+int ArrayModifyTest::sumIntArray(int n, int *array)
+{
+ return std::accumulate(array, array + n, 0);
+}
+
+ClassWithFunctionPointer::ClassWithFunctionPointer()
+{
+ callFunctionPointer(0, &ClassWithFunctionPointer::doNothing);
+}
+
+void ClassWithFunctionPointer::callFunctionPointer(int dummy, void (*fp)(void *))
+{
+ size_t a = dummy;
+ fp(reinterpret_cast<void *>(a));
+}
+
+void ClassWithFunctionPointer::doNothing(void *operand)
+{
+ (void) operand;
+}
+
+std::string addStdStrings(const std::string &s1, const std::string &s2)
+{
+ return s1 + s2;
+}
+
+std::wstring addStdWStrings(const std::wstring &s1, const std::wstring &s2)
+{
+ return s1 + s2;
+}
+
+void testNullPtrT(std::nullptr_t)
+{
+ std::cout << __FUNCTION__ << '\n';
+}
+
+int takePolygon(Polygon &&p)
+{
+ auto p2 = std::move(p);
+ std::cout << __FUNCTION__ << ' ' << p2.points().size() << " points\n";
+ return int(p2.points().size());
+}
+
+int takeObjectType(ObjectType &&o)
+{
+ auto o2 = std::move(o);
+ std::cout << __FUNCTION__ << ' ' << o2.objectName().cstring() << '\n';
+ return o2.objectName().size();
+}
diff --git a/sources/shiboken6/tests/libsample/functions.h b/sources/shiboken6/tests/libsample/functions.h
new file mode 100644
index 000000000..b745aed6b
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/functions.h
@@ -0,0 +1,91 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef FUNCTIONS_H
+#define FUNCTIONS_H
+
+#include "libsamplemacros.h"
+#include "oddbool.h"
+#include "complex.h"
+#include "objecttype.h"
+
+#include <list>
+#include <utility>
+
+class Polygon;
+
+enum GlobalEnum {
+ NoThing,
+ FirstThing,
+ SecondThing,
+ ThirdThing
+};
+
+enum GlobalOverloadFuncEnum {
+ GlobalOverloadFunc_i,
+ GlobalOverloadFunc_d
+};
+
+LIBSAMPLE_API void printSomething();
+LIBSAMPLE_API int gimmeInt();
+LIBSAMPLE_API double gimmeDouble();
+LIBSAMPLE_API double multiplyPair(std::pair<double, double> pair);
+LIBSAMPLE_API std::list<Complex> gimmeComplexList();
+LIBSAMPLE_API Complex sumComplexPair(std::pair<Complex, Complex> cpx_pair);
+
+LIBSAMPLE_API int countCharacters(const char *text);
+LIBSAMPLE_API char *makeCString();
+LIBSAMPLE_API const char *returnCString();
+
+LIBSAMPLE_API char *returnNullPrimitivePointer();
+LIBSAMPLE_API ObjectType *returnNullObjectTypePointer();
+LIBSAMPLE_API Event *returnNullValueTypePointer();
+
+// Tests overloading on functions (!methods)
+LIBSAMPLE_API GlobalOverloadFuncEnum overloadedFunc(int val);
+LIBSAMPLE_API GlobalOverloadFuncEnum overloadedFunc(double val);
+
+LIBSAMPLE_API unsigned int doubleUnsignedInt(unsigned int value);
+LIBSAMPLE_API long long doubleLongLong(long long value);
+LIBSAMPLE_API unsigned long long doubleUnsignedLongLong(unsigned long long value);
+LIBSAMPLE_API short doubleShort(short value);
+
+LIBSAMPLE_API int acceptInt(int x);
+LIBSAMPLE_API const int *acceptIntReturnPtr(int x);
+LIBSAMPLE_API unsigned int acceptUInt(unsigned int x);
+LIBSAMPLE_API long acceptLong(long x);
+LIBSAMPLE_API unsigned long acceptULong(unsigned long x);
+LIBSAMPLE_API double acceptDouble(double x);
+
+LIBSAMPLE_API int acceptIntReference(int &x);
+LIBSAMPLE_API OddBool acceptOddBoolReference(OddBool &x);
+
+LIBSAMPLE_API int sumIntArray(int array[4]);
+LIBSAMPLE_API double sumDoubleArray(double array[4]);
+LIBSAMPLE_API int sumIntMatrix(int m[2][3]);
+LIBSAMPLE_API double sumDoubleMatrix(double m[2][3]);
+
+LIBSAMPLE_API std::string addStdStrings(const std::string &s1, const std::string &s2);
+LIBSAMPLE_API std::wstring addStdWStrings(const std::wstring &s1, const std::wstring &s2);
+
+LIBSAMPLE_API void testNullPtrT(std::nullptr_t);
+
+LIBSAMPLE_API int takePolygon(Polygon &&p);
+LIBSAMPLE_API int takeObjectType(ObjectType &&o);
+
+class LIBSAMPLE_API ArrayModifyTest
+{
+public:
+ ArrayModifyTest();
+ int sumIntArray(int n, int *array);
+};
+
+class LIBSAMPLE_API ClassWithFunctionPointer
+{
+public:
+ explicit ClassWithFunctionPointer();
+ void callFunctionPointer(int dummy, void (*fp)(void *));
+ static void doNothing(void *operand);
+};
+
+#endif // FUNCTIONS_H
diff --git a/sources/shiboken6/tests/libsample/handle.cpp b/sources/shiboken6/tests/libsample/handle.cpp
new file mode 100644
index 000000000..93c2abe47
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/handle.cpp
@@ -0,0 +1,19 @@
+// 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 "handle.h"
+
+SAMPLE_HANDLE HandleHolder::createHandle()
+{
+ return (SAMPLE_HANDLE) new OBJ;
+}
+
+bool HandleHolder::compare(HandleHolder *other)
+{
+ return other->m_handle == m_handle;
+}
+
+bool HandleHolder::compare2(HandleHolder *other)
+{
+ return other->m_handle2 == m_handle2;
+}
diff --git a/sources/shiboken6/tests/libsample/handle.h b/sources/shiboken6/tests/libsample/handle.h
new file mode 100644
index 000000000..07fc89d15
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/handle.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef HANDLE_H
+#define HANDLE_H
+
+#include "libsamplemacros.h"
+
+/* See http://bugs.pyside.org/show_bug.cgi?id=1105. */
+namespace Foo {
+ using SAMPLE_HANDLE = unsigned long;
+}
+
+class LIBSAMPLE_API OBJ
+{
+};
+
+using SAMPLE_HANDLE = OBJ *;
+
+class LIBSAMPLE_API HandleHolder
+{
+public:
+ explicit HandleHolder(SAMPLE_HANDLE ptr = nullptr) : m_handle(ptr) {}
+ explicit HandleHolder(Foo::SAMPLE_HANDLE val): m_handle2(val) {}
+
+ void set(SAMPLE_HANDLE ptr);
+ inline void set(const Foo::SAMPLE_HANDLE &val) { m_handle2 = val; }
+ inline SAMPLE_HANDLE handle() const { return m_handle; }
+ inline Foo::SAMPLE_HANDLE handle2() const { return m_handle2; }
+
+ static SAMPLE_HANDLE createHandle();
+ bool compare(HandleHolder *other);
+ bool compare2(HandleHolder *other);
+
+private:
+ SAMPLE_HANDLE m_handle = nullptr;
+ Foo::SAMPLE_HANDLE m_handle2 = 0;
+};
+
+inline void HandleHolder::set(SAMPLE_HANDLE)
+{
+ SAMPLE_HANDLE tmp = m_handle;
+ m_handle = tmp;
+}
+
+struct LIBSAMPLE_API PrimitiveStruct {};
+using PrimitiveStructPtr = struct PrimitiveStruct *;
+struct LIBSAMPLE_API PrimitiveStructPointerHolder
+{
+ PrimitiveStructPtr primitiveStructPtr;
+};
+
+#endif // HANDLE_H
diff --git a/sources/shiboken6/tests/libsample/implicitconv.cpp b/sources/shiboken6/tests/libsample/implicitconv.cpp
new file mode 100644
index 000000000..887fa6b1c
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/implicitconv.cpp
@@ -0,0 +1,39 @@
+// 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 "implicitconv.h"
+
+ImplicitConv::ImplicitConv(const Null &) :
+ m_ctorEnum(CtorPrimitiveType)
+{
+}
+
+ImplicitConv ImplicitConv::implicitConvCommon(ImplicitConv implicit)
+{
+ return implicit;
+}
+
+ImplicitConv ImplicitConv::implicitConvDefault(ImplicitConv implicit)
+{
+ return implicit;
+}
+
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(ImplicitConv, int)
+{
+ return ImplicitConv::OverFunc_Ii;
+}
+
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(ImplicitConv, bool)
+{
+ return ImplicitConv::OverFunc_Ib;
+}
+
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(int)
+{
+ return ImplicitConv::OverFunc_i;
+}
+
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(CtorEnum)
+{
+ return ImplicitConv::OverFunc_C;
+}
diff --git a/sources/shiboken6/tests/libsample/implicitconv.h b/sources/shiboken6/tests/libsample/implicitconv.h
new file mode 100644
index 000000000..5d69eb487
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/implicitconv.h
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef IMPLICITCONV_H
+#define IMPLICITCONV_H
+
+#include "libsamplemacros.h"
+#include "null.h"
+
+class ObjectType;
+
+class LIBSAMPLE_API ImplicitConv
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ImplicitConv)
+
+ enum CtorEnum {
+ CtorNone,
+ CtorOne,
+ CtorTwo,
+ CtorThree,
+ CtorObjectTypeReference,
+ CtorPrimitiveType
+ };
+
+ enum ICOverloadedFuncEnum {
+ OverFunc_Ii,
+ OverFunc_Ib,
+ OverFunc_i,
+ OverFunc_C
+ };
+
+ ImplicitConv() noexcept = default;
+ ImplicitConv(int objId) noexcept : m_ctorEnum(CtorOne), m_objId(objId) {}
+ ImplicitConv(CtorEnum ctorEnum) : m_ctorEnum(ctorEnum) {}
+ ImplicitConv(ObjectType&) : m_ctorEnum(CtorObjectTypeReference) {}
+ ImplicitConv(double value, bool=true) : m_ctorEnum(CtorNone), m_value(value) {}
+ ImplicitConv(const Null &null);
+ ~ImplicitConv() = default;
+
+ inline CtorEnum ctorEnum() const { return m_ctorEnum; }
+ inline int objId() const { return m_objId; }
+ inline double value() const { return m_value; }
+
+ static ImplicitConv implicitConvCommon(ImplicitConv implicit);
+
+ static ImplicitConv implicitConvDefault(ImplicitConv implicit = CtorTwo);
+
+ static ICOverloadedFuncEnum implicitConvOverloading(ImplicitConv implicit, int dummyArg);
+ static ICOverloadedFuncEnum implicitConvOverloading(ImplicitConv implicit, bool dummyArg);
+ static ICOverloadedFuncEnum implicitConvOverloading(int dummyArg);
+ static ICOverloadedFuncEnum implicitConvOverloading(CtorEnum dummyArg);
+
+private:
+ CtorEnum m_ctorEnum = CtorNone;
+ int m_objId = -1;
+ double m_value = -1.0;
+};
+
+#endif // IMPLICITCONV_H
diff --git a/sources/shiboken6/tests/libsample/injectcode.cpp b/sources/shiboken6/tests/libsample/injectcode.cpp
new file mode 100644
index 000000000..707d14ed8
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/injectcode.cpp
@@ -0,0 +1,78 @@
+// 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 "injectcode.h"
+
+#include <sstream>
+
+InjectCode::InjectCode() noexcept = default;
+
+InjectCode::~InjectCode() = default;
+
+template<typename T>
+const char *InjectCode::toStr(const T &value)
+{
+ std::ostringstream s;
+ s << value;
+ m_valueHolder = s.str();
+ return m_valueHolder.c_str();
+}
+
+const char *InjectCode::simpleMethod1(int arg0, int arg1)
+{
+ return toStr(arg0 + arg1);
+}
+
+const char *InjectCode::simpleMethod2()
+{
+ return "_";
+}
+
+const char *InjectCode::simpleMethod3(int argc, char **argv)
+{
+ for (int i = 0; i < argc; ++i)
+ m_valueHolder += argv[i];
+ return m_valueHolder.c_str();
+}
+
+const char *InjectCode::overloadedMethod(int arg0, bool arg1)
+{
+ toStr(arg0);
+ m_valueHolder += arg1 ? "true" : "false";
+ return m_valueHolder.c_str();
+}
+
+const char *InjectCode::overloadedMethod(int arg0, double arg1)
+{
+ return toStr(arg0 + arg1);
+}
+
+const char *InjectCode::overloadedMethod(int argc, char **argv)
+{
+ return simpleMethod3(argc, argv);
+}
+
+const char *InjectCode::virtualMethod(int arg)
+{
+ return toStr(arg);
+}
+
+int InjectCode::arrayMethod(int count, int *values) const
+{
+ int ret = 0;
+ for (int i=0; i < count; i++)
+ ret += values[i];
+ return ret;
+}
+
+int InjectCode::sumArrayAndLength(int *values) const
+{
+ int sum = 0;
+
+ while (*values) {
+ sum = sum + *values + 1;
+ ++values;
+ }
+
+ return sum;
+}
diff --git a/sources/shiboken6/tests/libsample/injectcode.h b/sources/shiboken6/tests/libsample/injectcode.h
new file mode 100644
index 000000000..74046dad5
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/injectcode.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef INJECTCODE_H
+#define INJECTCODE_H
+
+#include "libsamplemacros.h"
+
+#include <utility>
+#include <string>
+
+class LIBSAMPLE_API InjectCode
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(InjectCode)
+
+ InjectCode() noexcept;
+ virtual ~InjectCode();
+
+ const char *simpleMethod1(int arg0, int arg1);
+ const char *simpleMethod2();
+ const char *simpleMethod3(int argc, char **argv);
+
+ const char *overloadedMethod(int argc, char **argv);
+ const char *overloadedMethod(int arg0, double arg1);
+ const char *overloadedMethod(int arg0, bool arg1);
+
+ virtual int arrayMethod(int count, int *values) const;
+ inline int callArrayMethod(int count, int *values) const { return arrayMethod(count, values); }
+ virtual const char *virtualMethod(int arg);
+ int sumArrayAndLength(int *values) const;
+
+private:
+ // This attr is just to retain the memory pointed by all return values,
+ // So, the memory returned by all methods will be valid until someone call
+ // another method of this class.
+ std::string m_valueHolder;
+
+ template<typename T>
+ const char *toStr(const T &value);
+};
+
+#endif // INJECTCODE_H
+
diff --git a/sources/shiboken6/tests/libsample/intwrapper.cpp b/sources/shiboken6/tests/libsample/intwrapper.cpp
new file mode 100644
index 000000000..0eaf30465
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/intwrapper.cpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+
+#include "intwrapper.h"
+
+int IntWrapper::toInt() const
+{
+ return m_number;
+}
+
+IntWrapper &IntWrapper::operator ++()
+{
+ ++m_number;
+ return *this;
+}
+
+IntWrapper IntWrapper::operator++(int)
+{
+ IntWrapper result(*this);
+ ++m_number;
+ return result;
+}
+
+IntWrapper &IntWrapper::operator--()
+{
+ --m_number;
+ return *this;
+}
+
+IntWrapper IntWrapper::operator--(int)
+{
+ IntWrapper result(*this);
+ --m_number;
+ return result;
+}
diff --git a/sources/shiboken6/tests/libsample/intwrapper.h b/sources/shiboken6/tests/libsample/intwrapper.h
new file mode 100644
index 000000000..cfda5adc7
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/intwrapper.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef INTWRAPPER_H
+#define INTWRAPPER_H
+
+#include "libsamplemacros.h"
+
+// Wrapper around int for testing operators
+class LIBSAMPLE_API IntWrapper
+{
+public:
+ constexpr explicit IntWrapper(int i) noexcept : m_number(i) {}
+ int toInt() const;
+
+ IntWrapper &operator++();
+ IntWrapper operator++(int); // Postfix
+
+ IntWrapper &operator--();
+ IntWrapper operator--(int); // Postfix
+
+ friend constexpr inline bool operator==(IntWrapper lhs, IntWrapper rhs) noexcept
+ { return lhs.m_number == rhs.m_number; }
+ friend constexpr inline bool operator!=(IntWrapper lhs, IntWrapper rhs) noexcept
+ { return lhs.m_number != rhs.m_number; }
+ friend constexpr inline bool operator<(IntWrapper lhs, IntWrapper rhs) noexcept
+ { return lhs.m_number < rhs.m_number; }
+ friend constexpr inline bool operator>(IntWrapper lhs, IntWrapper rhs) noexcept
+ { return lhs.m_number > rhs.m_number; }
+ friend constexpr inline bool operator<=(IntWrapper lhs, IntWrapper rhs) noexcept
+ { return lhs.m_number <= rhs.m_number; }
+ friend constexpr inline bool operator>=(IntWrapper lhs, IntWrapper rhs) noexcept
+ { return lhs.m_number >= rhs.m_number; }
+
+ constexpr inline IntWrapper &operator+=(IntWrapper i);
+ constexpr inline IntWrapper &operator-=(const IntWrapper i);
+
+ friend constexpr inline IntWrapper operator+(IntWrapper lhs, IntWrapper rhs) noexcept
+ { return IntWrapper(lhs.m_number + rhs.m_number); }
+ friend constexpr inline IntWrapper operator-(IntWrapper lhs, IntWrapper rhs) noexcept
+ { return IntWrapper(lhs.m_number - rhs.m_number); }
+
+ // FIXME: Test spaceship operator with C++ 20:
+ // auto operator<=>(IntWrapper) const = default;
+
+private:
+ int m_number;
+};
+
+constexpr inline IntWrapper &IntWrapper::operator+=(IntWrapper i)
+{
+ m_number += i.m_number;
+ return *this;
+}
+
+constexpr inline IntWrapper &IntWrapper::operator-=(const IntWrapper i)
+{
+ m_number -= i.m_number;
+ return *this;
+}
+
+#endif // INTWRAPPER_H
diff --git a/sources/shiboken6/tests/libsample/libsamplemacros.h b/sources/shiboken6/tests/libsample/libsamplemacros.h
new file mode 100644
index 000000000..93e549bfb
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/libsamplemacros.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef LIBSAMPLEMACROS_H
+#define LIBSAMPLEMACROS_H
+
+#include "../libminimal/libminimalmacros.h"
+
+#define LIBSAMPLE_EXPORT LIBMINIMAL_EXPORT
+#define LIBSAMPLE_IMPORT LIBMINIMAL_IMPORT
+
+#ifdef LIBSAMPLE_BUILD
+# define LIBSAMPLE_API LIBSAMPLE_EXPORT
+#else
+# define LIBSAMPLE_API LIBSAMPLE_IMPORT
+#endif
+
+#endif // LIBSAMPLEMACROS_H
diff --git a/sources/shiboken6/tests/libsample/list.h b/sources/shiboken6/tests/libsample/list.h
new file mode 100644
index 000000000..5e06d2a66
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/list.h
@@ -0,0 +1,99 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef LIST_H
+#define LIST_H
+
+#include <list>
+#include "libsamplemacros.h"
+#include "point.h"
+
+class ObjectType;
+
+template<class T>
+class List : public std::list<T>
+{
+};
+
+class IntList : public List<int>
+{
+public:
+ LIBMINIMAL_DEFAULT_MOVE(IntList)
+
+ enum CtorEnum {
+ NoParamsCtor,
+ IntCtor,
+ CopyCtor,
+ ListOfIntCtor
+ };
+
+ inline IntList() noexcept : m_ctorUsed(NoParamsCtor) {}
+ inline explicit IntList(int val) : m_ctorUsed(IntCtor) { push_back(val); }
+ inline IntList(const List<int> &lst) : List<int>(lst), m_ctorUsed(ListOfIntCtor) {}
+ ~IntList() = default;
+
+ inline IntList(const IntList &lst) : List<int>(lst), m_ctorUsed(CopyCtor) {}
+ IntList &operator=(const IntList &) = default;
+
+ inline void append(int v) { insert(end(), v); }
+ CtorEnum constructorUsed() { return m_ctorUsed; }
+private:
+ CtorEnum m_ctorUsed;
+};
+
+class PointValueList : public List<Point>
+{
+public:
+ LIBMINIMAL_DEFAULT_MOVE(PointValueList)
+
+ enum CtorEnum {
+ NoParamsCtor,
+ PointCtor,
+ CopyCtor,
+ ListOfPointValuesCtor
+ };
+
+ inline PointValueList() noexcept : m_ctorUsed(NoParamsCtor) {}
+ inline explicit PointValueList(Point val) : m_ctorUsed(PointCtor) { push_back(val); }
+ inline PointValueList(const List<Point> &lst) : List<Point>(lst), m_ctorUsed(ListOfPointValuesCtor) {}
+
+ inline PointValueList(const PointValueList &lst) : List<Point>(lst), m_ctorUsed(CopyCtor) {}
+ PointValueList &operator=(const PointValueList &) = default;
+ ~PointValueList() = default;
+
+ inline void append(Point v) { insert(end(), v); }
+ CtorEnum constructorUsed() { return m_ctorUsed; }
+private:
+ CtorEnum m_ctorUsed;
+};
+
+class ObjectTypePtrList : public List<ObjectType*>
+{
+public:
+ LIBMINIMAL_DEFAULT_MOVE(ObjectTypePtrList)
+
+ enum CtorEnum {
+ NoParamsCtor,
+ ObjectTypeCtor,
+ CopyCtor,
+ ListOfObjectTypePtrCtor
+ };
+
+ inline ObjectTypePtrList() = default;
+ inline ObjectTypePtrList(const ObjectTypePtrList &lst) :
+ List<ObjectType*>(lst), m_ctorUsed(CopyCtor) {}
+ inline explicit ObjectTypePtrList(ObjectType *val) :
+ m_ctorUsed(ObjectTypeCtor) { push_back(val); }
+ inline ObjectTypePtrList(const List<ObjectType*> &lst) :
+ List<ObjectType*>(lst), m_ctorUsed(ListOfObjectTypePtrCtor) {}
+ ~ObjectTypePtrList() = default;
+
+ ObjectTypePtrList &operator=(const ObjectTypePtrList &) = default;
+
+ inline void append(ObjectType *v) { insert(end(), v); }
+ CtorEnum constructorUsed() { return m_ctorUsed; }
+private:
+ CtorEnum m_ctorUsed = NoParamsCtor;
+};
+
+#endif // LIST_H
diff --git a/sources/shiboken6/tests/libsample/listuser.cpp b/sources/shiboken6/tests/libsample/listuser.cpp
new file mode 100644
index 000000000..9bb7f7798
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/listuser.cpp
@@ -0,0 +1,63 @@
+// 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 "listuser.h"
+
+#include <numeric>
+#include <cstdlib>
+
+std::list<int> ListUser::callCreateList()
+{
+ return createList();
+}
+
+ListUser::ListUser() = default;
+ListUser::ListUser(const ListUser &other) = default;
+ListUser::ListUser(ListUser &&other) noexcept = default;
+ListUser &ListUser::operator=(const ListUser &other) = default;
+ListUser &ListUser::operator=(ListUser &&other) noexcept = default;
+ListUser::~ListUser() = default;
+
+std::list<int> ListUser::createList()
+{
+ std::list<int> retval;
+ for (int i = 0; i < 4; i++)
+ retval.push_front(rand());
+ return retval;
+}
+
+std::list<Complex> ListUser::createComplexList(Complex cpx0, Complex cpx1)
+{
+ std::list<Complex> retval;
+ retval.push_back(cpx0);
+ retval.push_back(cpx1);
+ return retval;
+}
+
+double ListUser::sumList(std::list<int> vallist)
+{
+ return std::accumulate(vallist.begin(), vallist.end(), 0.0);
+}
+
+double ListUser::sumList(std::list<double> vallist)
+{
+ return std::accumulate(vallist.begin(), vallist.end(), 0.0);
+}
+
+ListUser::ListOfSomething ListUser::listOfPoints(const std::list<Point> &)
+{
+ return ListOfPoint;
+}
+
+ListUser::ListOfSomething ListUser::listOfPoints(const std::list<PointF> &)
+{
+ return ListOfPointF;
+}
+
+void ListUser::multiplyPointList(PointList &points, double multiplier)
+{
+ for (auto *point : points) {
+ point->setX(point->x() * multiplier);
+ point->setY(point->y() * multiplier);
+ }
+}
diff --git a/sources/shiboken6/tests/libsample/listuser.h b/sources/shiboken6/tests/libsample/listuser.h
new file mode 100644
index 000000000..96781ed16
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/listuser.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef LISTUSER_H
+#define LISTUSER_H
+
+#include "complex.h"
+#include "point.h"
+#include "pointf.h"
+
+#include "libsamplemacros.h"
+
+#include <list>
+
+class LIBSAMPLE_API ListUser
+{
+public:
+ using PointList = std::list<Point *>;
+
+ enum ListOfSomething {
+ ListOfPoint,
+ ListOfPointF
+ };
+
+ ListUser();
+ ListUser(const ListUser &other);
+ ListUser(ListUser &&other) noexcept;
+ ListUser &operator=(const ListUser &other);
+ ListUser &operator=(ListUser &&other) noexcept;
+ virtual ~ListUser();
+
+ virtual std::list<int> createList();
+ std::list<int> callCreateList();
+
+ static std::list<Complex> createComplexList(Complex cpx0, Complex cpx1);
+
+ double sumList(std::list<int> vallist);
+ double sumList(std::list<double> vallist);
+
+ static ListOfSomething listOfPoints(const std::list<Point> &pointlist);
+ static ListOfSomething listOfPoints(const std::list<PointF> &pointlist);
+
+ static void multiplyPointList(PointList &points, double multiplier);
+
+ inline void setList(std::list<int> lst) { m_lst = lst; }
+ inline std::list<int> getList() const { return m_lst; }
+
+private:
+ std::list<int> m_lst;
+};
+
+#endif // LISTUSER_H
+
diff --git a/sources/shiboken6/tests/libsample/main.cpp b/sources/shiboken6/tests/libsample/main.cpp
new file mode 100644
index 000000000..1b44642ae
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/main.cpp
@@ -0,0 +1,209 @@
+// 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 <iostream>
+#include <list>
+#include "abstract.h"
+#include "derived.h"
+#include "kindergarten.h"
+#include "complex.h"
+#include "point.h"
+#include "size.h"
+#include "listuser.h"
+#include "samplenamespace.h"
+
+int
+main(int argv, char **argc)
+{
+ std::cout << std::endl;
+
+ Derived derived;
+
+ std::cout << std::endl;
+
+ derived.unpureVirtual();
+ derived.pureVirtual();
+ derived.callPureVirtual();
+
+ std::cout << std::endl;
+ auto *abs = Abstract::createObject();
+ std::cout << "Abstract::createObject(): " << abs << std::endl << std::endl;
+ delete abs;
+
+ abs = Derived::createObject();
+ std::cout << "Derived::createObject() : ";
+ abs->show();
+ std::cout << std::endl;
+ delete abs;
+ std::cout << std::endl;
+
+ abs = Derived::createObject();
+ std::cout << "Derived::createObject() : ";
+ abs->show();
+ std::cout << std::endl;
+ delete abs;
+ std::cout << std::endl;
+
+ std::cout << "\n-----------------------------------------\n";
+
+ KinderGarten kg;
+ Derived *d[] = { 0, 0, 0 };
+
+ for (int i = 0; i < 3; i++) {
+ d[i] = new Derived(i);
+ d[i]->show();
+ std::cout << std::endl;
+ kg.addChild(d[i]);
+ }
+
+ kg.show();
+ std::cout << std::endl;
+
+ std::cout << "\n* kill child ";
+ d[2]->show();
+ std::cout << " ----------------\n";
+ kg.killChild(d[2]);
+ kg.show();
+ std::cout << std::endl;
+
+ std::cout << "\n* release child ";
+ d[1]->show();
+ std::cout << " -------------\n";
+ Abstract *released = kg.releaseChild(d[1]);
+ std::cout << "released: ";
+ released->show();
+ std::cout << std::endl;
+ kg.show();
+ std::cout << "\n\n* kill children ------------------------------------\n";
+ kg.killChildren();
+ kg.show();
+ std::cout << "\n\n-----------------------------------------\n";
+ ListUser lu;
+ std::cout << "ListUser::createList()\n";
+ std::list<int> intlist = lu.createList();
+ for (std::list<int>::iterator it = intlist.begin(); it != intlist.end(); it++)
+ std::cout << "* " << *it << std::endl;
+
+ std::cout << "ListUser::createComplexList\n";
+ std::list<Complex> cpxlist = ListUser::createComplexList(Complex(1.1, 2.2), Complex(3.3, 4.4));
+ for (std::list<Complex>::iterator it = cpxlist.begin(); it != cpxlist.end(); it++) {
+ std::cout << "* ";
+ (*it).show();
+ std::cout << std::endl;
+ }
+ std::cout << "\n-----------------------------------------\n"
+ << "SampleNamespace\n";
+
+ std::cout << "SampleNamespace::RandomNumber: ";
+ std::cout << SampleNamespace::getNumber(SampleNamespace::RandomNumber);
+ std::cout << std::endl;
+ std::cout << "SampleNamespace::UnixTime: ";
+ std::cout << SampleNamespace::getNumber(SampleNamespace::UnixTime);
+ std::cout << std::endl;
+ double val_d = 1.3;
+ std::cout << "SampleNamespace::powerOfTwo(" << val_d << "): ";
+ std::cout << SampleNamespace::powerOfTwo(val_d) << std::endl;
+ int val_i = 7;
+ std::cout << "SampleNamespace::powerOfTwo(" << val_i << "): ";
+ std::cout << SampleNamespace::powerOfTwo(val_i) << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "-----------------------------------------" << std::endl;
+ std::cout << "Point" << std::endl;
+
+ Point p1(1.1, 2.2);
+ std::cout << "p1: ";
+ p1.show();
+ std::cout << std::endl;
+
+ Point p2(3.4, 5.6);
+ std::cout << "p2: ";
+ p2.show();
+ std::cout << std::endl;
+
+ std::cout << "p1 + p2 == ";
+ (p1 + p2).show();
+ std::cout << std::endl;
+
+ std::cout << "p1 * 2.0 == ";
+ (p1 * 2.0).show();
+ std::cout << std::endl;
+
+ std::cout << "1.5 * p2 == ";
+ (1.5 * p2).show();
+ std::cout << std::endl;
+
+ std::cout << "p1: ";
+ p1.show();
+ std::cout << std::endl << "p2: ";
+ p2.show();
+ std::cout << std::endl << "p1 += p2" << std::endl;
+ p1 += p2;
+ std::cout << "p1: ";
+ p1.show();
+ std::cout << std::endl;
+
+ std::cout << "p1 == p2 ? " << ((p1 == p2) ? "true" : "false") << std::endl;
+ std::cout << "p1 == p1 ? " << ((p1 == p1) ? "true" : "false") << std::endl;
+ std::cout << "p2 == p2 ? " << ((p2 == p2) ? "true" : "false") << std::endl;
+
+ std::cout << "-----------------------------------------" << std::endl;
+ std::cout << "Size" << std::endl;
+
+ Size s1(2, 2);
+ std::cout << "s1: ";
+ s1.show();
+ std::cout << ", area: " << s1.calculateArea();
+ std::cout << std::endl;
+
+ Size s2(3, 5);
+ std::cout << "s2: ";
+ s2.show();
+ std::cout << ", area: " << s2.calculateArea();
+ std::cout << std::endl;
+
+ std::cout << std::endl;
+
+ std::cout << "s1 == s2 ? " << ((s1 == s2) ? "true" : "false") << std::endl;
+ std::cout << "s1 != s2 ? " << ((s1 != s2) ? "true" : "false") << std::endl;
+
+ std::cout << "s1 < s2 ? " << ((s1 < s2) ? "true" : "false") << std::endl;
+ std::cout << "s1 <= s2 ? " << ((s1 <= s2) ? "true" : "false") << std::endl;
+ std::cout << "s1 > s2 ? " << ((s1 > s2) ? "true" : "false") << std::endl;
+ std::cout << "s1 >= s2 ? " << ((s1 >= s2) ? "true" : "false") << std::endl;
+
+ std::cout << "s1 < 10 ? " << ((s1 < 10) ? "true" : "false") << std::endl;
+ std::cout << "s1 <= 10 ? " << ((s1 <= 10) ? "true" : "false") << std::endl;
+ std::cout << "s1 > 10 ? " << ((s1 > 10) ? "true" : "false") << std::endl;
+ std::cout << "s1 >= 10 ? " << ((s1 >= 10) ? "true" : "false") << std::endl;
+ std::cout << "s2 < 10 ? " << ((s2 < 10) ? "true" : "false") << std::endl;
+ std::cout << "s2 <= 10 ? " << ((s2 <= 10) ? "true" : "false") << std::endl;
+ std::cout << "s2 > 10 ? " << ((s2 > 10) ? "true" : "false") << std::endl;
+ std::cout << "s2 >= 10 ? " << ((s2 >= 10) ? "true" : "false") << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "s1: ";
+ s1.show();
+ std::cout << std::endl << "s2: ";
+ s2.show();
+ std::cout << std::endl << "s1 += s2" << std::endl;
+ s1 += s2;
+ std::cout << "s1: ";
+ s1.show();
+ std::cout << std::endl;
+
+ std::cout << std::endl;
+
+ std::cout << "s1: ";
+ s1.show();
+ std::cout << std::endl << "s1 *= 2.0" << std::endl;
+ s1 *= 2.0;
+ std::cout << "s1: ";
+ s1.show();
+ std::cout << std::endl;
+
+ std::cout << std::endl;
+
+ return 0;
+}
+
diff --git a/sources/shiboken6/tests/libsample/mapuser.cpp b/sources/shiboken6/tests/libsample/mapuser.cpp
new file mode 100644
index 000000000..40059bbcd
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/mapuser.cpp
@@ -0,0 +1,48 @@
+// 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 "mapuser.h"
+
+#include <iostream>
+
+std::map<std::string, std::pair<Complex, int> > MapUser::callCreateMap()
+{
+ return createMap();
+}
+
+std::map<std::string, std::pair<Complex, int> > MapUser::createMap()
+{
+ std::map<std::string, std::pair<Complex, int> > retval;
+
+ std::pair<Complex, int> value{Complex(1.2, 3.4), 2};
+ retval.insert({"zero", value});
+
+ value = {Complex(5.6, 7.8), 3};
+ retval.insert({"one", value});
+
+ value = {Complex(9.1, 2.3), 5};
+ retval.insert({"two", value});
+
+ return retval;
+}
+
+void MapUser::showMap(std::map<std::string, int> mapping)
+{
+ std::cout << __FUNCTION__ << std::endl;
+ for (const auto &p : mapping)
+ std::cout << p.first << " => " << p.second << std::endl;
+}
+
+void MapUser::pointerToMap(std::map<std::string, std::string> *)
+{
+}
+
+void MapUser::referenceToMap(std::map<std::string, std::string> &)
+{
+}
+
+std::map<int, std::list<std::list<double> > > MapUser::foo() const
+{
+ std::map<int, std::list<std::list<double> > > result;
+ return result;
+}
diff --git a/sources/shiboken6/tests/libsample/mapuser.h b/sources/shiboken6/tests/libsample/mapuser.h
new file mode 100644
index 000000000..1677a4bfb
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/mapuser.h
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef MAPUSER_H
+#define MAPUSER_H
+
+#include "libsamplemacros.h"
+
+#include "complex.h"
+#include "bytearray.h"
+
+#include <map>
+#include <list>
+#include <utility>
+#include <string>
+
+class LIBSAMPLE_API MapUser
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(MapUser)
+
+ MapUser() noexcept = default;
+ virtual ~MapUser() = default;
+
+ virtual std::map<std::string, std::pair<Complex, int> > createMap();
+ std::map<std::string, std::pair<Complex, int> > callCreateMap();
+
+ void showMap(std::map<std::string, int> mapping);
+
+ inline void setMap(std::map<std::string, std::list<int> > map) { m_map = map; }
+ inline std::map<std::string, std::list<int> > getMap() { return m_map; }
+
+ // Compile test
+ static void pointerToMap(std::map<std::string, std::string> *arg);
+ static void referenceToMap(std::map<std::string, std::string> &arg);
+
+ inline const std::map<int, ByteArray> &passMapIntValueType(const std::map<int, ByteArray>& arg) { return arg; }
+
+ std::map<int, std::list<std::list<double> > > foo() const;
+
+private:
+ std::map<std::string, std::list<int> > m_map;
+};
+
+#endif // MAPUSER_H
diff --git a/sources/shiboken6/tests/libsample/modelindex.h b/sources/shiboken6/tests/libsample/modelindex.h
new file mode 100644
index 000000000..48e1b7de3
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/modelindex.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef MODELINDEX_H
+#define MODELINDEX_H
+
+class ModelIndex
+{
+public:
+ ModelIndex() = default;
+
+ inline void setValue(int value) { m_value = value; }
+ inline int value() const { return m_value; }
+ static int getValue(const ModelIndex &index) { return index.value(); }
+
+private:
+ int m_value = 0;
+};
+
+class ReferentModelIndex
+{
+public:
+ ReferentModelIndex() = default;
+
+ explicit ReferentModelIndex(const ModelIndex &index) : m_index(index) {}
+
+ inline void setValue(int value) { m_index.setValue(value); }
+ inline int value() const { return m_index.value(); }
+ operator const ModelIndex&() const { return m_index; }
+
+private:
+ ModelIndex m_index;
+};
+
+class PersistentModelIndex
+{
+public:
+ PersistentModelIndex() = default;
+
+ explicit PersistentModelIndex(const ModelIndex &index) : m_index(index) {}
+
+ inline void setValue(int value) { m_index.setValue(value); }
+ inline int value() const { return m_index.value(); }
+ operator ModelIndex() const { return m_index; }
+
+private:
+ ModelIndex m_index;
+};
+
+#endif // MODELINDEX_H
diff --git a/sources/shiboken6/tests/libsample/modifications.cpp b/sources/shiboken6/tests/libsample/modifications.cpp
new file mode 100644
index 000000000..6d627c4c1
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/modifications.cpp
@@ -0,0 +1,207 @@
+// 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 "modifications.h"
+#include "objecttype.h"
+
+#include <iostream>
+
+Modifications::Modifications()
+ : m_object(new ObjectType())
+{
+ m_object->setObjectName("MyObject");
+}
+
+Modifications::~Modifications()
+{
+ delete m_object;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, Point, Point)
+{
+ return Overloaded_ibPP;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, int, int)
+{
+ return Overloaded_ibii;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, int, Point)
+{
+ return Overloaded_ibiP;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, int, bool)
+{
+ return Overloaded_ibib;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, int, double)
+{
+ return Overloaded_ibid;
+}
+
+void Modifications::argRemoval0(int, bool, int, int)
+{
+}
+
+void Modifications::argRemoval0(int, bool, int, bool)
+{
+}
+
+void Modifications::argRemoval1(int, bool, Point, Point, int)
+{
+}
+
+void Modifications::argRemoval1(int, bool, int, bool)
+{
+}
+
+void Modifications::argRemoval2(int, bool, Point, Point, int)
+{
+}
+
+void Modifications::argRemoval3(int, Point, bool, Point, int)
+{
+}
+
+void Modifications::argRemoval4(int, Point, bool, Point, int)
+{
+}
+
+void Modifications::argRemoval5(int, bool, Point, Point, int)
+{
+}
+
+void Modifications::argRemoval5(int, bool, int, bool)
+{
+}
+
+std::pair<double, double> Modifications::pointToPair(Point pt, bool *ok)
+{
+ std::pair<double, double> retval(pt.x(), pt.y());
+ *ok = true;
+ return retval;
+}
+
+double Modifications::multiplyPointCoordsPlusValue(bool *ok, Point pt, double value)
+{
+ double retval = (pt.x() * pt.y()) + value;
+ *ok = true;
+ return retval;
+}
+
+int Modifications::doublePlus(int value, int plus)
+{
+ return (2 * value) + plus;
+}
+
+int Modifications::power(int base, int exponent)
+{
+ if (exponent == 0)
+ return 1;
+ int retval = base;
+ for (int i = 1; i < exponent; i++)
+ retval = retval * base;
+ return retval;
+}
+
+int Modifications::timesTen(int number)
+{
+ return number * 10;
+}
+
+int Modifications::increment(int number)
+{
+ return ++number;
+}
+
+void Modifications::exclusiveCppStuff()
+{
+ std::cout << __FUNCTION__ << std::endl;
+}
+
+int Modifications::cppMultiply(int a, int b)
+{
+ return a * b;
+}
+
+const char *Modifications::className()
+{
+ return "Modifications";
+}
+
+Point Modifications::sumPointArray(int arraySize, const Point pointArray[])
+{
+ Point point;
+ for (int i = 0; i < arraySize; ++i)
+ point = point + pointArray[i];
+ return point;
+}
+
+int Modifications::getSize(const void *data, int size)
+{
+ (void)data;
+ return size;
+}
+
+int Modifications::sumPointCoordinates(const Point *point)
+{
+ return point->x() + point->y();
+}
+
+double Modifications::differenceOfPointCoordinates(const Point *pt, bool *ok)
+{
+ if (!pt) {
+ *ok = false;
+ return 0.0;
+ }
+ *ok = true;
+ double result = pt->x() - pt->y();
+ if (result < 0)
+ result = result * -1.0;
+ return result;
+}
+
+bool Modifications::nonConversionRuleForArgumentWithDefaultValue(ObjectType **object)
+{
+ if (object)
+ *object = m_object;
+ return true;
+}
+
+void Modifications::setEnumValue(TestEnum e)
+{
+ m_enumValue = e;
+}
+
+Modifications::TestEnum Modifications::enumValue() const
+{
+ return m_enumValue;
+}
+
+Modifications::TestEnum Modifications::defaultEnumValue() const
+{
+ return TestEnumValue2;
+}
+
+bool Modifications::wasGetAttroCalled() const
+{
+ return m_getAttroCalled;
+}
+
+void Modifications::notifyGetAttroCalled()
+{
+ m_getAttroCalled = true;
+}
+
+bool Modifications::wasSetAttroCalled() const
+{
+ return m_setAttroCalled;
+}
+
+void Modifications::notifySetAttroCalled()
+{
+ m_setAttroCalled = true;
+}
diff --git a/sources/shiboken6/tests/libsample/modifications.h b/sources/shiboken6/tests/libsample/modifications.h
new file mode 100644
index 000000000..5bd1bac47
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/modifications.h
@@ -0,0 +1,145 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef MODIFICATIONS_H
+#define MODIFICATIONS_H
+
+#include "libsamplemacros.h"
+#include "point.h"
+#include "oddbool.h"
+
+#include <utility>
+
+class ObjectType;
+
+class LIBSAMPLE_API Modifications
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Modifications)
+
+ Modifications();
+ virtual ~Modifications();
+
+ enum OverloadedModFunc {
+ OverloadedNone,
+ Overloaded_ibid,
+ Overloaded_ibib,
+ Overloaded_ibiP,
+ Overloaded_ibii,
+ Overloaded_ibPP
+ };
+
+ enum TestEnum {
+ TestEnumValue1,
+ TestEnumValue2
+ };
+
+ // those overloaded methods should be heavily modified
+ // to push the overload decisor to its limits
+ OverloadedModFunc overloaded(int a0, bool b0, int c0, double d0);
+ OverloadedModFunc overloaded(int a1, bool b1, int c1, bool d1);
+ OverloadedModFunc overloaded(int a2, bool b2, int c2, Point d2);
+ OverloadedModFunc overloaded(int a3, bool b3, int c3 = 123, int d3 = 456);
+ OverloadedModFunc overloaded(int a4, bool b4, Point c4, Point d4);
+
+ void argRemoval0(int a0, bool a1, int a2 = 123, int a3 = 456);
+ void argRemoval0(int a0, bool a1, int a2, bool a3);
+
+ void argRemoval1(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4),
+ int a4 = 333);
+ void argRemoval1(int a0, bool a1, int a2, bool a3);
+
+ void argRemoval2(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4),
+ int a4 = 333);
+
+ void argRemoval3(int a0, Point a1 = Point(1, 2), bool a2 = true, Point a3 = Point(3, 4),
+ int a4 = 333);
+
+ void argRemoval4(int a0, Point a1, bool a2, Point a3 = Point(3, 4), int a4 = 333);
+
+ void argRemoval5(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4),
+ int a4 = 333);
+ void argRemoval5(int a0, bool a1, int a2, bool a3);
+
+ // 'ok' must be removed and the return value will be changed
+ // to a tuple (PyObject*) containing the expected result plus
+ // the 'ok' value as a Python boolean
+ std::pair<double, double> pointToPair(Point pt, bool *ok);
+
+ // same as 'pointToPair' except that this time 'ok' is the first argument
+ double multiplyPointCoordsPlusValue(bool *ok, Point pt, double value);
+
+ // completely remove 'plus' from the Python side
+ int doublePlus(int value, int plus = 0);
+
+ // the default value for both arguments must be changed in Python
+ int power(int base = 1, int exponent = 0);
+
+ // in Python set argument default value to 10
+ int timesTen(int number);
+
+ // in Python remove the argument default value
+ int increment(int number = 0);
+
+ // don't export this method to Python
+ void exclusiveCppStuff();
+
+ // change the name of this regular method
+ int cppMultiply(int a, int b);
+
+ // change the name of this virtual method
+ virtual const char *className();
+
+ Point sumPointArray(int arraySize, const Point pointArray[]);
+
+ // Replace 'const void*' by 'ByteArray&'.
+ int getSize(const void *data, int size);
+
+ // Mark the argument with a <no-null-pointer/> tag;
+ // the test implementation must expect point never to be null.
+ int sumPointCoordinates(const Point *point);
+
+ // Modify the return value of a virtual method.
+ virtual double differenceOfPointCoordinates(const Point *pt, bool *ok);
+ double callDifferenceOfPointCoordinates(const Point *pt, bool *ok)
+ { return differenceOfPointCoordinates(pt, ok); }
+
+ // Sets an ObjectType in the argument and returns true.
+ bool nonConversionRuleForArgumentWithDefaultValue(ObjectType **object = nullptr);
+ ObjectType *getObject() const { return m_object; }
+
+ // Inject code with a %CONVERTTOPYTHON that receives an user's primitive type.
+ static inline OddBool passOddBool(OddBool ob) { return ob; }
+
+ void setEnumValue(TestEnum e = TestEnumValue1);
+ TestEnum enumValue() const;
+ TestEnum defaultEnumValue() const;
+
+ bool wasGetAttroCalled() const;
+ void notifyGetAttroCalled();
+
+ bool wasSetAttroCalled() const;
+ void notifySetAttroCalled();
+
+private:
+ ObjectType *m_object;
+ TestEnum m_enumValue = TestEnumValue1;
+ bool m_getAttroCalled = false;
+ bool m_setAttroCalled = false;
+};
+
+class LIBSAMPLE_API AbstractModifications : public Modifications
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(AbstractModifications)
+
+ AbstractModifications() noexcept = default;
+ ~AbstractModifications() override = default;
+
+ inline bool invert(bool value) { return !value; }
+
+ // completely remove this method in Python
+ virtual void pointlessPureVirtualMethod() = 0;
+};
+
+#endif // MODIFICATIONS_H
diff --git a/sources/shiboken6/tests/libsample/modified_constructor.cpp b/sources/shiboken6/tests/libsample/modified_constructor.cpp
new file mode 100644
index 000000000..c39c97738
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/modified_constructor.cpp
@@ -0,0 +1,16 @@
+// 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 "modified_constructor.h"
+
+ModifiedConstructor::ModifiedConstructor(int first_arg)
+{
+ m_stored_value = first_arg;
+}
+
+int ModifiedConstructor::retrieveValue() const
+{
+ return m_stored_value;
+}
+
+
diff --git a/sources/shiboken6/tests/libsample/modified_constructor.h b/sources/shiboken6/tests/libsample/modified_constructor.h
new file mode 100644
index 000000000..a27899f3f
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/modified_constructor.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef MODIFIEDCONSTRUCTOR_H
+#define MODIFIEDCONSTRUCTOR_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API ModifiedConstructor
+{
+public:
+
+ explicit ModifiedConstructor(int first_arg);
+ int retrieveValue() const;
+
+private:
+ int m_stored_value;
+};
+
+#endif // MODIFIEDCONSTRUCTOR_H
+
diff --git a/sources/shiboken6/tests/libsample/multiple_derived.cpp b/sources/shiboken6/tests/libsample/multiple_derived.cpp
new file mode 100644
index 000000000..be535c62f
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/multiple_derived.cpp
@@ -0,0 +1,24 @@
+// 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 "multiple_derived.h"
+
+MDerived1::MDerived1() noexcept = default;
+
+MDerived2::MDerived2() noexcept = default;
+
+MDerived3::MDerived3() noexcept = default;
+
+MDerived4::MDerived4() noexcept = default;
+
+MDerived5::MDerived5() noexcept = default;
+
+MDerived1 *MDerived1::transformFromBase1(Base1 *self)
+{
+ return dynamic_cast<MDerived1*>(self);
+}
+
+MDerived1 *MDerived1::transformFromBase2(Base2 *self)
+{
+ return dynamic_cast<MDerived1*>(self);
+}
diff --git a/sources/shiboken6/tests/libsample/multiple_derived.h b/sources/shiboken6/tests/libsample/multiple_derived.h
new file mode 100644
index 000000000..8c2143ed6
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/multiple_derived.h
@@ -0,0 +1,202 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef MDERIVED_H
+#define MDERIVED_H
+
+#include "libsamplemacros.h"
+
+#include <string>
+
+class Base1
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base1)
+
+ Base1() noexcept = default;
+ virtual ~Base1() = default;
+
+ virtual int base1Method() { return m_value; }
+
+ virtual void publicMethod() {};
+
+private:
+ int m_value = 1;
+};
+
+class Base2
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base2)
+
+ Base2() noexcept = default;
+ virtual ~Base2() = default;
+ virtual int base2Method() { return m_value; }
+
+private:
+ int m_value = 2;
+};
+
+class LIBSAMPLE_API MDerived1 : public Base1, public Base2
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived1)
+
+ MDerived1() noexcept;
+ ~MDerived1() override = default;
+
+ int mderived1Method() { return m_value; }
+ int base1Method () override { return Base1::base1Method() * 10; }
+ int base2Method() override { return Base2::base2Method() * 10; }
+
+ inline Base1 *castToBase1() { return (Base1*) this; }
+ inline Base2 *castToBase2() { return (Base2*) this; }
+
+ static MDerived1 *transformFromBase1(Base1 *self);
+ static MDerived1 *transformFromBase2(Base2 *self);
+
+private:
+ void publicMethod() override {}
+ int m_value = 100;
+};
+
+class SonOfMDerived1 : public MDerived1
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(SonOfMDerived1)
+
+ SonOfMDerived1() noexcept = default;
+ ~SonOfMDerived1() = default;
+
+ inline MDerived1 *castToMDerived1() { return this; }
+
+ int sonOfMDerived1Method() { return m_value; }
+
+private:
+ int m_value = 0;
+};
+
+class Base3
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base3)
+
+ explicit Base3(int val = 3) noexcept : m_value(val) {}
+ virtual ~Base3() = default;
+ int base3Method() { return m_value; }
+
+private:
+ int m_value;
+};
+
+class Base4
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base4)
+
+ Base4() noexcept = default;
+ virtual ~Base4() = default;
+ int base4Method() { return m_value; }
+
+private:
+ int m_value = 4;
+};
+
+class Base5
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base5)
+
+ Base5() noexcept = default;
+ virtual ~Base5() = default;
+ virtual int base5Method() { return m_value; }
+
+private:
+ int m_value = 5;
+};
+
+class Base6
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base6)
+
+ Base6() noexcept = default;
+ virtual ~Base6() = default;
+ virtual int base6Method() { return m_value; }
+
+private:
+ int m_value = 6;
+};
+
+class LIBSAMPLE_API MDerived2 : public Base3, public Base4, public Base5, public Base6
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived2)
+
+ MDerived2() noexcept;
+ virtual ~MDerived2() = default;
+
+ inline int base4Method() { return Base3::base3Method() * 10; }
+ inline int mderived2Method() { return m_value; }
+
+ inline Base3 *castToBase3() { return this; }
+ inline Base4 *castToBase4() { return this; }
+ inline Base5 *castToBase5() { return this; }
+ inline Base6 *castToBase6() { return this; }
+
+private:
+ int m_value = 200;
+};
+
+class LIBSAMPLE_API MDerived3 : public MDerived1, public MDerived2
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived3)
+
+ MDerived3() noexcept;
+ virtual ~MDerived3() = default;
+
+ inline virtual int mderived3Method() { return m_value; }
+
+ inline MDerived1 *castToMDerived1() { return this; }
+ inline MDerived2 *castToMDerived2() { return this; }
+
+ inline Base3 *castToBase3() { return (Base3*) this; }
+
+private:
+ int m_value = 3000;
+};
+
+class LIBSAMPLE_API MDerived4 : public Base3, public Base4
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived4)
+
+ MDerived4() noexcept;
+ ~MDerived4() = default;
+
+ inline int mderived4Method() { return 0; }
+ inline int justDummyMethod() { return m_value; }
+
+ inline Base3 *castToBase3() { return this; }
+ inline Base4 *castToBase4() { return this; }
+
+private:
+ int m_value;
+};
+
+class LIBSAMPLE_API MDerived5 : public Base3, public Base4
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived5)
+
+ MDerived5() noexcept;
+ virtual ~MDerived5() = default;
+
+ virtual int mderived5Method() { return 0; }
+
+ inline Base3 *castToBase3() { return this; }
+ inline Base4 *castToBase4() { return this; }
+};
+
+#endif // MDERIVED_H
diff --git a/sources/shiboken6/tests/libsample/noimplicitconversion.h b/sources/shiboken6/tests/libsample/noimplicitconversion.h
new file mode 100644
index 000000000..a0b91380b
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/noimplicitconversion.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef NOIMPLICITCONVERSION_H
+#define NOIMPLICITCONVERSION_H
+
+#include "libsamplemacros.h"
+
+// This class must not have implicit conversions AND
+// no conversion operators should be defined in its own module.
+class NoImplicitConversion
+{
+public:
+ explicit NoImplicitConversion(int objId) : m_objId(objId) {}
+ inline int objId() const { return m_objId; }
+ inline static int receivesNoImplicitConversionByValue(NoImplicitConversion arg)
+ { return arg.m_objId; }
+ inline static int receivesNoImplicitConversionByPointer(NoImplicitConversion *arg)
+ { return arg->m_objId; }
+ inline static int receivesNoImplicitConversionByReference(NoImplicitConversion &arg)
+ { return arg.m_objId; }
+private:
+ int m_objId;
+};
+
+#endif // NOIMPLICITCONVERSION_H
+
diff --git a/sources/shiboken6/tests/libsample/nondefaultctor.h b/sources/shiboken6/tests/libsample/nondefaultctor.h
new file mode 100644
index 000000000..fa97b8859
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/nondefaultctor.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef NONDEFAULTCTOR_H
+#define NONDEFAULTCTOR_H
+
+#include "libsamplemacros.h"
+
+class NonDefaultCtor
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(NonDefaultCtor)
+
+ explicit NonDefaultCtor(int value) noexcept : m_value(value)
+ {
+ }
+
+ virtual ~NonDefaultCtor() = default;
+
+ inline int value() const
+ {
+ return m_value;
+ }
+
+ inline NonDefaultCtor returnMyself()
+ {
+ return *this;
+ }
+
+ inline NonDefaultCtor returnMyself(int)
+ {
+ return *this;
+ }
+
+ inline NonDefaultCtor returnMyself(int, NonDefaultCtor)
+ {
+ return *this;
+ }
+
+ virtual NonDefaultCtor returnMyselfVirtual()
+ {
+ return *this;
+ }
+
+ inline NonDefaultCtor callReturnMyselfVirtual()
+ {
+ return returnMyselfVirtual();
+ }
+
+private:
+ int m_value;
+};
+
+#endif // NONDEFAULTCTOR_H
diff --git a/sources/shiboken6/tests/libsample/nontypetemplate.h b/sources/shiboken6/tests/libsample/nontypetemplate.h
new file mode 100644
index 000000000..e41c21604
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/nontypetemplate.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef NONTYPETEMPLATE_H
+#define NONTYPETEMPLATE_H
+
+#include "libsamplemacros.h"
+
+#include <algorithm>
+#include <numeric>
+
+template <int Size> class IntArray
+{
+public:
+ explicit IntArray(const int *data) { std::copy(data, data + Size, m_array); }
+ explicit IntArray(int v) { std::fill(m_array, m_array + Size, v); }
+
+ int sum() const { return std::accumulate(m_array, m_array + Size, int(0)); }
+
+private:
+ int m_array[Size];
+};
+
+using IntArray2 = IntArray<2>;
+using IntArray3 = IntArray<3>;
+
+#endif // NONTYPETEMPLATE_H
diff --git a/sources/shiboken6/tests/libsample/null.h b/sources/shiboken6/tests/libsample/null.h
new file mode 100644
index 000000000..945a89fa2
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/null.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef NULL_H
+#define NULL_H
+
+class Null
+{
+public:
+ Null(bool value) : m_isNull(value) {}
+ Null() = default;
+
+ void setIsNull(bool flag) { m_isNull = flag; }
+
+private:
+ bool m_isNull = false;
+};
+
+#endif // NULL_H
diff --git a/sources/shiboken6/tests/libsample/objectmodel.cpp b/sources/shiboken6/tests/libsample/objectmodel.cpp
new file mode 100644
index 000000000..56ed86577
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objectmodel.cpp
@@ -0,0 +1,24 @@
+// 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 "objectmodel.h"
+
+void ObjectModel::setData(ObjectType *data)
+{
+ m_data = data;
+}
+
+ObjectType *ObjectModel::data() const
+{
+ return m_data;
+}
+
+ObjectModel::MethodCalled ObjectModel::receivesObjectTypeFamily(const ObjectModel &)
+{
+ return ObjectModel::ObjectModelCalled;
+}
+
+ObjectModel::MethodCalled ObjectModel::receivesObjectTypeFamily(const ObjectType &)
+{
+ return ObjectModel::ObjectTypeCalled;
+}
diff --git a/sources/shiboken6/tests/libsample/objectmodel.h b/sources/shiboken6/tests/libsample/objectmodel.h
new file mode 100644
index 000000000..6d2f97aee
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objectmodel.h
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OBJECTMODEL_H
+#define OBJECTMODEL_H
+
+#include "objecttype.h"
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API ObjectModel : public ObjectType
+{
+public:
+ explicit ObjectModel(ObjectType *parent = nullptr)
+ : ObjectType(parent) {}
+
+ void setData(ObjectType *data);
+ virtual ObjectType *data() const;
+
+ // The MethodCalled enum and related static methods were created to
+ // test bug #630 [http://bugs.openbossa.org/show_bug.cgi?id=630]
+ enum MethodCalled { ObjectTypeCalled, ObjectModelCalled };
+ static MethodCalled receivesObjectTypeFamily(const ObjectType &object);
+ static MethodCalled receivesObjectTypeFamily(const ObjectModel &object);
+
+private:
+ // The model holds only one piece of data.
+ // (This is just a test after all.)
+ ObjectType *m_data = nullptr;
+};
+
+#endif // OBJECTMODEL_H
diff --git a/sources/shiboken6/tests/libsample/objecttype.cpp b/sources/shiboken6/tests/libsample/objecttype.cpp
new file mode 100644
index 000000000..fa3e7357c
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttype.cpp
@@ -0,0 +1,264 @@
+// 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 "objecttype.h"
+#include "objecttypelayout.h"
+
+#include <algorithm>
+#include <iostream>
+#include <string>
+#include <assert.h>
+
+ObjectType::ObjectType(ObjectType *parent)
+{
+ setParent(parent);
+}
+
+ObjectType::ObjectType(ObjectType &&) noexcept = default;
+ObjectType &ObjectType::operator=(ObjectType &&) noexcept = default;
+
+ObjectType::~ObjectType()
+{
+ for (auto *o : m_children)
+ delete o;
+}
+
+ObjectType *ObjectType::createWithChild()
+{
+ ObjectType *parent = create();
+ ObjectType *child = create();
+ child->setObjectName("child");
+ child->setParent(parent);
+ return parent;
+}
+
+void ObjectType::removeChild(ObjectType *child)
+{
+ if (!child)
+ return;
+
+ auto child_iter = std::find(m_children.begin(), m_children.end(), child);
+ if (child_iter != m_children.end()) {
+ m_children.erase(child_iter);
+ child->m_parent = nullptr;
+ }
+}
+
+ObjectType *ObjectType::takeChild(ObjectType *child)
+{
+ if (!child)
+ return nullptr;
+
+ auto child_iter = std::find(m_children.begin(), m_children.end(), child);
+ if (child_iter != m_children.end()) {
+ m_children.erase(child_iter);
+ child->m_parent = nullptr;
+ return child;
+ }
+ return nullptr;
+}
+
+ObjectType *ObjectType::takeChild(const Str &name)
+{
+ return takeChild(findChild(name));
+
+}
+
+ObjectTypeList::iterator ObjectType::findChildByName(const Str &name)
+{
+ return std::find_if(m_children.begin(), m_children.end(),
+ [&name](const ObjectType *o) {
+ return o->objectName() == name;
+ });
+}
+
+ObjectType *ObjectType::findChild(const Str &name)
+{
+ auto it = findChildByName(name);
+ return it != m_children.end() ? *it : nullptr;
+}
+
+void ObjectType::killChild(const Str &name)
+{
+ auto it = findChildByName(name);
+ if (it != m_children.end()) {
+ ObjectType *child = *it;
+ removeChild(child);
+ delete child;
+ }
+}
+
+void ObjectType::setParent(ObjectType *parent)
+{
+ if (m_parent == parent)
+ return;
+
+ if (m_parent)
+ m_parent->removeChild(this);
+
+ m_parent = parent;
+ if (m_parent)
+ m_parent->m_children.push_back(this);
+}
+
+void ObjectType::setObjectName(const Str &name)
+{
+ m_objectName = name;
+}
+
+Str ObjectType::objectName() const
+{
+ return m_objectName;
+}
+
+bool ObjectType::causeEvent(Event::EventType eventType)
+{
+ Event e(eventType);
+ return event(&e);
+}
+
+bool ObjectType::event(Event *)
+{
+ return true;
+}
+
+int ObjectType::processEvent(ObjectTypeList objects, Event *event)
+{
+ return std::count_if(objects.begin(), objects.end(),
+ [event] (ObjectType *o) {
+ return o->event(event);
+ });
+}
+
+void ObjectType::callInvalidateEvent(Event *event)
+{
+ invalidateEvent(event);
+}
+
+void ObjectType::invalidateEvent(Event *)
+{
+}
+
+void ObjectType::setLayout(ObjectTypeLayout *l)
+{
+ if (!l) {
+ std::cerr << "[WARNING] ObjectType::setLayout: Cannot set layout to 0.\n";
+ return;
+ }
+
+ if (layout()) {
+ if (layout() != l) {
+ std::cerr << "[WARNING] ObjectType::setLayout: Attempting to set ObjectTypeLayout '"
+ << l->objectName().cstring()
+ << "' on ObjectType '" << objectName().cstring()
+ << "', which already has a layout.\n";
+ }
+ return;
+ }
+
+ ObjectType *oldParent = l->parent();
+ if (oldParent && oldParent != this) {
+ if (oldParent->isLayoutType()) {
+ std::cerr << "[WARNING] ObjectType::setLayout: Attempting to set ObjectTypeLayout '"
+ << l->objectName().cstring()
+ << "' on ObjectType '" << objectName().cstring()
+ << "', when the ObjectTypeLayout already has a parent layout.\n";
+ return;
+ }
+ // Steal the layout from an ObjectType parent.
+ oldParent->takeLayout();
+ }
+
+ m_layout = l;
+ if (oldParent != this) {
+ l->setParent(this);
+ l->reparentChildren(this);
+ }
+}
+
+ObjectTypeLayout *ObjectType::takeLayout()
+{
+ ObjectTypeLayout *l = layout();
+ if (!l)
+ return nullptr;
+ m_layout = nullptr;
+ l->setParent(nullptr);
+ return l;
+}
+
+unsigned int objectTypeHash(const ObjectType *objectType)
+{
+ return reinterpret_cast<std::size_t>(objectType);
+}
+
+unsigned char ObjectType::callWithEnum(const Str &, Event::EventType, unsigned char value)
+{
+ return value * value;
+}
+
+unsigned char ObjectType::callWithEnum(const Str &, unsigned char value)
+{
+ return value;
+}
+
+void ObjectType::setObjectSplittedName(const char *, const Str &prefix, const Str &suffix)
+{
+ std::string result(prefix.cstring());
+ result += suffix.cstring();
+ m_objectName = result.c_str();
+}
+
+void ObjectType::setObjectNameWithSize(const char *, int size, const Str &name)
+{
+ std::string result(name.cstring(), size);
+ m_objectName = result.c_str();
+}
+
+void ObjectType::setObjectNameWithSize(const Str &name, int size)
+{
+ setObjectNameWithSize("", size, name);
+}
+
+void ObjectType::setObject(ObjectType *)
+{
+ m_call_id = 0;
+}
+
+void ObjectType::setObject(const Null&)
+{
+ m_call_id = 1;
+}
+
+int ObjectType::callId() const
+{
+ return m_call_id;
+}
+
+void ObjectType::callVirtualCreateChild()
+{
+ auto *fake_parent = new ObjectType();
+ ObjectType *fake_child = createChild(fake_parent);
+ assert(fake_child->isPython());
+ (void)fake_child;
+ delete fake_parent;
+}
+
+ObjectType *ObjectType::createChild(ObjectType *parent)
+{
+ return new ObjectType(parent);
+}
+
+std::size_t ObjectType::createObjectType()
+{
+ void *addr = new ObjectType();
+ return (std::size_t) addr;
+}
+
+OtherBase::~OtherBase() = default;
+
+ObjectTypeDerived::~ObjectTypeDerived() = default;
+
+bool ObjectTypeDerived::event(Event *)
+{
+ return true;
+}
diff --git a/sources/shiboken6/tests/libsample/objecttype.h b/sources/shiboken6/tests/libsample/objecttype.h
new file mode 100644
index 000000000..498556459
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttype.h
@@ -0,0 +1,166 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OBJECTTYPE_H
+#define OBJECTTYPE_H
+
+#include "str.h"
+#include "null.h"
+
+#include "libsamplemacros.h"
+
+#include <list>
+
+struct Event
+{
+ enum EventType {
+ NO_EVENT,
+ BASIC_EVENT,
+ SOME_EVENT,
+ ANY_EVENT
+ };
+
+ enum class EventTypeClass {
+ Value1,
+ Value2
+ };
+
+ explicit Event(EventType eventType) : m_eventType(eventType) {}
+ EventType eventType() const { return m_eventType; }
+
+ void setEventType(EventType et) { m_eventType = et; }
+ void setEventTypeByConstRef(const EventType &et) { m_eventType = et; }
+ void setEventTypeByConstPtr(const EventType *etPtr) { m_eventType = *etPtr; }
+
+private:
+ EventType m_eventType;
+};
+
+class ObjectTypeLayout;
+class ObjectType;
+using ObjectTypeList = std::list<ObjectType*>;
+
+class LIBSAMPLE_API ObjectType
+{
+public:
+ // ### Fixme: Use uintptr_t in C++ 11
+ using Identifier = size_t;
+
+ explicit ObjectType(ObjectType *parent = nullptr);
+ virtual ~ObjectType();
+ ObjectType(const ObjectType &) = delete;
+ ObjectType &operator=(const ObjectType &) = delete;
+ ObjectType(ObjectType &&) noexcept;
+ ObjectType &operator=(ObjectType &&) noexcept;
+
+ // factory method
+ inline static ObjectType *create() { return new ObjectType(); }
+ static ObjectType *createWithChild();
+
+ void setParent(ObjectType *parent);
+ inline ObjectType *parent() const { return m_parent; }
+ inline const ObjectTypeList &children() const { return m_children; }
+ void killChild(const Str &name);
+ void removeChild(ObjectType *child);
+ ObjectType *takeChild(ObjectType *child);
+ virtual ObjectType *takeChild(const Str &name);
+ ObjectType *findChild(const Str &name);
+
+ Str objectName() const;
+ void setObjectName(const Str &name);
+
+ inline Identifier identifier() const { return reinterpret_cast<Identifier>(this); }
+
+ bool causeEvent(Event::EventType eventType);
+
+ // Returns true if the event is processed.
+ virtual bool event(Event *event);
+ static int processEvent(ObjectTypeList objects, Event *event);
+
+ void callInvalidateEvent(Event *event);
+ virtual void invalidateEvent(Event *event);
+
+ // This nonsense method emulate QWidget.setLayout method
+ // All layout objects will became children of this object.
+ void setLayout(ObjectTypeLayout *layout);
+ inline ObjectTypeLayout *layout() const { return m_layout; }
+
+ // This method should be reimplemented by ObjectTypeLayout.
+ virtual bool isLayoutType() { return false; }
+
+ unsigned char callWithEnum(const Str &prefix, Event::EventType type,
+ unsigned char value=80);
+ unsigned char callWithEnum(const Str &prefix, unsigned char value=0);
+
+ //Functions used in test with named arguments
+ void setObjectSplittedName(const char *, const Str &prefix = Str("<unk"),
+ const Str &suffix = Str("nown>"));
+ void setObjectNameWithSize(const char *, int size=9,
+ const Str &name = Str("<unknown>"));
+ void setObjectNameWithSize(const Str &name = Str("<unknown>"), int size = 9);
+
+ //Function used to confuse the generator when two values accept Null as arg
+ void setObject(ObjectType *);
+ void setObject(const Null &);
+ int callId() const;
+
+ //Function used to create a parent from C++
+ virtual bool isPython() { return false; }
+ void callVirtualCreateChild();
+ virtual ObjectType *createChild(ObjectType *parent);
+ static std::size_t createObjectType();
+
+ //return a parent from C++
+ ObjectType *getCppParent() {
+ if (!m_parent) {
+ ObjectType *parent = new ObjectType();
+ setParent(parent);
+ }
+ return m_parent;
+ }
+
+ void destroyCppParent() {
+ delete m_parent;
+ }
+
+ //Deprecated test
+ bool deprecatedFunction() { return true; }
+
+ // nextInFocusChain simply returns the parent to test object cycles; the parent
+ // may be returned by the QWidget's implementation but isn't always returned
+ ObjectType *nextInFocusChain() { return m_parent; }
+
+private:
+ ObjectTypeLayout *takeLayout();
+ ObjectTypeList::iterator findChildByName(const Str &name);
+
+ Str m_objectName;
+ ObjectType *m_parent = nullptr;
+ ObjectTypeList m_children;
+
+ ObjectTypeLayout *m_layout = nullptr;
+ //used on overload null test
+ int m_call_id = -1;
+};
+
+LIBSAMPLE_API unsigned int objectTypeHash(const ObjectType *objectType);
+
+class LIBSAMPLE_API OtherBase {
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(OtherBase)
+
+ OtherBase() noexcept = default;
+ virtual ~OtherBase();
+};
+
+class LIBSAMPLE_API ObjectTypeDerived: public ObjectType, public OtherBase {
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(ObjectTypeDerived)
+
+ ObjectTypeDerived() noexcept = default;
+
+ bool event(Event *event) override;
+ ~ObjectTypeDerived() override;
+};
+
+#endif // OBJECTTYPE_H
diff --git a/sources/shiboken6/tests/libsample/objecttypebyvalue.h b/sources/shiboken6/tests/libsample/objecttypebyvalue.h
new file mode 100644
index 000000000..7b12ff945
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttypebyvalue.h
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OBJECTTYPEBYVALUE_H
+#define OBJECTTYPEBYVALUE_H
+
+#include "protected.h"
+
+#include <list>
+
+class ObjectTypeByValue
+{
+public:
+ ObjectTypeByValue returnSomeKindOfMe() { return {}; }
+ void acceptKindOfMeAsValue(ObjectTypeByValue kindOfMe);
+
+ void acceptListOfObjectTypeByValue(std::list<ObjectTypeByValue> listOfMe);
+
+ // prop used to check for segfaults
+ ProtectedProperty prop;
+};
+
+inline void ObjectTypeByValue::acceptKindOfMeAsValue(ObjectTypeByValue)
+{
+}
+
+inline void ObjectTypeByValue::acceptListOfObjectTypeByValue(std::list<ObjectTypeByValue>)
+{
+}
+
+#endif // OBJECTTYPEBYVALUE_H
diff --git a/sources/shiboken6/tests/libsample/objecttypeholder.cpp b/sources/shiboken6/tests/libsample/objecttypeholder.cpp
new file mode 100644
index 000000000..c0950d09c
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttypeholder.cpp
@@ -0,0 +1,31 @@
+// 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 "objecttypeholder.h"
+
+ObjectTypeHolder::ObjectTypeHolder(const char *objectName)
+{
+ auto *object = new ObjectType();
+ object->setObjectName(objectName);
+ m_objectType = object;
+}
+
+ObjectTypeHolder::ObjectTypeHolder(const ObjectType *object) noexcept :
+ m_objectType(object)
+{
+}
+
+ObjectTypeHolder::~ObjectTypeHolder()
+{
+ delete m_objectType;
+}
+
+Str ObjectTypeHolder::passObjectTypeAsReference(const ObjectType &objectType)
+{
+ return objectType.objectName();
+}
+
+Str ObjectTypeHolder::callPassObjectTypeAsReference()
+{
+ return passObjectTypeAsReference(*m_objectType);
+}
diff --git a/sources/shiboken6/tests/libsample/objecttypeholder.h b/sources/shiboken6/tests/libsample/objecttypeholder.h
new file mode 100644
index 000000000..190664608
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttypeholder.h
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OBJECTTYPEHOLDER_H
+#define OBJECTTYPEHOLDER_H
+
+#include "libsamplemacros.h"
+#include "objecttype.h"
+#include "str.h"
+
+class LIBSAMPLE_API ObjectTypeHolder
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(ObjectTypeHolder)
+
+ explicit ObjectTypeHolder(const char *objectName);
+ explicit ObjectTypeHolder(const ObjectType *object) noexcept;
+ virtual ~ObjectTypeHolder();
+
+ const ObjectType *getObjectType() const { return m_objectType; }
+
+ virtual Str passObjectTypeAsReference(const ObjectType &objectType);
+ Str callPassObjectTypeAsReference();
+
+private:
+ const ObjectType *m_objectType;
+};
+
+#endif // OBJECTTYPEHOLDER_H
diff --git a/sources/shiboken6/tests/libsample/objecttypelayout.cpp b/sources/shiboken6/tests/libsample/objecttypelayout.cpp
new file mode 100644
index 000000000..3fa02917c
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttypelayout.cpp
@@ -0,0 +1,40 @@
+// 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 "objecttypelayout.h"
+
+#include <iostream>
+
+void ObjectTypeLayout::addObject(ObjectType *obj)
+{
+ if (obj->isLayoutType()) {
+ auto *l = reinterpret_cast<ObjectTypeLayout*>(obj);
+ if (l->parent()) {
+ std::cerr << "[WARNING] ObjectTypeLayout::addObject: layout '"
+ << l->objectName().cstring() << "' already has a parent.\n";
+ return;
+ }
+
+ l->setParent(this);
+
+ if (parent() && !parent()->isLayoutType())
+ l->reparentChildren(parent());
+ }
+
+ m_objects.push_back(obj);
+}
+
+std::list<ObjectType*> ObjectTypeLayout::objects() const
+{
+ return m_objects;
+}
+
+void ObjectTypeLayout::reparentChildren(ObjectType *parent)
+{
+ for (auto *o : m_objects) {
+ if (o->isLayoutType())
+ reinterpret_cast<ObjectTypeLayout *>(o)->reparentChildren(parent);
+ else
+ o->setParent(parent);
+ }
+}
diff --git a/sources/shiboken6/tests/libsample/objecttypelayout.h b/sources/shiboken6/tests/libsample/objecttypelayout.h
new file mode 100644
index 000000000..0aa9fad6e
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttypelayout.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OBJECTTYPELAYOUT_H
+#define OBJECTTYPELAYOUT_H
+
+#include "libsamplemacros.h"
+#include "objecttype.h"
+
+#include <list>
+
+class ObjectType;
+
+class LIBSAMPLE_API ObjectTypeLayout : public ObjectType
+{
+public:
+ void addObject(ObjectType *obj);
+ std::list<ObjectType*> objects() const;
+
+ bool isLayoutType() override { return true; }
+ inline static ObjectTypeLayout *create() { return new ObjectTypeLayout(); }
+
+ ObjectType *takeChild(const Str &name) override { return ObjectType::takeChild(name); }
+
+private:
+ std::list<ObjectType*> m_objects;
+
+ void reparentChildren(ObjectType *parent);
+ friend LIBSAMPLE_API void ObjectType::setLayout(ObjectTypeLayout *l);
+};
+
+#endif // OBJECTTYPELAYOUT_H
diff --git a/sources/shiboken6/tests/libsample/objecttypeoperators.cpp b/sources/shiboken6/tests/libsample/objecttypeoperators.cpp
new file mode 100644
index 000000000..c78387a3e
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttypeoperators.cpp
@@ -0,0 +1,38 @@
+// 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 "objecttypeoperators.h"
+
+ObjectTypeOperators::ObjectTypeOperators(const std::string key) : m_key(key)
+{
+}
+
+bool ObjectTypeOperators::operator==(const ObjectTypeOperators &other) const
+{
+ return m_key == other.m_key;
+}
+
+const ObjectTypeOperators &ObjectTypeOperators::operator<(const ObjectTypeOperators &other) const
+{
+ return m_key < other.m_key ? *this : other;
+}
+
+bool operator==(const ObjectTypeOperators *obj, const std::string &str)
+{
+ return obj->key() == str;
+}
+
+bool operator==(const std::string &str, const ObjectTypeOperators *obj)
+{
+ return str == obj->key();
+}
+
+std::string operator+(const ObjectTypeOperators *obj, const std::string &str)
+{
+ return obj->key() + str;
+}
+
+std::string operator+(const std::string &str, const ObjectTypeOperators *obj)
+{
+ return str + obj->key();
+}
diff --git a/sources/shiboken6/tests/libsample/objecttypeoperators.h b/sources/shiboken6/tests/libsample/objecttypeoperators.h
new file mode 100644
index 000000000..6144952ca
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objecttypeoperators.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OBJECTTYPEOPERATORS_H
+#define OBJECTTYPEOPERATORS_H
+
+#include "libsamplemacros.h"
+
+#include <string>
+
+class LIBSAMPLE_API ObjectTypeOperators
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(ObjectTypeOperators)
+
+ explicit ObjectTypeOperators(const std::string key);
+ virtual ~ObjectTypeOperators() = default;
+
+ bool operator==(const ObjectTypeOperators &other) const;
+ const ObjectTypeOperators &operator<(const ObjectTypeOperators &other) const;
+
+ // chaos!
+ virtual void operator>(const ObjectTypeOperators &) { m_key.append("operator>"); }
+
+ std::string key() const { return m_key; }
+
+private:
+ std::string m_key;
+};
+
+LIBSAMPLE_API bool operator==(const ObjectTypeOperators *obj, const std::string &str);
+LIBSAMPLE_API bool operator==(const std::string &str, const ObjectTypeOperators *obj);
+LIBSAMPLE_API std::string operator+(const ObjectTypeOperators *obj, const std::string &str);
+LIBSAMPLE_API std::string operator+(const std::string &str, const ObjectTypeOperators *obj);
+
+#endif // OBJECTTYPEOPERATORS_H
diff --git a/sources/shiboken6/tests/libsample/objectview.cpp b/sources/shiboken6/tests/libsample/objectview.cpp
new file mode 100644
index 000000000..1b727f88c
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objectview.cpp
@@ -0,0 +1,24 @@
+// 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 "objectview.h"
+#include "objectmodel.h"
+#include "str.h"
+
+Str ObjectView::displayModelData()
+{
+ if (!m_model)
+ return {"(NULL)"};
+ return Str("Name: %VAR").arg(m_model->objectName());
+}
+
+void ObjectView::modifyModelData(Str &data)
+{
+ if (m_model)
+ m_model->setObjectName(data);
+}
+
+ObjectType *ObjectView::getRawModelData()
+{
+ return m_model->data();
+}
diff --git a/sources/shiboken6/tests/libsample/objectview.h b/sources/shiboken6/tests/libsample/objectview.h
new file mode 100644
index 000000000..2567deee5
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/objectview.h
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OBJECTVIEW_H
+#define OBJECTVIEW_H
+
+#include "objecttype.h"
+#include "libsamplemacros.h"
+
+class Str;
+class ObjectModel;
+
+class LIBSAMPLE_API ObjectView : public ObjectType
+{
+public:
+ explicit ObjectView(ObjectModel *model = nullptr, ObjectType *parent = nullptr)
+ : ObjectType(parent), m_model(model) {}
+
+ inline void setModel(ObjectModel *model) { m_model = model; }
+ inline ObjectModel *model() const { return m_model; }
+
+ Str displayModelData();
+ void modifyModelData(Str &data);
+
+ ObjectType *getRawModelData();
+
+private:
+ ObjectModel *m_model;
+};
+
+#endif // OBJECTVIEW_H
diff --git a/sources/shiboken6/tests/libsample/oddbool.cpp b/sources/shiboken6/tests/libsample/oddbool.cpp
new file mode 100644
index 000000000..bc1ee833f
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/oddbool.cpp
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "oddbool.h"
+
+ComparisonTester::ComparisonTester(int v) : m_value(v)
+{
+}
+
+ComparisonTester &ComparisonTester::operator=(int v)
+{
+ m_value = v;
+ return *this;
+}
+
+int ComparisonTester::compare(const ComparisonTester &rhs) const
+{
+ if (m_value < rhs.m_value)
+ return -1;
+ if (m_value > rhs.m_value)
+ return 1;
+ return 0;
+}
+
+SpaceshipComparisonTester::SpaceshipComparisonTester(int v) : m_value(v)
+{
+}
diff --git a/sources/shiboken6/tests/libsample/oddbool.h b/sources/shiboken6/tests/libsample/oddbool.h
new file mode 100644
index 000000000..dd2d32604
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/oddbool.h
@@ -0,0 +1,106 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef ODDBOOL_H
+#define ODDBOOL_H
+
+#include "libsamplemacros.h"
+
+#include <type_traits>
+
+#if __cplusplus >= 202002 || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002)
+# include <compare>
+#endif
+
+class OddBool
+{
+
+public:
+ inline explicit OddBool(bool b) noexcept : m_value(b) {}
+ bool value() const { return m_value; }
+
+ inline OddBool operator!() const { return OddBool(!m_value); }
+
+private:
+ bool m_value;
+};
+
+inline bool operator==(OddBool b1, bool b2) { return (!b1).value() == !b2; }
+inline bool operator==(bool b1, OddBool b2) { return (!b1) == (!b2).value(); }
+inline bool operator==(OddBool b1, OddBool b2) { return (!b1).value() == (!b2).value(); }
+inline bool operator!=(OddBool b1, bool b2) { return (!b1).value() != !b2; }
+inline bool operator!=(bool b1, OddBool b2) { return (!b1) != (!b2).value(); }
+inline bool operator!=(OddBool b1, OddBool b2) { return (!b1).value() != (!b2).value(); }
+
+class OddBoolUser
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(OddBoolUser)
+
+ OddBoolUser() noexcept : m_oddbool(OddBool(false)) {}
+ OddBoolUser(const OddBool &oddBool) : m_oddbool(oddBool) {}
+ virtual ~OddBoolUser() = default;
+
+ inline OddBool oddBool() { return m_oddbool; }
+ inline void setOddBool(OddBool oddBool) { m_oddbool = oddBool; }
+
+ virtual OddBool invertedOddBool()
+ {
+ return !m_oddbool;
+ }
+
+ inline OddBool callInvertedOddBool()
+ {
+ return invertedOddBool();
+ }
+
+ static inline OddBool getOddBool(const OddBoolUser &oddBoolUser)
+ {
+ return oddBoolUser.m_oddbool;
+ }
+
+private:
+ OddBool m_oddbool;
+};
+
+class LIBSAMPLE_API ComparisonTester
+{
+public:
+ explicit ComparisonTester(int v);
+ ComparisonTester &operator=(int v);
+
+ int compare(const ComparisonTester &rhs) const;
+
+private:
+ int m_value;
+};
+
+// Hide the comparison operators from the clang parser (see typesystem_sample.xml:184,
+// oddbool_test.py)
+
+inline std::enable_if<std::is_assignable<ComparisonTester, int>::value, bool>::type
+ operator==(const ComparisonTester &c1, const ComparisonTester &c2)
+{ return c1.compare(c2) == 0; }
+
+inline std::enable_if<std::is_assignable<ComparisonTester, int>::value, bool>::type
+ operator!=(const ComparisonTester &c1, const ComparisonTester &c2)
+{ return c1.compare(c2) != 0; }
+
+class LIBSAMPLE_API SpaceshipComparisonTester
+{
+public:
+ explicit SpaceshipComparisonTester(int v);
+
+#if __cplusplus >= 202002 || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002)
+ auto operator<=>(const SpaceshipComparisonTester &rhs) const = default;
+
+ enum Enabled { HasSpaceshipOperator = 1 };
+#else
+ enum Enabled { HasSpaceshipOperator = 0 };
+#endif // C++ 20
+
+private:
+ int m_value;
+};
+
+#endif // ODDBOOL_H
diff --git a/sources/shiboken6/tests/libsample/onlycopy.cpp b/sources/shiboken6/tests/libsample/onlycopy.cpp
new file mode 100644
index 000000000..981ea88a4
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/onlycopy.cpp
@@ -0,0 +1,36 @@
+// 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 "onlycopy.h"
+
+class OnlyCopyPrivate
+{
+public:
+ explicit OnlyCopyPrivate(int v = 0) : value(v) {}
+
+ int value;
+};
+
+OnlyCopy::OnlyCopy(int value) : d(std::make_shared<OnlyCopyPrivate>(value))
+{
+}
+
+OnlyCopy::~OnlyCopy() = default;
+
+int OnlyCopy::value() const
+{
+ return d->value;
+}
+
+OnlyCopy FriendOfOnlyCopy::createOnlyCopy(int value)
+{
+ return OnlyCopy(value);
+}
+
+std::list<OnlyCopy> FriendOfOnlyCopy::createListOfOnlyCopy(int quantity)
+{
+ std::list<OnlyCopy> list;
+ for (int i = 0; i < quantity; ++i)
+ list.push_back(createOnlyCopy(i));
+ return list;
+}
diff --git a/sources/shiboken6/tests/libsample/onlycopy.h b/sources/shiboken6/tests/libsample/onlycopy.h
new file mode 100644
index 000000000..7dc3e0069
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/onlycopy.h
@@ -0,0 +1,42 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef ONLYCOPYCLASS_H
+#define ONLYCOPYCLASS_H
+
+#include "libsamplemacros.h"
+
+#include <list>
+#include <memory>
+
+// These classes simulate a situation found in QWebEngineHistoryItem.
+
+class OnlyCopyPrivate;
+
+class LIBSAMPLE_API OnlyCopy
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(OnlyCopy)
+
+ ~OnlyCopy();
+
+ int value() const;
+ static int getValue(OnlyCopy onlyCopy) { return onlyCopy.value(); }
+ static int getValueFromReference(const OnlyCopy &onlyCopy) { return onlyCopy.value(); }
+
+private:
+ friend class FriendOfOnlyCopy;
+
+ explicit OnlyCopy(int value);
+
+ std::shared_ptr<OnlyCopyPrivate> d;
+};
+
+class LIBSAMPLE_API FriendOfOnlyCopy
+{
+public:
+ static OnlyCopy createOnlyCopy(int value);
+ static std::list<OnlyCopy> createListOfOnlyCopy(int quantity);
+};
+
+#endif // ONLYCOPYCLASS_H
diff --git a/sources/shiboken6/tests/libsample/overload.cpp b/sources/shiboken6/tests/libsample/overload.cpp
new file mode 100644
index 000000000..34da28e03
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/overload.cpp
@@ -0,0 +1,203 @@
+// 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 "overload.h"
+
+Overload::FunctionEnum Overload::overloaded()
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::overloaded(Size *)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::overloaded(Point *, ParamEnum)
+{
+ return Function2;
+}
+
+Overload::FunctionEnum Overload::overloaded(const Point &)
+{
+ return Function3;
+}
+
+void Overload::differentReturnTypes(ParamEnum)
+{
+
+}
+
+int Overload::differentReturnTypes(ParamEnum, int val)
+{
+ return val;
+}
+
+int Overload::intOverloads(const Point &, double)
+{
+ return 1;
+}
+
+int Overload::intOverloads(int, int)
+{
+ return 2;
+}
+
+int Overload::intOverloads(int, int, double)
+{
+ return 3;
+}
+
+Overload::FunctionEnum Overload::intDoubleOverloads(double, double) const
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::intDoubleOverloads(int, int) const
+{
+ return Function0;
+}
+
+void Overload::singleOverload(Point *)
+{
+}
+
+Overload::FunctionEnum Overload::wrapperIntIntOverloads(const Polygon &, int, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::wrapperIntIntOverloads(const Point &, int, int)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::strBufferOverloads(const Str &, const char *, bool)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::strBufferOverloads(unsigned char *, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::drawText(const PointF &, const Str &)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::drawText(const Point &, const Str &)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::drawText(const RectF &, const Str &, const Echo &)
+{
+ return Function4;
+}
+
+Overload::FunctionEnum Overload::drawText(const RectF &, int, const Str &)
+{
+ return Function3;
+}
+
+Overload::FunctionEnum Overload::drawText(const Rect &, int, const Str &)
+{
+ return Function2;
+}
+
+Overload::FunctionEnum Overload::drawText(int, int, const Str &)
+{
+ return Function5;
+}
+
+Overload::FunctionEnum Overload::drawText(int, int, int, int, int, const Str &)
+{
+ return Function6;
+}
+
+Overload::FunctionEnum Overload::drawText2(const PointF &, const Str &)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::drawText2(const Point &, const Str &)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::drawText2(int, int, const Str &)
+{
+ return Function5;
+}
+
+Overload::FunctionEnum Overload::drawText2(const RectF &, const Str &, const Echo &)
+{
+ return Function4;
+}
+
+Overload::FunctionEnum Overload::drawText2(const RectF &, int, const Str &)
+{
+ return Function3;
+}
+
+Overload::FunctionEnum Overload::drawText2(const Rect &, int, const Str &)
+{
+ return Function2;
+}
+
+Overload::FunctionEnum Overload::drawText2(int, int, int, int, int, const Str &)
+{
+ return Function6;
+}
+
+Overload::FunctionEnum Overload::drawText3(const Str &, const Str &, const Str &)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::drawText3(int, int, int, int, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::drawText4(int, int, int)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::drawText4(int, int, int, int, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::acceptSequence()
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(const Str &, ParamEnum)
+{
+ return Function2;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(int, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(void *)
+{
+ return Function5;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(const char *const[])
+{
+ return Function4;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(const Size &)
+{
+ return Function3;
+}
diff --git a/sources/shiboken6/tests/libsample/overload.h b/sources/shiboken6/tests/libsample/overload.h
new file mode 100644
index 000000000..b640bf7c7
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/overload.h
@@ -0,0 +1,121 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OVERLOAD_H
+#define OVERLOAD_H
+
+#include "echo.h"
+#include "str.h"
+#include "size.h"
+#include "point.h"
+#include "pointf.h"
+#include "polygon.h"
+#include "rect.h"
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API Overload
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Overload)
+
+ enum FunctionEnum {
+ Function0,
+ Function1,
+ Function2,
+ Function3,
+ Function4,
+ Function5,
+ Function6
+ };
+
+ enum ParamEnum {
+ Param0,
+ Param1
+ };
+
+ Overload() noexcept = default;
+ virtual ~Overload() = default;
+
+ FunctionEnum overloaded();
+ FunctionEnum overloaded(Size *size);
+ FunctionEnum overloaded(Point *point, ParamEnum param);
+ FunctionEnum overloaded(const Point &point);
+
+ void differentReturnTypes(ParamEnum param = Param0);
+ int differentReturnTypes(ParamEnum param, int val);
+
+ int intOverloads(const Point &p, double d);
+ int intOverloads(int i, int i2);
+ int intOverloads(int i, int removedArg, double d);
+
+ FunctionEnum intDoubleOverloads(int a0, int a1) const;
+ FunctionEnum intDoubleOverloads(double a0, double a1) const;
+
+ void singleOverload(Point *x);
+ Point *singleOverload() { return new Point(); }
+
+ // Similar to QImage::trueMatrix(QMatrix,int,int) and QImage::trueMatrix(QTransform,int,int)
+ FunctionEnum wrapperIntIntOverloads(const Point &arg0, int arg1, int arg2);
+ FunctionEnum wrapperIntIntOverloads(const Polygon &arg0, int arg1, int arg2);
+
+ // Similar to QImage constructor
+ FunctionEnum strBufferOverloads(const Str &arg0, const char *arg1 = nullptr,
+ bool arg2 = true);
+ FunctionEnum strBufferOverloads(unsigned char *arg0, int arg1);
+ FunctionEnum strBufferOverloads() { return Function2; }
+
+ // Similar to QPainter::drawText(...)
+ FunctionEnum drawText(const Point &a0, const Str &a1);
+ FunctionEnum drawText(const PointF &a0, const Str &a1);
+ FunctionEnum drawText(const Rect &a0, int a1, const Str &a2);
+ FunctionEnum drawText(const RectF &a0, int a1, const Str &a2);
+ FunctionEnum drawText(const RectF &a0, const Str &a1, const Echo &a2 = Echo());
+ FunctionEnum drawText(int a0, int a1, const Str &a2);
+ FunctionEnum drawText(int a0, int a1, int a2, int a3, int a4, const Str &a5);
+
+ // A variant of the one similar to QPainter::drawText(...)
+ FunctionEnum drawText2(const Point &a0, const Str &a1);
+ FunctionEnum drawText2(const PointF &a0, const Str &a1);
+ FunctionEnum drawText2(const Rect &a0, int a1, const Str &a2);
+ FunctionEnum drawText2(const RectF &a0, int a1, const Str &a2);
+ FunctionEnum drawText2(const RectF &a0, const Str &a1, const Echo &a2 = Echo());
+ FunctionEnum drawText2(int a0, int a1, const Str &a2);
+ FunctionEnum drawText2(int a0, int a1, int a2, int a3 = 0, int a4 = 0,
+ const Str &a5 = Str());
+
+ // A simpler variant of the one similar to QPainter::drawText(...)
+ FunctionEnum drawText3(const Str &a0, const Str &a1, const Str &a2);
+ FunctionEnum drawText3(int a0, int a1, int a2, int a3, int a4);
+
+ // Another simpler variant of the one similar to QPainter::drawText(...)
+ FunctionEnum drawText4(int a0, int a1, int a2);
+ FunctionEnum drawText4(int a0, int a1, int a2, int a3, int a4);
+
+ FunctionEnum acceptSequence();
+ FunctionEnum acceptSequence(int a0, int a1);
+ FunctionEnum acceptSequence(const Str &a0, ParamEnum a1 = Param0);
+ FunctionEnum acceptSequence(const Size &a0);
+ // The type must be changed to PySequence.
+ FunctionEnum acceptSequence(const char *const a0[]);
+ FunctionEnum acceptSequence(void *a0);
+};
+
+class LIBSAMPLE_API Overload2 : public Overload
+{
+public:
+ // test bug#616, public and private method differ only by const
+ void doNothingInPublic() const {}
+ void doNothingInPublic(int) {}
+ virtual void doNothingInPublic3() const {}
+ void doNothingInPublic3(int) const {}
+protected:
+ void doNothingInPublic2() const {}
+ void doNothingInPublic2(int) {}
+private:
+ void doNothingInPublic() {}
+ void doNothingInPublic2() {}
+ void doNothingInPublic3() {}
+};
+
+#endif // OVERLOAD_H
diff --git a/sources/shiboken6/tests/libsample/overloadsort.cpp b/sources/shiboken6/tests/libsample/overloadsort.cpp
new file mode 100644
index 000000000..a9b4b0972
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/overloadsort.cpp
@@ -0,0 +1,49 @@
+// 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 "overloadsort.h"
+
+const char *SortedOverload::overload(int)
+{
+ return "int";
+}
+
+const char *SortedOverload::overload(double)
+{
+ return "double";
+}
+
+const char *SortedOverload::overload(ImplicitBase)
+{
+ return "ImplicitBase";
+}
+
+const char *SortedOverload::overload(ImplicitTarget)
+{
+ return "ImplicitTarget";
+}
+
+const char *SortedOverload::overload(const std::list<ImplicitBase> &)
+{
+ return "list(ImplicitBase)";
+}
+
+int SortedOverload::implicit_overload(const ImplicitBase &)
+{
+ return 1;
+}
+
+const char *SortedOverload::overloadDeep(int, ImplicitBase &)
+{
+ return "ImplicitBase";
+}
+
+int CustomOverloadSequence::overload(short v) const
+{
+ return v + int(sizeof(v));
+}
+
+int CustomOverloadSequence::overload(int v) const
+{
+ return v + 4;
+}
diff --git a/sources/shiboken6/tests/libsample/overloadsort.h b/sources/shiboken6/tests/libsample/overloadsort.h
new file mode 100644
index 000000000..ee269cc21
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/overloadsort.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OVERLOADSORT_H
+#define OVERLOADSORT_H
+
+#include "libsamplemacros.h"
+
+#include <list>
+
+class ImplicitTarget
+{
+public:
+ ImplicitTarget() = default;
+};
+
+class ImplicitBase
+{
+public:
+ ImplicitBase() = default;
+ ImplicitBase(const ImplicitTarget &b);
+};
+
+inline ImplicitBase::ImplicitBase(const ImplicitTarget &)
+{
+}
+
+class LIBSAMPLE_API SortedOverload
+{
+public:
+
+ const char *overload(int x);
+ const char *overload(double x);
+ const char *overload(ImplicitBase x);
+ const char *overload(ImplicitTarget x);
+ const char *overload(const std::list<ImplicitBase> &x);
+
+ int implicit_overload(const ImplicitBase &x);
+
+ const char *overloadDeep(int x, ImplicitBase &y);
+
+ inline const char *pyObjOverload(int, int) { return "int,int"; }
+ inline const char *pyObjOverload(unsigned char *, int)
+ { return "PyObject,int"; }
+};
+
+class LIBSAMPLE_API CustomOverloadSequence
+{
+public:
+ int overload(short v) const;
+ int overload(int v) const;
+};
+
+#endif // OVERLOADSORT_H
diff --git a/sources/shiboken6/tests/libsample/pairuser.cpp b/sources/shiboken6/tests/libsample/pairuser.cpp
new file mode 100644
index 000000000..5b7eb4d8c
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/pairuser.cpp
@@ -0,0 +1,24 @@
+// 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 "pairuser.h"
+
+std::pair<int, int> PairUser::callCreatePair()
+{
+ return createPair();
+}
+
+std::pair<int, int> PairUser::createPair()
+{
+ return {10, 20};
+}
+
+std::pair<Complex, Complex> PairUser::createComplexPair(Complex cpx0, Complex cpx1)
+{
+ return {cpx0, cpx1};
+}
+
+double PairUser::sumPair(std::pair<int, double> pair)
+{
+ return ((double) pair.first) + pair.second;
+}
diff --git a/sources/shiboken6/tests/libsample/pairuser.h b/sources/shiboken6/tests/libsample/pairuser.h
new file mode 100644
index 000000000..ee51d818e
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/pairuser.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PAIRUSER_H
+#define PAIRUSER_H
+
+#include "libsamplemacros.h"
+#include "complex.h"
+
+#include <utility>
+
+class LIBSAMPLE_API PairUser
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(PairUser)
+
+ PairUser() noexcept = default;
+ virtual ~PairUser() = default;
+
+ virtual std::pair<int, int> createPair();
+ std::pair<int, int> callCreatePair();
+ static std::pair<Complex, Complex> createComplexPair(Complex cpx0, Complex cpx1);
+ double sumPair(std::pair<int, double> pair);
+
+ inline void setPair(std::pair<int, int> pair) { m_pair = pair; }
+ inline std::pair<int, int> getPair() { return m_pair; }
+
+private:
+ std::pair<int, int> m_pair;
+};
+
+#endif // PAIRUSER_H
diff --git a/sources/shiboken6/tests/libsample/pen.cpp b/sources/shiboken6/tests/libsample/pen.cpp
new file mode 100644
index 000000000..76473a264
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/pen.cpp
@@ -0,0 +1,83 @@
+// 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 "pen.h"
+
+Color::Color(SampleNamespace::InValue) : m_null(false)
+{
+}
+
+Color::Color(unsigned int) : m_null(false)
+{
+}
+
+bool Color::isNull() const
+{
+ return m_null;
+}
+
+Brush::Brush(const Color &c) : m_color(c)
+{
+}
+
+Brush::operator bool() const
+{
+ return !m_color.isNull();
+}
+
+Brush::Style Brush::style() const
+{
+ return m_style;
+}
+
+void Brush::setStyle(Style newStyle)
+{
+ m_style = newStyle;
+}
+
+const Color &Brush::color() const
+{
+ return m_color;
+}
+
+void Brush::setColor(const Color &newColor)
+{
+ m_color = newColor;
+}
+
+Pen::Pen() = default;
+
+Pen::Pen(SampleNamespace::Option) : m_ctor(EnumCtor)
+{
+}
+
+Pen::Pen(const Color &) : m_ctor(ColorCtor)
+{
+}
+
+Pen::Pen(const Pen &) : m_ctor(CopyCtor)
+{
+}
+
+Pen::Pen(Pen &&) noexcept = default;
+Pen &Pen::operator=(const Pen &pen) = default;
+Pen &Pen::operator=(Pen &&) noexcept = default;
+
+int Pen::ctorType()
+{
+ return m_ctor;
+}
+
+void Pen::drawLine(int, int, int, int, RenderHints)
+{
+}
+
+Pen::RenderHints Pen::getRenderHints() const
+{
+ return m_renderHints;
+}
+
+void Pen::setRenderHints(RenderHints h)
+{
+ m_renderHints = h;
+}
diff --git a/sources/shiboken6/tests/libsample/pen.h b/sources/shiboken6/tests/libsample/pen.h
new file mode 100644
index 000000000..6f528f0f9
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/pen.h
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PEN_H
+#define PEN_H
+
+#include "libsamplemacros.h"
+#include "samplenamespace.h"
+
+class LIBSAMPLE_API Color
+{
+public:
+ Color() = default;
+ Color(SampleNamespace::InValue arg);
+ Color(unsigned int arg);
+
+ bool isNull() const;
+
+private:
+ bool m_null = true;
+};
+
+class LIBSAMPLE_API Brush
+{
+public:
+ enum Style { Solid, Cross };
+
+ explicit Brush(const Color &c = {});
+
+ operator bool() const;
+
+ Style style() const;
+ void setStyle(Style newStyle);
+
+ const Color &color() const;
+ void setColor(const Color &newColor);
+
+private:
+ Style m_style = Solid;
+ Color m_color;
+};
+
+class LIBSAMPLE_API Pen
+{
+public:
+ enum { EmptyCtor, EnumCtor, ColorCtor, CopyCtor };
+
+ enum RenderHints { None = 0, Antialiasing = 0x1, TextAntialiasing = 0x2 };
+
+ Pen();
+ Pen(SampleNamespace::Option option);
+ Pen(const Color &color);
+ Pen(const Pen &pen);
+ Pen(Pen &&) noexcept;
+ Pen &operator=(const Pen &pen);
+ Pen &operator=(Pen &&) noexcept;
+ ~Pen() = default;
+
+ // PYSIDE-1325, default initializer
+ void drawLine(int x1, int y1, int x2, int y2, RenderHints renderHints = {});
+
+ int ctorType();
+
+ RenderHints getRenderHints() const;
+ void setRenderHints(RenderHints h);
+
+private:
+ int m_ctor = EmptyCtor;
+ RenderHints m_renderHints = None;
+};
+
+#endif
diff --git a/sources/shiboken6/tests/libsample/photon.cpp b/sources/shiboken6/tests/libsample/photon.cpp
new file mode 100644
index 000000000..2a7f20e33
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/photon.cpp
@@ -0,0 +1,31 @@
+// 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 "photon.h"
+
+namespace Photon
+{
+
+const ClassType Base::staticType;
+
+int callCalculateForValueDuplicatorPointer(ValueDuplicator *value)
+{
+ return value->calculate();
+}
+
+int callCalculateForValueDuplicatorReference(ValueDuplicator &value)
+{
+ return value.calculate();
+}
+
+int countValueIdentities(const std::list<ValueIdentity> &values)
+{
+ return values.size();
+}
+
+int countValueDuplicators(const std::list<TemplateBase<DuplicatorType> > &values)
+{
+ return values.size();
+}
+
+} // namespace Photon
diff --git a/sources/shiboken6/tests/libsample/photon.h b/sources/shiboken6/tests/libsample/photon.h
new file mode 100644
index 000000000..2debe47d1
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/photon.h
@@ -0,0 +1,110 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PHOTON_H
+#define PHOTON_H
+
+#include "libsamplemacros.h"
+
+#include <list>
+
+// This namespace and classes simulate
+// situations found in Qt's phonon module.
+
+namespace Photon
+{
+
+enum ClassType {
+ BaseType = 0,
+ IdentityType = 1,
+ DuplicatorType = 2
+};
+
+class LIBSAMPLE_API Base
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Base)
+
+ explicit Base(int value) noexcept : m_value(value) {}
+ virtual ~Base() = default;
+
+ inline void setValue(int value) { m_value = value; }
+ inline int value() const { return m_value; }
+
+ template <class T> bool isType() { return type() == T::staticType; }
+ bool isType(ClassType t) { return type() == t; }
+
+ virtual ClassType type() const { return BaseType; };
+ static const ClassType staticType = BaseType;
+
+protected:
+ int m_value;
+};
+
+template<ClassType CLASS_TYPE>
+class LIBSAMPLE_API TemplateBase : public Base
+{
+public:
+ explicit TemplateBase(int value) : Base(value) {}
+ inline int multiplicator() const { return int(CLASS_TYPE); }
+ inline int calculate() const { return m_value * (int(CLASS_TYPE)); }
+ static inline ClassType classType() { return CLASS_TYPE; }
+
+ inline int sumValueUsingPointer(TemplateBase<CLASS_TYPE> *other) const
+ { return m_value + other->m_value; }
+ inline int sumValueUsingReference(TemplateBase<CLASS_TYPE> &other) const
+ { return m_value + other.m_value; }
+
+ inline std::list<TemplateBase<CLASS_TYPE> > getListOfThisTemplateBase()
+ {
+ std::list<TemplateBase<CLASS_TYPE> > objs;
+ objs.push_back(*this);
+ objs.push_back(*this);
+ return objs;
+ }
+
+ static inline TemplateBase<CLASS_TYPE> *passPointerThrough(TemplateBase<CLASS_TYPE> *obj)
+ { return obj; }
+
+ ClassType type() const override { return CLASS_TYPE; }
+ static const ClassType staticType = CLASS_TYPE;
+};
+
+#if defined _WIN32 || defined __CYGWIN__
+template class LIBSAMPLE_API TemplateBase<IdentityType>;
+template class LIBSAMPLE_API TemplateBase<DuplicatorType>;
+#endif
+
+using ValueIdentity = TemplateBase<IdentityType>;
+using ValueDuplicator = TemplateBase<DuplicatorType>;
+
+LIBSAMPLE_API int callCalculateForValueDuplicatorPointer(ValueDuplicator *value);
+LIBSAMPLE_API int callCalculateForValueDuplicatorReference(ValueDuplicator &value);
+LIBSAMPLE_API int countValueIdentities(const std::list<ValueIdentity> &values);
+LIBSAMPLE_API int countValueDuplicators(const std::list<TemplateBase<DuplicatorType> > &values);
+
+class Pointer
+{
+public:
+ Pointer() noexcept = default;
+ explicit Pointer(int *p) : px(p) {}
+
+ void reset() noexcept { Pointer().swap(*this); }
+
+ int *get() const noexcept { return px; }
+ int &operator*() const { return *px; }
+
+ void swap(Pointer &rhs) noexcept
+ {
+ int *tmp = px;
+ px = rhs.px;
+ rhs.px = tmp;
+ }
+
+private:
+ int *px = nullptr;
+};
+
+} // namespace Photon
+
+#endif // PHOTON_H
diff --git a/sources/shiboken6/tests/libsample/point.cpp b/sources/shiboken6/tests/libsample/point.cpp
new file mode 100644
index 000000000..0a28e877f
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/point.cpp
@@ -0,0 +1,111 @@
+// 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 "point.h"
+
+#include <iostream>
+
+Point::Point(int x, int y) noexcept : m_x(x), m_y(y)
+{
+}
+
+Point::Point(double x, double y) noexcept : m_x(x), m_y(y)
+{
+}
+
+void Point::midpoint(const Point &other, Point *midpoint) const
+{
+ if (!midpoint)
+ return;
+ midpoint->setX((m_x + other.m_x) / 2.0);
+ midpoint->setY((m_y + other.m_y) / 2.0);
+}
+
+Point *Point::copy() const
+{
+ Point *pt = new Point();
+ pt->m_x = m_x;
+ pt->m_y = m_y;
+ return pt;
+}
+
+void Point::show() const
+{
+ std::cout << "(x: " << m_x << ", y: " << m_y << ")";
+}
+
+bool Point::operator==(const Point &other) const
+{
+ return m_x == other.m_x && m_y == other.m_y;
+}
+
+Point Point::operator+(const Point &other)
+{
+ return {m_x + other.m_x, m_y + other.m_y};
+}
+
+Point Point::operator-(const Point &other)
+{
+ return {m_x - other.m_x, m_y - other.m_y};
+}
+
+Point &Point::operator+=(Point &other)
+{
+ m_x += other.m_x;
+ m_y += other.m_y;
+ return *this;
+}
+
+Point &Point::operator-=(Point &other)
+{
+ m_x -= other.m_x;
+ m_y -= other.m_y;
+ return *this;
+}
+
+Point operator*(const Point &pt, double mult)
+{
+ return Point(pt.m_x * mult, pt.m_y * mult);
+}
+
+Point operator*(const Point &pt, int mult)
+{
+ return {int(pt.m_x) * mult, int(pt.m_y) * mult};
+}
+
+Point operator*(double mult, const Point &pt)
+{
+ return {pt.m_x * mult, pt.m_y * mult};
+}
+
+Point operator*(int mult, const Point &pt)
+{
+ return {int(pt.m_x) * mult, int(pt.m_y) * mult};
+}
+
+Point operator-(const Point &pt)
+{
+ return {-pt.m_x, -pt.m_y};
+}
+
+bool operator!(const Point &pt)
+{
+ return pt.m_x == 0.0 && pt.m_y == 0.0;
+}
+
+Point Point::operator/(int operand)
+{
+ return {m_x/operand, m_y/operand};
+}
+
+Complex transmutePointIntoComplex(const Point &point)
+{
+ Complex cpx(point.x(), point.y());
+ return cpx;
+}
+
+Point transmuteComplexIntoPoint(const Complex &cpx)
+{
+ Point pt(cpx.real(), cpx.imag());
+ return pt;
+}
diff --git a/sources/shiboken6/tests/libsample/point.h b/sources/shiboken6/tests/libsample/point.h
new file mode 100644
index 000000000..7e5d128ab
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/point.h
@@ -0,0 +1,76 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef POINT_H
+#define POINT_H
+
+#include "libsamplemacros.h"
+#include "complex.h"
+
+#include <utility>
+
+class LIBSAMPLE_API Point
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Point)
+
+ Point(int x = 0, int y = 0) noexcept;
+ Point(double x, double y) noexcept;
+ ~Point() = default;
+
+ inline double x() const { return m_x; }
+ inline double y() const { return m_y; }
+
+ inline void setX(double x) { m_x = x; }
+ inline void setY(double y) { m_y = y; }
+ inline void setXAsUint(unsigned int x) { m_x = x; }
+ inline void setYAsUint(unsigned int y) { m_y = y; }
+
+ // This method could simply return the midpoint,
+ // but the interesting part of the test is to set the
+ // result in the pointer argument.
+ void midpoint(const Point &other, Point *midpoint) const;
+
+ Point *copy() const;
+
+ inline const Point &getConstReferenceToSelf() const { return *this; }
+ inline const Point *getSelf() const { return this; }
+
+ // The != operator is not implemented for the purpose of testing
+ // for the absense of the __ne__ method in the Python binding.
+ bool operator==(const Point &other) const;
+
+ Point operator+(const Point &other);
+ Point operator-(const Point &other);
+ Point operator/(int operand);
+
+ friend LIBSAMPLE_API Point operator*(const Point &pt, double mult);
+ friend LIBSAMPLE_API Point operator*(const Point &pt, int mult);
+ friend LIBSAMPLE_API Point operator*(double mult, const Point &pt);
+ friend LIBSAMPLE_API Point operator*(int mult, const Point &pt);
+ friend LIBSAMPLE_API Point operator-(const Point &pt);
+ friend LIBSAMPLE_API bool operator!(const Point &pt);
+
+ Point &operator+=(Point &other);
+ Point &operator-=(Point &other);
+
+ void show() const;
+
+private:
+ double m_x;
+ double m_y;
+};
+
+LIBSAMPLE_API Point operator*(const Point &pt, double mult);
+LIBSAMPLE_API Point operator*(const Point &pt, int mult);
+LIBSAMPLE_API Point operator*(double mult, const Point &pt);
+LIBSAMPLE_API Point operator*(int mult, const Point &pt);
+LIBSAMPLE_API Point operator-(const Point &pt);
+LIBSAMPLE_API bool operator!(const Point &pt);
+
+LIBSAMPLE_API Complex transmutePointIntoComplex(const Point &point);
+LIBSAMPLE_API Point transmuteComplexIntoPoint(const Complex &cpx);
+
+LIBSAMPLE_API Point operator*(const Point &pt, double multiplier);
+
+#endif // POINT_H
diff --git a/sources/shiboken6/tests/libsample/pointerholder.h b/sources/shiboken6/tests/libsample/pointerholder.h
new file mode 100644
index 000000000..26f1cf0a6
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/pointerholder.h
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef POINTERHOLDER_H
+#define POINTERHOLDER_H
+
+#include "libsamplemacros.h"
+
+class PointerHolder
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(PointerHolder)
+
+ explicit PointerHolder(void *ptr) : m_pointer(ptr) {}
+ ~PointerHolder() = default;
+
+ inline void *pointer() const { return m_pointer; }
+
+private:
+ void *m_pointer;
+};
+
+#endif // POINTERHOLDER_H
diff --git a/sources/shiboken6/tests/libsample/pointf.cpp b/sources/shiboken6/tests/libsample/pointf.cpp
new file mode 100644
index 000000000..736a5c6b5
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/pointf.cpp
@@ -0,0 +1,86 @@
+// 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 "pointf.h"
+
+#include <iostream>
+
+PointF::PointF(const Point &point) noexcept : m_x(point.x()), m_y(point.y())
+{
+}
+
+PointF::PointF(double x, double y) noexcept : m_x(x), m_y(y)
+{
+}
+
+void PointF::midpoint(const PointF &other, PointF *midpoint) const
+{
+ if (!midpoint)
+ return;
+ midpoint->setX((m_x + other.m_x) / 2.0);
+ midpoint->setY((m_y + other.m_y) / 2.0);
+}
+
+void PointF::show() const
+{
+ std::cout << "(x: " << m_x << ", y: " << m_y << ")";
+}
+
+bool PointF::operator==(const PointF &other) const
+{
+ return m_x == other.m_x && m_y == other.m_y;
+}
+
+PointF PointF::operator+(const PointF &other)
+{
+ return {m_x + other.m_x, m_y + other.m_y};
+}
+
+PointF PointF::operator-(const PointF &other)
+{
+ return {m_x - other.m_x, m_y - other.m_y};
+}
+
+PointF &PointF::operator+=(PointF &other)
+{
+ m_x += other.m_x;
+ m_y += other.m_y;
+ return *this;
+}
+
+PointF &PointF::operator-=(PointF &other)
+{
+ m_x -= other.m_x;
+ m_y -= other.m_y;
+ return *this;
+}
+
+PointF operator*(const PointF &pt, double mult)
+{
+ return {pt.m_x * mult, pt.m_y * mult};
+}
+
+PointF operator*(const PointF &pt, int mult)
+{
+ return PointF(int(pt.m_x) * mult, int(pt.m_y) * mult);
+}
+
+PointF operator*(double mult, const PointF &pt)
+{
+ return {pt.m_x * mult, pt.m_y * mult};
+}
+
+PointF operator*(int mult, const PointF &pt)
+{
+ return PointF(int(pt.m_x) * mult, int(pt.m_y) * mult);
+}
+
+PointF operator-(const PointF &pt)
+{
+ return {-pt.m_x, -pt.m_y};
+}
+
+bool operator!(const PointF &pt)
+{
+ return pt.m_x == 0.0 && pt.m_y == 0.0;
+}
diff --git a/sources/shiboken6/tests/libsample/pointf.h b/sources/shiboken6/tests/libsample/pointf.h
new file mode 100644
index 000000000..49e009467
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/pointf.h
@@ -0,0 +1,65 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef POINTF_H
+#define POINTF_H
+
+#include "libsamplemacros.h"
+#include "point.h"
+
+#include <utility>
+
+class LIBSAMPLE_API PointF
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(PointF)
+
+ PointF(const Point &point) noexcept;
+ PointF(double x = 0.0, double y = 0.0) noexcept;
+ ~PointF() noexcept = default;
+
+ inline double x() const { return m_x; }
+ inline double y() const { return m_y; }
+
+ inline void setX(double x) { m_x = x; }
+ inline void setY(double y) { m_y = y; }
+
+ // This method could simply return the midpoint,
+ // but the interesting part of the test is to set the
+ // result in the pointer argument.
+ void midpoint(const PointF &other, PointF *midpoint) const;
+
+ // The != operator is not implemented for the purpose of testing
+ // for the absence of the __ne__ method in the Python binding.
+ bool operator==(const PointF &other) const;
+
+ PointF operator+(const PointF &other);
+ PointF operator-(const PointF &other);
+
+ friend LIBSAMPLE_API PointF operator*(const PointF &pt, double mult);
+ friend LIBSAMPLE_API PointF operator*(const PointF &pt, int mult);
+ friend LIBSAMPLE_API PointF operator*(double mult, const PointF &pt);
+ friend LIBSAMPLE_API PointF operator*(int mult, const PointF &pt);
+ friend LIBSAMPLE_API PointF operator-(const PointF &pt);
+ friend LIBSAMPLE_API bool operator!(const PointF &pt);
+
+ PointF &operator+=(PointF &other);
+ PointF &operator-=(PointF &other);
+
+ void show() const;
+
+private:
+ double m_x;
+ double m_y;
+};
+
+LIBSAMPLE_API PointF operator*(const PointF &pt, double mult);
+LIBSAMPLE_API PointF operator*(const PointF &pt, int mult);
+LIBSAMPLE_API PointF operator*(double mult, const PointF &pt);
+LIBSAMPLE_API PointF operator*(int mult, const PointF &pt);
+LIBSAMPLE_API PointF operator-(const PointF &pt);
+LIBSAMPLE_API bool operator!(const PointF &pt);
+
+LIBSAMPLE_API PointF operator*(const PointF &pt, double multiplier);
+
+#endif // POINTF_H
diff --git a/sources/shiboken6/tests/libsample/polygon.cpp b/sources/shiboken6/tests/libsample/polygon.cpp
new file mode 100644
index 000000000..6af597192
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/polygon.cpp
@@ -0,0 +1,39 @@
+// 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 "polygon.h"
+
+Polygon::Polygon(double x, double y) : m_points({Point(x, y)})
+{
+}
+
+Polygon::Polygon(Point point) : m_points({point})
+{
+}
+
+Polygon::Polygon(PointList points) : m_points(points)
+{
+}
+
+void Polygon::addPoint(Point point)
+{
+ m_points.push_back(point);
+}
+
+Polygon Polygon::doublePolygonScale(Polygon polygon)
+{
+ Polygon result;
+ for (const auto &point : polygon.points())
+ result.addPoint(point * 2.0);
+ return result;
+}
+
+void Polygon::stealOwnershipFromPython(Point *point)
+{
+ delete point;
+}
+
+void Polygon::stealOwnershipFromPython(Polygon *polygon)
+{
+ delete polygon;
+}
diff --git a/sources/shiboken6/tests/libsample/polygon.h b/sources/shiboken6/tests/libsample/polygon.h
new file mode 100644
index 000000000..2424ddd51
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/polygon.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef POLYGON_H
+#define POLYGON_H
+
+#include "libsamplemacros.h"
+#include "point.h"
+
+#include <list>
+
+class LIBSAMPLE_API Polygon // should be moveable
+{
+public:
+ using PointList = std::list<Point>;
+
+ Polygon() noexcept = default;
+ Polygon(double x, double y);
+ Polygon(Point point);
+ Polygon(PointList points);
+
+ void addPoint(Point point);
+
+ inline const PointList &points() const { return m_points; }
+
+ // This method intentionally receives and returns copies of a Polygon object.
+ static Polygon doublePolygonScale(Polygon polygon);
+
+ // This method invalidates the argument to be used for Polygon(Point) implicit conversion.
+ static void stealOwnershipFromPython(Point *point);
+
+ // This method invalidates the argument to be used in a call to doublePolygonScale(Polygon).
+ static void stealOwnershipFromPython(Polygon *polygon);
+
+private:
+ PointList m_points;
+};
+
+#endif // POLYGON_H
diff --git a/sources/shiboken6/tests/libsample/privatector.h b/sources/shiboken6/tests/libsample/privatector.h
new file mode 100644
index 000000000..3b38414f8
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/privatector.h
@@ -0,0 +1,42 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PRIVATECTOR_H
+#define PRIVATECTOR_H
+
+#include "libsamplemacros.h"
+
+class PrivateCtor
+{
+public:
+ inline static PrivateCtor *instance()
+ {
+ static PrivateCtor self;
+ self.m_instantiations++;
+ return &self;
+ }
+
+ inline int instanceCalls()
+ {
+ return m_instantiations;
+ }
+
+private:
+ int m_instantiations = 0;
+
+ PrivateCtor() = default;
+};
+
+class DeletedDefaultCtor
+{
+public:
+ DeletedDefaultCtor() = delete;
+
+ DeletedDefaultCtor(const DeletedDefaultCtor &) = default;
+ DeletedDefaultCtor(DeletedDefaultCtor &&) = default;
+ DeletedDefaultCtor &operator=(const DeletedDefaultCtor &) = default;
+ DeletedDefaultCtor &operator=(DeletedDefaultCtor &&) = default;
+ ~DeletedDefaultCtor() = default;
+};
+
+#endif // PRIVATECTOR_H
diff --git a/sources/shiboken6/tests/libsample/privatedtor.h b/sources/shiboken6/tests/libsample/privatedtor.h
new file mode 100644
index 000000000..05f18ea53
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/privatedtor.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PRIVATEDTOR_H
+#define PRIVATEDTOR_H
+
+#include "libsamplemacros.h"
+
+class PrivateDtor
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(PrivateDtor)
+
+ inline static PrivateDtor *instance()
+ {
+ static PrivateDtor self;
+ self.m_instantiations++;
+ return &self;
+ }
+
+ inline int instanceCalls()
+ {
+ return m_instantiations;
+ }
+
+protected:
+ inline int protectedInstanceCalls() { return m_instantiations; }
+
+private:
+ int m_instantiations = 0;
+
+ PrivateDtor() noexcept = default;
+ ~PrivateDtor() = default;
+};
+
+#endif // PRIVATEDTOR_H
diff --git a/sources/shiboken6/tests/libsample/protected.cpp b/sources/shiboken6/tests/libsample/protected.cpp
new file mode 100644
index 000000000..7ab52d22b
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/protected.cpp
@@ -0,0 +1,16 @@
+// 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 "protected.h"
+
+int ProtectedVirtualDestructor::dtor_called = 0;
+
+const char *ProtectedNonPolymorphic::dataTypeName(void *) const
+{
+ return "pointer";
+}
+
+const char *ProtectedNonPolymorphic::dataTypeName(int) const
+{
+ return "integer";
+}
diff --git a/sources/shiboken6/tests/libsample/protected.h b/sources/shiboken6/tests/libsample/protected.h
new file mode 100644
index 000000000..059cced5d
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/protected.h
@@ -0,0 +1,139 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PROTECTED_H
+#define PROTECTED_H
+
+#include "libsamplemacros.h"
+#include "objecttype.h"
+#include "point.h"
+
+#include <string>
+#include <list>
+
+class LIBSAMPLE_API ProtectedNonPolymorphic
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ProtectedNonPolymorphic)
+
+ explicit ProtectedNonPolymorphic(const char *name) : m_name(name) {}
+ ~ProtectedNonPolymorphic() = default;
+
+ inline const char *publicName() { return m_name.c_str(); }
+
+ inline static ProtectedNonPolymorphic *create()
+ { return new ProtectedNonPolymorphic("created"); }
+
+protected:
+ inline const char *protectedName() { return m_name.c_str(); }
+ inline int protectedSum(int a0, int a1) { return a0 + a1; }
+ inline int modifiedProtectedSum(int a0, int a1) { return a0 + a1; }
+ inline static const char *protectedStatic() { return "protectedStatic"; }
+ const char *dataTypeName(void *data = nullptr) const;
+ const char *dataTypeName(int data) const;
+
+private:
+ std::string m_name;
+};
+
+class LIBSAMPLE_API ProtectedPolymorphic
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ProtectedPolymorphic)
+
+ explicit ProtectedPolymorphic(const char *name) : m_name(name) {}
+ virtual ~ProtectedPolymorphic() = default;
+
+ inline static ProtectedPolymorphic *create()
+ { return new ProtectedPolymorphic("created"); }
+ inline const char *publicName() { return m_name.c_str(); }
+ inline const char *callProtectedName() { return protectedName(); }
+
+protected:
+ virtual const char *protectedName() { return m_name.c_str(); }
+
+private:
+ std::string m_name;
+};
+
+class LIBSAMPLE_API ProtectedPolymorphicDaughter : public ProtectedPolymorphic
+{
+public:
+ explicit ProtectedPolymorphicDaughter(const char *name) :
+ ProtectedPolymorphic(name) {}
+ inline static ProtectedPolymorphicDaughter *create()
+ { return new ProtectedPolymorphicDaughter("created"); }
+};
+
+class LIBSAMPLE_API ProtectedPolymorphicGrandDaughter: public ProtectedPolymorphicDaughter
+{
+public:
+ explicit ProtectedPolymorphicGrandDaughter(const char *name) :
+ ProtectedPolymorphicDaughter(name) {}
+ inline static ProtectedPolymorphicGrandDaughter *create()
+ { return new ProtectedPolymorphicGrandDaughter("created"); }
+};
+
+class LIBSAMPLE_API ProtectedVirtualDestructor
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(ProtectedVirtualDestructor)
+
+ ProtectedVirtualDestructor() noexcept = default;
+ inline static ProtectedVirtualDestructor *create()
+ { return new ProtectedVirtualDestructor(); }
+ inline static int dtorCalled() { return dtor_called; }
+ inline static void resetDtorCounter() { dtor_called = 0; }
+protected:
+ virtual ~ProtectedVirtualDestructor() { dtor_called++; }
+private:
+ static int dtor_called;
+};
+
+class LIBSAMPLE_API ProtectedEnumClass
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(ProtectedEnumClass)
+
+ ProtectedEnumClass() noexcept = default;
+ virtual ~ProtectedEnumClass() = default;
+ enum PublicEnum {
+ PublicItem0,
+ PublicItem1
+ };
+protected:
+ enum ProtectedEnum {
+ ProtectedItem0,
+ ProtectedItem1
+ };
+ ProtectedEnum callProtectedEnumMethod(ProtectedEnum in)
+ { return protectedEnumMethod(in); }
+ inline PublicEnum callPublicEnumMethod(PublicEnum in)
+ { return publicEnumMethod(in); }
+
+ virtual ProtectedEnum protectedEnumMethod(ProtectedEnum in) { return in; }
+ virtual PublicEnum publicEnumMethod(PublicEnum in) { return in; }
+};
+
+class LIBSAMPLE_API ProtectedProperty
+{
+public:
+ ProtectedProperty() = default;
+
+protected:
+ // This is deliberately the first member to test wrapper registration
+ // for value type members sharing the same memory address.
+ Point protectedValueTypeProperty{0, 0};
+ int protectedProperty = 0;
+ std::list<int> protectedContainerProperty;
+ Event::EventType protectedEnumProperty = Event::NO_EVENT;
+ Point *protectedValueTypePointerProperty = nullptr;
+ ObjectType *protectedObjectTypeProperty = nullptr;
+};
+
+LIBSAMPLE_API inline ProtectedProperty *createProtectedProperty()
+{
+ return new ProtectedProperty;
+}
+
+#endif // PROTECTED_H
diff --git a/sources/shiboken6/tests/libsample/rect.h b/sources/shiboken6/tests/libsample/rect.h
new file mode 100644
index 000000000..53296d26c
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/rect.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef RECT_H
+#define RECT_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API Rect
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Rect)
+
+ Rect() noexcept = default;
+ explicit Rect(int left, int top, int right, int bottom) noexcept
+ : m_left(left), m_top(top), m_right(right), m_bottom(bottom) { }
+ ~Rect() = default;
+
+ inline int left() const { return m_left; }
+ inline int top() const { return m_top; }
+ inline int right() const { return m_right; }
+ inline int bottom() const { return m_bottom; }
+private:
+ int m_left = 0;
+ int m_top = 0;
+ int m_right = -1;
+ int m_bottom = -1;
+};
+
+class LIBSAMPLE_API RectF
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(RectF)
+
+ RectF() noexcept = default;
+ explicit RectF(int left, int top, int right, int bottom) noexcept
+ : m_left(left), m_top(top), m_right(right), m_bottom(bottom) { }
+ RectF(const Rect &other) noexcept :
+ m_left(other.left()), m_top(other.top()),
+ m_right(other.right()), m_bottom(other.bottom()) {}
+ ~RectF() = default;
+
+ inline double left() const { return m_left; }
+ inline double top() const { return m_top; }
+ inline double right() const { return m_right; }
+ inline double bottom() const { return m_bottom; }
+private:
+ double m_left = 0;
+ double m_top = 0;
+ double m_right = -1;
+ double m_bottom = -1;
+};
+
+#endif // RECT_H
diff --git a/sources/shiboken6/tests/libsample/reference.cpp b/sources/shiboken6/tests/libsample/reference.cpp
new file mode 100644
index 000000000..29dcfc054
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/reference.cpp
@@ -0,0 +1,53 @@
+// 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 "reference.h"
+
+#include <iostream>
+
+void Reference::show() const
+{
+ std::cout << "Reference.objId: " << m_objId << ", address: " << this;
+}
+
+Reference &Reference::returnMySecondArg(int, Reference &ref)
+{
+ return ref;
+}
+
+int Reference::usesReferenceVirtual(Reference &r, int inc)
+{
+ return r.m_objId + inc;
+}
+
+int Reference::usesConstReferenceVirtual(const Reference &r, int inc)
+{
+ return r.m_objId + inc;
+}
+
+int Reference::callUsesReferenceVirtual(Reference &r, int inc)
+{
+ return usesReferenceVirtual(r, inc);
+}
+
+int Reference::callUsesConstReferenceVirtual(const Reference &r, int inc)
+{
+ return usesConstReferenceVirtual(r, inc);
+}
+
+void Reference::alterReferenceIdVirtual(Reference &r)
+{
+ r.setObjId(r.objId() * Reference::multiplier());
+}
+
+void Reference::callAlterReferenceIdVirtual(Reference &r)
+{
+ alterReferenceIdVirtual(r);
+}
+
+ObjTypeReference::~ObjTypeReference() = default;
+
+ObjTypeReference &ObjTypeReference::returnMySecondArg(int, ObjTypeReference &ref)
+{
+ return ref;
+}
diff --git a/sources/shiboken6/tests/libsample/reference.h b/sources/shiboken6/tests/libsample/reference.h
new file mode 100644
index 000000000..52818d9ea
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/reference.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef REFERENCE_H
+#define REFERENCE_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API Reference
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Reference)
+
+ explicit Reference(int objId = -1) noexcept
+ : m_objId(objId) {}
+ virtual ~Reference() = default;
+
+ inline int objId() const { return m_objId; }
+ inline void setObjId(int objId) { m_objId = objId; }
+
+ inline static int usesReference(Reference &r) { return r.m_objId; }
+ inline static int usesConstReference(const Reference &r) { return r.m_objId; }
+
+ virtual int usesReferenceVirtual(Reference &r, int inc);
+ virtual int usesConstReferenceVirtual(const Reference &r, int inc);
+
+ int callUsesReferenceVirtual(Reference &r, int inc);
+ int callUsesConstReferenceVirtual(const Reference &r, int inc);
+
+ virtual void alterReferenceIdVirtual(Reference &r);
+ void callAlterReferenceIdVirtual(Reference &r);
+
+ void show() const;
+
+ inline static int multiplier() { return 10; }
+
+ virtual Reference &returnMyFirstArg(Reference &ref) { return ref; }
+ virtual Reference &returnMySecondArg(int a, Reference &ref);
+
+ // nonsense operator to test if Shiboken is ignoring dereference operators.
+ int operator*() { return m_objId; }
+
+private:
+ int m_objId;
+};
+
+class LIBSAMPLE_API ObjTypeReference
+{
+public:
+ LIBMINIMAL_DISABLE_MOVE(ObjTypeReference)
+
+ ObjTypeReference() noexcept = default;
+ ObjTypeReference(const ObjTypeReference &) noexcept = default;
+ ObjTypeReference &operator=(const ObjTypeReference &) = delete;
+ virtual ~ObjTypeReference();
+
+ virtual ObjTypeReference &returnMyFirstArg(ObjTypeReference &ref) { return ref; }
+ virtual ObjTypeReference &returnMySecondArg(int a, ObjTypeReference &ref);
+ virtual ObjTypeReference &justAPureVirtualFunc(ObjTypeReference &ref) = 0;
+};
+
+#endif // REFERENCE_H
diff --git a/sources/shiboken6/tests/libsample/removednamespaces.h b/sources/shiboken6/tests/libsample/removednamespaces.h
new file mode 100644
index 000000000..669f2ebf0
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/removednamespaces.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef REMOVEDNAMESPACE_H
+#define REMOVEDNAMESPACE_H
+
+#include "libsamplemacros.h"
+
+namespace RemovedNamespace1
+{
+
+enum RemovedNamespace1_Enum { RemovedNamespace1_Enum_Value0 = 0,
+ RemovedNamespace1_Enum_Value1 = 1 };
+
+enum { RemovedNamespace1_AnonymousEnum_Value0 };
+
+inline int mathSum(int x, int y) { return x + y; }
+
+struct ObjectOnInvisibleNamespace
+{
+ bool exists() const { return true; }
+ static int toInt(RemovedNamespace1_Enum e) { return static_cast<int>(e); }
+ static ObjectOnInvisibleNamespace consume(const ObjectOnInvisibleNamespace &other) { return other; }
+};
+
+namespace RemovedNamespace2
+{
+
+enum RemovedNamespace2_Enum { RemovedNamespace2_Enum_Value0 };
+
+} // namespace RemovedNamespace2
+} // namespace RemovedNamespace1
+
+namespace UnremovedNamespace
+{
+
+namespace RemovedNamespace3
+{
+ enum RemovedNamespace3_Enum { RemovedNamespace3_Enum_Value0 };
+
+ enum { RemovedNamespace3_AnonymousEnum_Value0 };
+
+ inline int nestedMathSum(int x, int y) { return x + y; }
+
+} // namespace RemovedNamespace3
+} // namespace UnremovedNamespace
+
+#endif // REMOVEDNAMESPACE_H
diff --git a/sources/shiboken6/tests/libsample/renaming.cpp b/sources/shiboken6/tests/libsample/renaming.cpp
new file mode 100644
index 000000000..d67b42a51
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/renaming.cpp
@@ -0,0 +1,21 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "renaming.h"
+
+#include <iostream>
+
+int ToBeRenamedValue::value() const
+{
+ return m_value;
+}
+
+void ToBeRenamedValue::setValue(int v)
+{
+ m_value = v;
+}
+
+void RenamedUser::useRenamedValue(const ToBeRenamedValue &v)
+{
+ std::cout << __FUNCTION__ << ' ' << v.value() << '\n';
+}
diff --git a/sources/shiboken6/tests/libsample/renaming.h b/sources/shiboken6/tests/libsample/renaming.h
new file mode 100644
index 000000000..787ccc2f7
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/renaming.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef RENAMING_H
+#define RENAMING_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API ToBeRenamedValue
+{
+public:
+ int value() const;
+ void setValue(int v);
+
+private:
+ int m_value = 42;
+};
+
+class LIBSAMPLE_API RenamedUser
+{
+public:
+ void useRenamedValue(const ToBeRenamedValue &v);
+};
+
+#endif // POINT_H
diff --git a/sources/shiboken6/tests/libsample/sample.cpp b/sources/shiboken6/tests/libsample/sample.cpp
new file mode 100644
index 000000000..5b5f8588b
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/sample.cpp
@@ -0,0 +1,22 @@
+// 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 "sample.h"
+
+namespace sample
+{
+
+sample::sample(int value) : m_value(value)
+{
+}
+
+int sample::value() const
+{
+ return m_value;
+}
+
+bool operator==(const sample &s1, const sample &s2)
+{
+ return s1.value() == s2.value();
+}
+} // namespace sample
diff --git a/sources/shiboken6/tests/libsample/sample.h b/sources/shiboken6/tests/libsample/sample.h
new file mode 100644
index 000000000..27909571a
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/sample.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SAMPLE_H
+#define SAMPLE_H
+
+#include "libsamplemacros.h"
+
+// namespace with the same name of the current package to try to mess up with the generator
+namespace sample
+{
+ // to increase the mess we add a class with the same name of the package/namespace
+ class LIBSAMPLE_API sample
+ {
+ public:
+ sample(int value = 0);
+ int value() const;
+ private:
+ int m_value;
+ };
+
+ // shiboken must not generate richcompare for namespace sample
+ LIBSAMPLE_API bool operator==(const sample &s1, const sample &s2);
+
+ const int INT_CONSTANT = 42;
+}
+
+#endif // SAMPLE_H
diff --git a/sources/shiboken6/tests/libsample/samplenamespace.cpp b/sources/shiboken6/tests/libsample/samplenamespace.cpp
new file mode 100644
index 000000000..eae5af2d2
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/samplenamespace.cpp
@@ -0,0 +1,101 @@
+// 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 "samplenamespace.h"
+
+#include <iostream>
+#include <cstdlib>
+#include <ctime>
+
+namespace SampleNamespace
+{
+
+// PYSIDE-817, scoped enums must not be converted to int in the wrappers generated
+// for the protected hacks
+SomeClass::PublicScopedEnum SomeClass::protectedMethodReturningPublicScopedEnum() const
+{
+ return PublicScopedEnum::v1;
+}
+
+OutValue enumInEnumOut(InValue in)
+{
+ auto retval = OutValue(-1);
+ switch(in) {
+ case ZeroIn:
+ retval = ZeroOut;
+ break;
+ case OneIn:
+ retval = OneOut;
+ break;
+ case TwoIn:
+ retval = TwoOut;
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+Option enumArgumentWithDefaultValue(Option opt)
+{
+ return opt;
+}
+
+int getNumber(Option opt)
+{
+ int retval;
+ switch(opt) {
+ case RandomNumber:
+ retval = rand() % 100;
+ break;
+ case UnixTime:
+ retval = int(std::time(nullptr));
+ break;
+ default:
+ retval = 0;
+ break;
+ }
+ return retval;
+}
+
+void doSomethingWithArray(const unsigned char *, unsigned int, const char *)
+{
+ // This function does nothing in fact.
+ // It is here as a dummy copy of QPixmap.loadFromData method
+ // to check compilation issues, i.e. if it compiles, it's ok.
+}
+
+int enumItemAsDefaultValueToIntArgument(int value)
+{
+ return value;
+}
+
+void forceDecisorSideA(ObjectType *)
+{
+}
+
+void forceDecisorSideA(const Point &, const Str &, ObjectType *)
+{
+}
+
+void forceDecisorSideB(int, ObjectType *)
+{
+}
+
+void forceDecisorSideB(int, const Point &, const Str &, ObjectType *)
+{
+}
+
+double passReferenceToValueType(const Point &point, double multiplier)
+{
+ return (point.x() + point.y()) * multiplier;
+}
+
+int passReferenceToObjectType(const ObjectType &obj, int multiplier)
+{
+ return obj.objectName().size() * multiplier;
+}
+
+int variableInNamespace = 42;
+
+} // namespace SampleNamespace
diff --git a/sources/shiboken6/tests/libsample/samplenamespace.h b/sources/shiboken6/tests/libsample/samplenamespace.h
new file mode 100644
index 000000000..99a0787ee
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/samplenamespace.h
@@ -0,0 +1,164 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SAMPLENAMESPACE_H
+#define SAMPLENAMESPACE_H
+
+#include "libsamplemacros.h"
+#include "str.h"
+#include "point.h"
+#include "objecttype.h"
+
+#include <list>
+
+// Anonymous global enum
+enum {
+ AnonymousGlobalEnum_Value0,
+ AnonymousGlobalEnum_Value1
+};
+
+namespace SampleNamespace
+{
+
+inline namespace InlineNamespace
+{
+ enum EnumWithinInlineNamespace { EWIN_Value0, EWIN_Value1 };
+
+ class LIBSAMPLE_API ClassWithinInlineNamespace {
+ public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ClassWithinInlineNamespace)
+
+ ClassWithinInlineNamespace() noexcept = default;
+ ~ClassWithinInlineNamespace() = default;
+
+ void setValue(EnumWithinInlineNamespace v) { m_value = v; }
+ EnumWithinInlineNamespace value() const { return m_value; }
+
+ private:
+ EnumWithinInlineNamespace m_value = EWIN_Value0;
+ };
+} // inline ns
+
+enum Option {
+ None_,
+ RandomNumber,
+ UnixTime
+};
+
+enum InValue {
+ ZeroIn,
+ OneIn,
+ TwoIn
+};
+
+enum OutValue {
+ ZeroOut,
+ OneOut,
+ TwoOut
+};
+
+// Anonymous non-global enum.
+// This counts as a class enum, since C++ namespaces
+// are represented as classes in Python.
+enum {
+ AnonymousClassEnum_Value0,
+ AnonymousClassEnum_Value1
+};
+
+LIBSAMPLE_API OutValue enumInEnumOut(InValue in);
+
+LIBSAMPLE_API Option enumArgumentWithDefaultValue(Option opt = UnixTime);
+
+LIBSAMPLE_API int getNumber(Option opt);
+
+inline double powerOfTwo(double num) {
+ return num * num;
+}
+
+LIBSAMPLE_API void doSomethingWithArray(const unsigned char *data, unsigned int size,
+ const char *format = nullptr);
+
+LIBSAMPLE_API int enumItemAsDefaultValueToIntArgument(int value = ZeroIn);
+
+class LIBSAMPLE_API SomeClass
+{
+public:
+ enum class PublicScopedEnum { v1, v2 };
+
+ class SomeInnerClass
+ {
+ public:
+ class OkThisIsRecursiveEnough
+ {
+ public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(OkThisIsRecursiveEnough)
+
+ OkThisIsRecursiveEnough() noexcept = default;
+ virtual ~OkThisIsRecursiveEnough() = default;
+ enum NiceEnum {
+ NiceValue1, NiceValue2
+ };
+
+ enum class NiceEnumClass {
+ NiceClassValue1, NiceClassValue2
+ };
+
+ inline int someMethod(SomeInnerClass *) { return 0; }
+ virtual OkThisIsRecursiveEnough *someVirtualMethod(OkThisIsRecursiveEnough *arg)
+ { return arg; }
+ };
+ protected:
+ enum ProtectedEnum {
+ ProtectedItem0,
+ ProtectedItem1
+ };
+ };
+ struct SomeOtherInnerClass {
+ std::list<SomeInnerClass> someInnerClasses;
+ };
+protected:
+ enum ProtectedEnum {
+ ProtectedItem0,
+ ProtectedItem1
+ };
+
+ PublicScopedEnum protectedMethodReturningPublicScopedEnum() const;
+};
+
+LIBSAMPLE_API inline int enumAsInt(SomeClass::PublicScopedEnum value)
+{ return static_cast<int>(value); }
+
+class DerivedFromNamespace : public SomeClass::SomeInnerClass::OkThisIsRecursiveEnough
+{
+public:
+ // FIXME Uncomment this when the fix for MSVC is available
+ // only to cause namespace confusion
+// enum SampleNamespace {
+// };
+ virtual OkThisIsRecursiveEnough *someVirtualMethod(OkThisIsRecursiveEnough *arg) { return arg; }
+ inline OkThisIsRecursiveEnough *methodReturningTypeFromParentScope() { return nullptr; }
+};
+
+// The combination of the following two overloaded methods could trigger a
+// problematic behaviour on the overload decisor, if it isn't working properly.
+LIBSAMPLE_API void forceDecisorSideA(ObjectType *object = nullptr);
+LIBSAMPLE_API void forceDecisorSideA(const Point &pt, const Str &text,
+ ObjectType *object = nullptr);
+
+// The combination of the following two overloaded methods could trigger a
+// problematic behaviour on the overload decisor, if it isn't working properly.
+// This is a variation of forceDecisorSideB.
+LIBSAMPLE_API void forceDecisorSideB(int a, ObjectType *object = nullptr);
+LIBSAMPLE_API void forceDecisorSideB(int a, const Point &pt, const Str &text,
+ ObjectType *object = nullptr);
+
+// Add a new signature on type system with only a Point value as parameter.
+LIBSAMPLE_API double passReferenceToValueType(const Point &point, double multiplier);
+// Add a new signature on type system with only a ObjectType pointer as parameter.
+LIBSAMPLE_API int passReferenceToObjectType(const ObjectType &obj, int multiplier);
+
+extern LIBSAMPLE_API int variableInNamespace;
+
+} // namespace SampleNamespace
+
+#endif // SAMPLENAMESPACE_H
diff --git a/sources/shiboken6/tests/libsample/sbkdate.cpp b/sources/shiboken6/tests/libsample/sbkdate.cpp
new file mode 100644
index 000000000..fd408f637
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/sbkdate.cpp
@@ -0,0 +1,23 @@
+// 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 "sbkdate.h"
+
+SbkDate::SbkDate(int d, int m, int y) : m_d(d), m_m(m), m_y(y)
+{
+}
+
+int SbkDate::day() const
+{
+ return m_d;
+}
+
+int SbkDate::month() const
+{
+ return m_m;
+}
+
+int SbkDate::year() const
+{
+ return m_y;
+}
diff --git a/sources/shiboken6/tests/libsample/sbkdate.h b/sources/shiboken6/tests/libsample/sbkdate.h
new file mode 100644
index 000000000..5e1dd0b84
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/sbkdate.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SBKDATE_H
+#define SBKDATE_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API SbkDate
+{
+public:
+ explicit SbkDate(int d, int m, int y);
+
+ int day() const;
+ int month() const;
+ int year() const;
+
+private:
+ int m_d;
+ int m_m;
+ int m_y;
+};
+
+#endif // SBKDATE_H
diff --git a/sources/shiboken6/tests/libsample/simplefile.cpp b/sources/shiboken6/tests/libsample/simplefile.cpp
new file mode 100644
index 000000000..e51b14088
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/simplefile.cpp
@@ -0,0 +1,73 @@
+// 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 "simplefile.h"
+
+#include <cstdlib>
+#include <cstdio>
+#include <string>
+#include <filesystem>
+
+class SimpleFilePrivate
+{
+public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(SimpleFilePrivate)
+
+ SimpleFilePrivate(const char *filename) : m_filename(filename) {}
+ ~SimpleFilePrivate() = default;
+
+ std::string m_filename;
+ FILE *m_descriptor = nullptr;
+ long m_size = 0;
+};
+
+SimpleFile::SimpleFile(const char *filename) :
+ p(std::make_unique<SimpleFilePrivate>(filename))
+{
+}
+
+SimpleFile::~SimpleFile()
+{
+ close();
+}
+
+const char *SimpleFile::filename()
+{
+ return p->m_filename.c_str();
+}
+
+long SimpleFile::size() const
+{
+ return p->m_size;
+}
+
+bool SimpleFile::open()
+{
+ auto *descriptor = std::fopen(p->m_filename.c_str(), "rb");
+ if (descriptor == nullptr)
+ return false;
+
+ p->m_descriptor = descriptor;
+ const auto size = std::filesystem::file_size(std::filesystem::path(p->m_filename));
+ p->m_size = long(size);
+
+ return true;
+}
+
+void SimpleFile::close()
+{
+ if (p->m_descriptor != nullptr) {
+ std::fclose(p->m_descriptor);
+ p->m_descriptor = nullptr;
+ }
+}
+
+bool SimpleFile::exists() const
+{
+ return std::filesystem::exists(std::filesystem::path(p->m_filename));
+}
+
+bool SimpleFile::exists(const char *filename)
+{
+ return std::filesystem::exists(std::filesystem::path(filename));
+}
diff --git a/sources/shiboken6/tests/libsample/simplefile.h b/sources/shiboken6/tests/libsample/simplefile.h
new file mode 100644
index 000000000..e4612c944
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/simplefile.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SIMPLEFILE_H
+#define SIMPLEFILE_H
+
+#include "libsamplemacros.h"
+
+#include <memory>
+
+class SimpleFilePrivate;
+
+class LIBSAMPLE_API SimpleFile
+{
+public:
+ LIBMINIMAL_DISABLE_COPY(SimpleFile)
+ LIBMINIMAL_DEFAULT_MOVE(SimpleFile)
+
+ explicit SimpleFile(const char *filename);
+ ~SimpleFile();
+
+ const char *filename();
+ long size() const;
+ bool open();
+ void close();
+
+ bool exists() const;
+ static bool exists(const char *filename);
+
+private:
+ std::unique_ptr<SimpleFilePrivate> p;
+};
+
+#endif // SIMPLEFILE_H
diff --git a/sources/shiboken6/tests/libsample/size.cpp b/sources/shiboken6/tests/libsample/size.cpp
new file mode 100644
index 000000000..0291d6e86
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/size.cpp
@@ -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 "size.h"
+
+#include <iostream>
+
+void Size::show() const
+{
+ std::cout << "(width: " << m_width << ", height: " << m_height << ")";
+}
diff --git a/sources/shiboken6/tests/libsample/size.h b/sources/shiboken6/tests/libsample/size.h
new file mode 100644
index 000000000..2d194e96b
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/size.h
@@ -0,0 +1,185 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SIZE_H
+#define SIZE_H
+
+#include "libsamplemacros.h"
+
+class LIBSAMPLE_API Size
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Size)
+
+ explicit Size(double width = 0.0, double height = 0.0) noexcept :
+ m_width(width), m_height(height) {}
+ ~Size() = default;
+
+ inline double width() const { return m_width; }
+ inline void setWidth(double width) { m_width = width; }
+ inline double height() const { return m_height; }
+ inline void setHeight(double height) { m_height = height; }
+
+ inline double calculateArea() const { return m_width * m_height; }
+
+ // Comparison Operators
+ inline bool operator<(const Size &other)
+ {
+ return calculateArea() < other.calculateArea();
+ }
+
+ inline bool operator>(const Size &other)
+ {
+ // On some x86 hardware and compiler combinations, floating point
+ // comparisons may fail due to a hardware bug. One workaround is to
+ // simplify comparison expressions by putting partial results in
+ // variables. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c109
+ // for details.
+ double a = calculateArea();
+ double b = other.calculateArea();
+ return a > b;
+ }
+
+ inline bool operator<=(const Size &other)
+ {
+ // See comments for operator>()
+ double a = calculateArea();
+ double b = other.calculateArea();
+ return a <= b;
+ }
+
+ inline bool operator>=(const Size &other)
+ {
+ return calculateArea() >= other.calculateArea();
+ }
+
+ inline bool operator<(double area) { return calculateArea() < area; }
+ inline bool operator>(double area) { return calculateArea() > area; }
+ inline bool operator<=(double area) { return calculateArea() <= area; }
+ inline bool operator>=(double area) { return calculateArea() >= area; }
+
+ // Arithmetic Operators
+ inline Size &operator+=(const Size &s)
+ {
+ m_width += s.m_width;
+ m_height += s.m_height;
+ return *this;
+ }
+
+ inline Size &operator-=(const Size &s)
+ {
+ m_width -= s.m_width;
+ m_height -= s.m_height;
+ return *this;
+ }
+
+ inline Size &operator*=(double mult)
+ {
+ m_width *= mult;
+ m_height *= mult;
+ return *this;
+ }
+
+ inline Size &operator/=(double div)
+ {
+ m_width /= div;
+ m_height /= div;
+ return *this;
+ }
+
+ // TODO: add ++size, size++, --size, size--
+
+ // External operators
+ friend inline bool operator==(const Size&, const Size&);
+ friend inline bool operator!=(const Size&, const Size&);
+ friend inline Size operator+(const Size&, const Size&);
+ friend inline Size operator-(const Size&, const Size&);
+ friend inline Size operator*(const Size&, double);
+ friend inline Size operator*(double, const Size&);
+ friend inline Size operator/(const Size&, double);
+
+ friend inline bool operator<(double, const Size&);
+ friend inline bool operator>(double, const Size&);
+ friend inline bool operator<=(double, const Size&);
+ friend inline bool operator>=(double, const Size&);
+
+ void show() const;
+
+private:
+ double m_width;
+ double m_height;
+};
+
+// Comparison Operators
+inline bool operator!=(const Size &s1, const Size &s2)
+{
+ return s1.m_width != s2.m_width || s1.m_height != s2.m_height;
+}
+
+inline bool operator==(const Size &s1, const Size &s2)
+{
+ return s1.m_width == s2.m_width && s1.m_height == s2.m_height;
+}
+
+inline bool operator<(double area, const Size &s)
+{
+ return area < s.calculateArea();
+}
+
+inline bool operator>(double area, const Size &s)
+{
+ return area > s.calculateArea();
+}
+
+inline bool operator<=(double area, const Size &s)
+{
+ return area <= s.calculateArea();
+}
+
+inline bool operator>=(double area, const Size &s)
+{
+ return area >= s.calculateArea();
+}
+
+// Arithmetic Operators
+inline Size operator+(const Size &s1, const Size &s2)
+{
+ return Size(s1.m_width + s2.m_width, s1.m_height + s2.m_height);
+}
+
+inline Size operator-(const Size &s1, const Size &s2)
+{
+ return Size(s1.m_width - s2.m_width, s1.m_height - s2.m_height);
+}
+
+inline Size operator*(const Size &s, double mult)
+{
+ return Size(s.m_width * mult, s.m_height * mult);
+}
+
+inline Size operator*(double mult, const Size &s)
+{
+ return Size(s.m_width * mult, s.m_height * mult);
+}
+
+inline Size operator/(const Size &s, double div)
+{
+ return Size(s.m_width / div, s.m_height / div);
+}
+
+using real = double;
+using ushort = unsigned short;
+
+class LIBSAMPLE_API SizeF
+{
+public:
+ explicit SizeF(real width, real height) : m_width(width), m_height(height) {}
+ real width() const { return m_width; }
+ real height() const { return m_height; }
+ static inline ushort passTypedefOfUnsignedShort(ushort value) { return value; }
+private:
+ real m_width;
+ real m_height;
+};
+
+#endif // SIZE_H
diff --git a/sources/shiboken6/tests/libsample/snakecasetest.cpp b/sources/shiboken6/tests/libsample/snakecasetest.cpp
new file mode 100644
index 000000000..8240308b4
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/snakecasetest.cpp
@@ -0,0 +1,44 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "snakecasetest.h"
+
+int SnakeCaseGlobalFunction()
+{
+ return 42;
+}
+
+SnakeCaseTest::SnakeCaseTest() = default;
+SnakeCaseTest::~SnakeCaseTest() = default;
+
+int SnakeCaseTest::testFunction1() const
+{
+ return 42;
+}
+
+int SnakeCaseTest::testFunctionDisabled() const
+{
+ return 42;
+}
+
+int SnakeCaseTest::testFunctionBoth() const
+{
+ return 42;
+}
+
+int SnakeCaseTest::callVirtualFunc() const
+{
+ return virtualFunc();
+}
+
+int SnakeCaseTest::virtualFunc() const
+{
+ return 42;
+}
+
+SnakeCaseDerivedTest::SnakeCaseDerivedTest() = default;
+
+int SnakeCaseDerivedTest::virtualFunc() const
+{
+ return 43;
+}
diff --git a/sources/shiboken6/tests/libsample/snakecasetest.h b/sources/shiboken6/tests/libsample/snakecasetest.h
new file mode 100644
index 000000000..757dd23b2
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/snakecasetest.h
@@ -0,0 +1,40 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SNAKECASETEST_H
+#define SNAKECASETEST_H
+
+#include "libsamplemacros.h"
+
+LIBSAMPLE_API int SnakeCaseGlobalFunction();
+
+class LIBSAMPLE_API SnakeCaseTest
+{
+public:
+ SnakeCaseTest();
+ virtual ~SnakeCaseTest();
+
+ int testFunction1() const;
+ int testFunctionDisabled() const;
+ int testFunctionBoth() const;
+
+ int callVirtualFunc() const;
+
+ int testField = 42;
+ int testFieldDisabled = 42;
+ int testFieldBoth = 42;
+
+protected:
+ virtual int virtualFunc() const;
+};
+
+class LIBSAMPLE_API SnakeCaseDerivedTest : public SnakeCaseTest
+{
+public:
+ SnakeCaseDerivedTest();
+
+protected:
+ int virtualFunc() const override;
+};
+
+#endif // SNAKECASETEST_H
diff --git a/sources/shiboken6/tests/libsample/sometime.cpp b/sources/shiboken6/tests/libsample/sometime.cpp
new file mode 100644
index 000000000..ad9a0d81c
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/sometime.cpp
@@ -0,0 +1,67 @@
+// 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 "sometime.h"
+
+#include <cstdio>
+
+void Time::setTime()
+{
+ m_hour = 0;
+ m_minute = 0;
+ m_second = 0;
+ m_msec = 0;
+ m_is_null = true;
+}
+
+void Time::setTime(int h, int m, int s, int ms)
+{
+ m_hour = h;
+ m_minute = m;
+ m_second = s;
+ m_msec = ms;
+ m_is_null = false;
+}
+
+Time::NumArgs Time::somethingCompletelyDifferent()
+{
+ return ZeroArgs;
+}
+
+Time::NumArgs Time::somethingCompletelyDifferent(int, int, ImplicitConv ic, ObjectType *type)
+{
+ if (type)
+ return FourArgs;
+ if (ic.ctorEnum() == ImplicitConv::CtorThree && ic.objId() == -1)
+ return TwoArgs;
+ return ThreeArgs;
+}
+
+Str Time::toString() const
+{
+ if (m_is_null)
+ return Str();
+ char buffer[13];
+ std::snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%03d",
+ m_hour, m_minute, m_second, m_msec);
+ return Str(buffer);
+}
+
+bool Time::operator==(const Time &other) const
+{
+ return m_hour == other.m_hour
+ && m_minute == other.m_minute
+ && m_second == other.m_second
+ && m_msec == other.m_msec
+ && m_is_null == other.m_is_null;
+}
+
+bool Time::operator!=(const Time &other) const
+{
+ return !operator==(other);
+}
+
+Time::operator Str() const
+{
+ return Time::toString();
+}
diff --git a/sources/shiboken6/tests/libsample/sometime.h b/sources/shiboken6/tests/libsample/sometime.h
new file mode 100644
index 000000000..575d4b136
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/sometime.h
@@ -0,0 +1,66 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SOMETIME_H
+#define SOMETIME_H
+
+#include "libsamplemacros.h"
+#include "str.h"
+#include "implicitconv.h"
+#include "objecttype.h"
+
+class LIBSAMPLE_API Time
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Time)
+
+ enum NumArgs {
+ ZeroArgs,
+ TwoArgs,
+ ThreeArgs,
+ FourArgs
+ };
+
+ Time() noexcept = default;
+ explicit Time(int h, int m, int s = 0, int ms = 0) noexcept:
+ m_hour(h), m_minute(m), m_second(s), m_msec(ms), m_is_null(false)
+ {}
+
+ ~Time() = default;
+
+ inline bool isNull() const { return m_is_null; }
+
+ inline int hour() const { return m_hour; }
+ inline int minute() const { return m_minute; }
+ inline int second() const { return m_second; }
+ inline int msec() const { return m_msec; }
+
+ void setTime();
+ void setTime(int h, int m, int s = 0, int ms = 0);
+
+ // This one is completely different from the other methods in this class,
+ // it was added to give the overload decisor a really hard time with
+ // an value-type with implicit conversion and a default argument, and also
+ // an object-type, just because I feel like it.
+ NumArgs somethingCompletelyDifferent();
+ NumArgs somethingCompletelyDifferent(int h, int m,
+ ImplicitConv ic = ImplicitConv::CtorThree,
+ ObjectType *type = nullptr);
+
+ Str toString() const;
+ bool operator==(const Time &other) const;
+ bool operator!=(const Time &other) const;
+
+ // This cast operator must become an implicit conversion of Str.
+ operator Str() const;
+
+private:
+ int m_hour = 0;
+ int m_minute = 0;
+ int m_second = 0;
+ int m_msec = 0;
+
+ bool m_is_null = true;
+};
+
+#endif // SOMETIME_H
diff --git a/sources/shiboken6/tests/libsample/stdcomplex.cpp b/sources/shiboken6/tests/libsample/stdcomplex.cpp
new file mode 100644
index 000000000..847174387
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/stdcomplex.cpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "stdcomplex.h"
+
+#include <iostream>
+
+StdComplex::StdComplex() noexcept = default;
+
+StdComplex::StdComplex(double re, double img) noexcept : m_impl(re, img)
+{
+}
+
+StdComplex::operator int() const
+{
+ return std::lround(abs_value());
+}
+
+StdComplex::StdComplex(const Impl &impl) noexcept : m_impl(impl)
+{
+}
+
+StdComplex StdComplex::pow(const StdComplex &exp) const
+{
+ return StdComplex(std::pow(m_impl, exp.m_impl));
+}
+
+std::ostream &operator<<(std::ostream &str, const StdComplex &c)
+{
+ str << "Complex(" << c.real() << ", " << c.imag() << ')';
+ return str;
+}
diff --git a/sources/shiboken6/tests/libsample/stdcomplex.h b/sources/shiboken6/tests/libsample/stdcomplex.h
new file mode 100644
index 000000000..b39b80612
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/stdcomplex.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef STDCOMPLEX_H
+#define STDCOMPLEX_H
+
+#include "libsamplemacros.h"
+
+#include <complex>
+#include <iosfwd>
+
+// A complex number based on std::complex for exercising esoteric number
+// protocols (Py_nb_). For standard number protocols, see Point.
+
+class LIBSAMPLE_API StdComplex
+{
+ using Impl = std::complex<double>;
+
+public:
+ StdComplex() noexcept;
+ explicit StdComplex(double re, double img) noexcept;
+
+ double real() const { return m_impl.real(); }
+ double imag() const { return m_impl.imag(); }
+
+ double abs_value() const { return std::abs(m_impl); } // abs() is reserved Python word
+
+ StdComplex pow(const StdComplex &exp) const;
+
+ operator double() const { return abs_value(); }
+ operator int() const;
+
+ friend inline bool operator==(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return c1.m_impl == c2.m_impl; }
+ friend inline bool operator!=(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return c1.m_impl != c2.m_impl; }
+
+ friend inline StdComplex operator+(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return StdComplex(c1.m_impl + c2.m_impl); }
+ friend inline StdComplex operator-(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return StdComplex(c1.m_impl - c2.m_impl); }
+ friend inline StdComplex operator*(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return StdComplex(c1.m_impl * c2.m_impl); }
+ friend inline StdComplex operator/(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return StdComplex(c1.m_impl / c2.m_impl); }
+
+private:
+ explicit StdComplex(const Impl &impl) noexcept;
+
+ Impl m_impl;
+};
+
+std::ostream &operator<<(std::ostream &str, const StdComplex &c);
+
+#endif // STDCOMPLEX_H
diff --git a/sources/shiboken6/tests/libsample/str.cpp b/sources/shiboken6/tests/libsample/str.cpp
new file mode 100644
index 000000000..742c0bb01
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/str.cpp
@@ -0,0 +1,137 @@
+// 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 "str.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+Str::Str(char c)
+{
+ char str[2] = { c, 0 };
+ init(str);
+}
+
+Str::Str(const char *cstr)
+{
+ init(cstr);
+}
+
+void Str::init(const char *cstr)
+{
+ if (cstr)
+ m_str = cstr;
+}
+
+Str Str::arg(const Str &s) const
+{
+ size_t idx = m_str.find_first_of("%VAR");
+ if (idx == std::string::npos)
+ return *this;
+
+ std::string result = m_str;
+ result.replace(idx, 4, s.m_str);
+ return result.c_str();
+}
+
+Str &Str::append(const Str &s)
+{
+ m_str += s.m_str;
+ return *this;
+}
+
+Str &Str::prepend(const Str &s)
+{
+ m_str = s.m_str + m_str;
+ return *this;
+}
+
+const char *Str::cstring() const
+{
+ return m_str.c_str();
+}
+
+int Str::toInt(bool *ok, int base) const
+{
+ int result = 0;
+ std::istringstream conv(m_str);
+ switch (base) {
+ case 8:
+ conv >> std::oct >> result;
+ break;
+ case 10:
+ conv >> std::dec >> result;
+ break;
+ case 16:
+ conv >> std::hex >> result;
+ break;
+ }
+ const bool my_ok = std::istringstream::eofbit & conv.rdstate();
+ if (!my_ok)
+ result = 0;
+ if (ok)
+ *ok = my_ok;
+ return result;
+}
+
+void Str::show() const
+{
+ std::printf("%s", cstring());
+}
+
+char Str::get_char(int pos) const
+{
+ return m_str[pos];
+}
+
+bool Str::set_char(int pos, char ch)
+{
+ m_str[pos] = ch;
+ return true;
+}
+
+Str Str::operator+(int number) const
+{
+ std::ostringstream in;
+ in << m_str << number;
+ return in.str().c_str();
+}
+
+bool Str::operator==(const Str &other) const
+{
+ return m_str == other.m_str;
+}
+
+Str operator+(int number, const Str &str)
+{
+ std::ostringstream in;
+ in << number << str.m_str;
+ return in.str().c_str();
+}
+
+bool Str::operator<(const Str &other) const
+{
+ return m_str < other.m_str;
+}
+
+unsigned int strHash(const Str &str)
+{
+ unsigned int result = 0;
+ for (char c : str.m_str)
+ result = 5U * result + unsigned(c);
+ return result;
+}
+
+void changePStr(PStr *pstr, const char *suffix)
+{
+ pstr->append(suffix);
+}
+
+void duplicatePStr(PStr *pstr)
+{
+ if (!pstr)
+ return;
+ pstr->append(*pstr);
+}
diff --git a/sources/shiboken6/tests/libsample/str.h b/sources/shiboken6/tests/libsample/str.h
new file mode 100644
index 000000000..6b3386cef
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/str.h
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef STR_H
+#define STR_H
+
+#include "libsamplemacros.h"
+
+#include <string>
+
+class LIBSAMPLE_API Str
+{
+public:
+ Str(char c);
+ Str(const char *cstr = "");
+
+ Str arg(const Str &s) const;
+
+ Str &append(const Str &s);
+ Str &prepend(const Str &s);
+
+ const char *cstring() const;
+ char get_char(int pos) const;
+ bool set_char(int pos, char ch);
+
+ int toInt(bool *ok = nullptr, int base = 10) const;
+
+ void show() const;
+
+ inline int size() const { return int(m_str.size()); }
+
+ // nonsense operator just to test reverse operators
+ Str operator+(int number) const;
+ bool operator==(const Str &other) const;
+ bool operator<(const Str &other) const;
+
+private:
+ void init(const char *cstr);
+ std::string m_str;
+
+ friend LIBSAMPLE_API Str operator+(int number, const Str &str);
+ friend LIBSAMPLE_API unsigned int strHash(const Str &str);
+};
+
+LIBSAMPLE_API Str operator+(int number, const Str &str);
+LIBSAMPLE_API unsigned int strHash(const Str &str);
+
+using PStr = Str;
+LIBSAMPLE_API void changePStr(PStr *pstr, const char *suffix);
+LIBSAMPLE_API void duplicatePStr(PStr *pstr = nullptr);
+
+#endif // STR_H
diff --git a/sources/shiboken6/tests/libsample/strlist.cpp b/sources/shiboken6/tests/libsample/strlist.cpp
new file mode 100644
index 000000000..5840a0516
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/strlist.cpp
@@ -0,0 +1,25 @@
+// 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 "strlist.h"
+
+#include <algorithm>
+
+bool StrList::operator==(const std::list<Str> &other) const
+{
+ return size() == other.size()
+ && std::equal(begin(), end(), other.begin());
+}
+
+Str StrList::join(const Str &sep) const
+{
+ Str result;
+ const auto i1 = begin();
+ const auto i2 = end();
+ for (auto it = i1; i1 != i2; ++it) {
+ if (it != i1)
+ result.append(sep);
+ result.append(*it);
+ }
+ return result;
+}
diff --git a/sources/shiboken6/tests/libsample/strlist.h b/sources/shiboken6/tests/libsample/strlist.h
new file mode 100644
index 000000000..01865a5b4
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/strlist.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef STRLIST_H
+#define STRLIST_H
+
+#include "libsamplemacros.h"
+#include "str.h"
+
+#include <list>
+
+class LIBSAMPLE_API StrList : public std::list<Str>
+{
+public:
+ enum CtorEnum {
+ NoParamsCtor,
+ StrCtor,
+ CopyCtor,
+ ListOfStrCtor
+ };
+
+ inline StrList() = default;
+ inline StrList(const std::list<Str> &lst) :
+ std::list<Str>(lst), m_ctorUsed(ListOfStrCtor) {}
+ inline explicit StrList(const Str &str) :
+ m_ctorUsed(StrCtor) { push_back(str); }
+ inline StrList(const StrList &lst) :
+ std::list<Str>(lst), m_ctorUsed(CopyCtor) {}
+
+ StrList(StrList &&) = default;
+ StrList &operator=(const StrList &) = default;
+ StrList &operator=(StrList &&) = default;
+ ~StrList() = default;
+
+ inline void append(const Str &str) { push_back(str); }
+ Str join(const Str &sep) const;
+
+ bool operator==(const std::list<Str> &other) const;
+ inline bool operator!=(const std::list<Str> &other) const { return !(*this == other); }
+
+ CtorEnum constructorUsed() const { return m_ctorUsed; }
+
+private:
+ CtorEnum m_ctorUsed = NoParamsCtor;
+};
+
+using PStrList = StrList;
+
+#endif // STRLIST_H
diff --git a/sources/shiboken6/tests/libsample/templateptr.cpp b/sources/shiboken6/tests/libsample/templateptr.cpp
new file mode 100644
index 000000000..a73f78417
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/templateptr.cpp
@@ -0,0 +1,8 @@
+// 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 "templateptr.h"
+
+void TemplatePtr::dummy(std::list<std::pair<BlackBox *, BlackBox *> > &)
+{
+}
diff --git a/sources/shiboken6/tests/libsample/templateptr.h b/sources/shiboken6/tests/libsample/templateptr.h
new file mode 100644
index 000000000..bf230c363
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/templateptr.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TEMPLATEPTR_H
+#define TEMPLATEPTR_H
+
+#include "libsamplemacros.h"
+#include "blackbox.h"
+
+#include <utility>
+#include <list>
+
+class LIBSAMPLE_API TemplatePtr
+{
+public:
+ void dummy(std::list<std::pair<BlackBox *, BlackBox *> > &items);
+};
+
+#endif // TEMPLATEPTR_H
diff --git a/sources/shiboken6/tests/libsample/transform.cpp b/sources/shiboken6/tests/libsample/transform.cpp
new file mode 100644
index 000000000..5ccf5d1ed
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/transform.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2013 Kitware, Inc.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "transform.h"
+
+#include <cmath>
+
+Point applyHomogeneousTransform(const Point &in,
+ double m11, double m12, double m13,
+ double m21, double m22, double m23,
+ double m31, double m32, double m33,
+ bool *okay)
+{
+ double x = m11 * in.x() + m12 * in.y() + m13;
+ double y = m21 * in.x() + m22 * in.y() + m23;
+ double w = m31 * in.x() + m32 * in.y() + m33;
+
+ if (std::isfinite(w) && fabs(w) > 1e-10) {
+ if (okay)
+ *okay = true;
+ return {x / w, y / w};
+ }
+
+ if (okay)
+ *okay = false;
+ return {};
+}
diff --git a/sources/shiboken6/tests/libsample/transform.h b/sources/shiboken6/tests/libsample/transform.h
new file mode 100644
index 000000000..34ebf40d3
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/transform.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2013 Kitware, Inc.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TRANSFORM_H
+#define TRANSFORM_H
+
+#include "point.h"
+
+#include "libsamplemacros.h"
+
+LIBSAMPLE_API Point applyHomogeneousTransform(const Point &in,
+ double m11, double m12, double m13,
+ double m21, double m22, double m23,
+ double m31, double m32, double m33,
+ bool *okay);
+
+#endif // TRANSFORM_H
diff --git a/sources/shiboken6/tests/libsample/typesystypedef.cpp b/sources/shiboken6/tests/libsample/typesystypedef.cpp
new file mode 100644
index 000000000..d9c9a92fc
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/typesystypedef.cpp
@@ -0,0 +1,12 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "typesystypedef.h"
+
+ValueWithUnitUser::ValueWithUnitUser() = default;
+
+ValueWithUnit<double, LengthUnit::Millimeter>
+ ValueWithUnitUser::doubleInchToMillimeter(ValueWithUnit<double, LengthUnit::Inch> v)
+{
+ return ValueWithUnit<double, LengthUnit::Millimeter>(v.value() * 254);
+}
diff --git a/sources/shiboken6/tests/libsample/typesystypedef.h b/sources/shiboken6/tests/libsample/typesystypedef.h
new file mode 100644
index 000000000..be42fbefe
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/typesystypedef.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TYPESYSTYPEDEF_H
+#define TYPESYSTYPEDEF_H
+
+#include "libsamplemacros.h"
+
+enum class LengthUnit { Millimeter, Inch };
+
+template <class T, LengthUnit Unit>
+class ValueWithUnit
+{
+ public:
+ explicit ValueWithUnit(T value = {}) : m_value(value) {}
+
+ T value() const { return m_value; }
+ void setValue(const T &value) { m_value = value; }
+
+private:
+ T m_value;
+};
+
+class LIBSAMPLE_API ValueWithUnitUser
+{
+public:
+ ValueWithUnitUser();
+
+ static ValueWithUnit<double, LengthUnit::Millimeter> doubleInchToMillimeter(ValueWithUnit<double, LengthUnit::Inch>);
+};
+
+#endif // TYPESYSTYPEDEF_H
diff --git a/sources/shiboken6/tests/libsample/valueandvirtual.h b/sources/shiboken6/tests/libsample/valueandvirtual.h
new file mode 100644
index 000000000..799e11e40
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/valueandvirtual.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef VALUEANDVIRTUAL_H
+#define VALUEANDVIRTUAL_H
+
+#include "libsamplemacros.h"
+
+class ValueAndVirtual
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ValueAndVirtual)
+
+ explicit ValueAndVirtual(int id) noexcept : m_id(id) {}
+ virtual ~ValueAndVirtual() = default;
+
+ bool operator()(int id, int id2) { return id == id2; }
+
+ inline int id() const { return m_id; }
+
+private:
+ int m_id;
+};
+
+#endif // VALUEANDVIRTUAL_H
diff --git a/sources/shiboken6/tests/libsample/virtualmethods.cpp b/sources/shiboken6/tests/libsample/virtualmethods.cpp
new file mode 100644
index 000000000..515564664
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/virtualmethods.cpp
@@ -0,0 +1,66 @@
+// 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 "virtualmethods.h"
+
+int VirtualDtor::dtor_called = 0;
+
+double VirtualMethods::virtualMethod0(Point pt, int val, Complex cpx, bool b)
+{
+ return (pt.x() * pt.y() * val) + cpx.imag() + ((int) b);
+}
+
+bool VirtualMethods::createStr(const char *text, Str *&ret)
+{
+ if (!text) {
+ ret = nullptr;
+ return false;
+ }
+
+ ret = new Str(text);
+ return true;
+}
+
+void VirtualMethods::getMargins(int *left, int *top, int *right, int *bottom) const
+{
+ *left = m_left;
+ *top = m_top;
+ *right = m_right;
+ *bottom = m_bottom;
+}
+
+int VirtualMethods::recursionOnModifiedVirtual(Str) const
+{
+ return 0;
+}
+
+const Str & VirtualMethods::returnConstRef() const
+{
+ static const Str result;
+ return result;
+}
+
+int VirtualMethods::stringViewLength(std::string_view in) const
+{
+ return int(in.size());
+}
+
+double VirtualDaughter2::virtualMethod0(Point pt, int val, Complex cpx, bool b)
+{
+ return 42 + VirtualMethods::virtualMethod0(pt, val, cpx, b);
+}
+
+int VirtualDaughter2::sum0(int a0, int a1, int a2)
+{
+ return 42 + VirtualMethods::sum0(a0, a1, a2);
+}
+
+double VirtualFinalDaughter::virtualMethod0(Point pt, int val, Complex cpx, bool b)
+{
+ return 42 + VirtualMethods::virtualMethod0(pt, val, cpx, b);
+}
+
+int VirtualFinalDaughter::sum0(int a0, int a1, int a2)
+{
+ return 42 + VirtualMethods::sum0(a0, a1, a2);
+}
diff --git a/sources/shiboken6/tests/libsample/virtualmethods.h b/sources/shiboken6/tests/libsample/virtualmethods.h
new file mode 100644
index 000000000..b7172ad0d
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/virtualmethods.h
@@ -0,0 +1,145 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef VIRTUALMETHODS_H
+#define VIRTUALMETHODS_H
+
+#include "point.h"
+#include "complex.h"
+#include "str.h"
+
+#include "libsamplemacros.h"
+#include "strlist.h"
+
+#include <string_view>
+#include <string>
+
+class LIBSAMPLE_API VirtualMethods
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(VirtualMethods)
+
+ explicit VirtualMethods(Str name = "VirtualMethods") : m_name(name) {}
+ virtual ~VirtualMethods() = default;
+
+ virtual double virtualMethod0(Point pt, int val, Complex cpx, bool b);
+ double callVirtualMethod0(Point pt, int val, Complex cpx, bool b)
+ {
+ return virtualMethod0(pt, val, cpx, b);
+ }
+
+ // Binding modification: rename.
+ virtual int sum0(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum0(int a0, int a1, int a2) { return sum0(a0, a1, a2); }
+
+ // Binding modification: set default value for the last argument.
+ virtual int sum1(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum1(int a0, int a1, int a2) { return sum1(a0, a1, a2); }
+
+ // Binding modification: remove the last argument and set a default value for it.
+ virtual int sum2(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum2(int a0, int a1, int a2) { return sum2(a0, a1, a2); }
+
+ // Binding modification: remove the second argument.
+ virtual int sum3(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum3(int a0, int a1, int a2) { return sum3(a0, a1, a2); }
+
+ // Binding modification: remove the second argument and set its default
+ // value, then inject code on the binding reimplementation of the virtual
+ // (with a native inject-code) to sum the value of the removed
+ // argument to the first argument before the method is called.
+ virtual int sum4(int a0, int a1, int a2) { return a0 + a1 + a2; }
+ int callSum4(int a0, int a1, int a2) { return sum4(a0, a1, a2); }
+
+ // Binding modification: prepend a string to the results of a Python override.
+ virtual Str name() { return m_name; }
+ Str callName() { return name(); }
+
+ // Binding modification: code injection that calls the Python override by itself.
+ virtual void callMe() {}
+ void callCallMe() { callMe(); }
+
+ // Passing reference to pointers.
+ virtual bool createStr(const char *text, Str *&ret);
+ bool callCreateStr(const char *text, Str *&ret) { return createStr(text, ret); }
+
+ // Return a non-binded method
+ std::list<Str> callStrListToStdList(const StrList &strList)
+ { return strListToStdList(strList); }
+ virtual std::list<Str> strListToStdList(const StrList &strList )
+ { return strList; }
+
+ void setMargins(int left, int top, int right, int bottom)
+ {
+ m_left = left;
+ m_top = top;
+ m_right = right;
+ m_bottom = bottom;
+ }
+ virtual void getMargins(int *left, int *top, int *right, int *bottom) const;
+ void callGetMargins(int *left, int *top, int *right, int *bottom) const
+ {
+ getMargins(left, top, right, bottom);
+ }
+
+ virtual int recursionOnModifiedVirtual(Str arg) const;
+ int callRecursionOnModifiedVirtual(Str arg) const { return recursionOnModifiedVirtual(arg); }
+
+ virtual const Str &returnConstRef() const;
+
+ virtual int stringViewLength(std::string_view in) const;
+
+protected:
+ // PYSIDE-1388: Protected hack with final classes (see VirtualFinalDaughter).
+ void protectedMethod() {}
+
+private:
+ Str m_name;
+ int m_left = 0;
+ int m_top = 0;
+ int m_right = 0;
+ int m_bottom = 0;
+};
+
+class LIBSAMPLE_API VirtualDaughter : public VirtualMethods
+{
+public:
+ VirtualDaughter() : VirtualMethods() {}
+ VirtualDaughter(Str name) : VirtualMethods(name) {}
+};
+
+class LIBSAMPLE_API VirtualDaughter2 : public VirtualMethods
+{
+public:
+ VirtualDaughter2() : VirtualMethods("VirtualDaughter2") {}
+
+ double virtualMethod0(Point pt, int val, Complex cpx, bool b) override;
+ int sum0(int a0, int a1, int a2) final;
+};
+
+class LIBSAMPLE_API VirtualFinalDaughter final : public VirtualMethods
+{
+public:
+ VirtualFinalDaughter() : VirtualMethods("VirtualFinalDaughter") {}
+
+ double virtualMethod0(Point pt, int val, Complex cpx, bool b) override;
+ int sum0(int a0, int a1, int a2) override;
+};
+
+class LIBSAMPLE_API VirtualDtor
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(VirtualDtor)
+
+ VirtualDtor() noexcept = default;
+ virtual ~VirtualDtor() { dtor_called++; }
+
+ static VirtualDtor *create() { return new VirtualDtor(); }
+ static int dtorCalled() { return dtor_called; }
+ static void resetDtorCounter() { dtor_called = 0; }
+
+private:
+ static int dtor_called;
+};
+
+#endif // VIRTUALMETHODS_H
diff --git a/sources/shiboken6/tests/libsample/voidholder.h b/sources/shiboken6/tests/libsample/voidholder.h
new file mode 100644
index 000000000..3f0f4d973
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/voidholder.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef VOIDHOLDER_H
+#define VOIDHOLDER_H
+
+#include "libsamplemacros.h"
+
+class VoidHolder
+{
+public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(VoidHolder)
+
+ explicit VoidHolder(void *ptr = nullptr) noexcept : m_ptr(ptr) {}
+ ~VoidHolder() = default;
+
+ inline void *voidPointer() { return m_ptr; }
+ inline static void *gimmeMeSomeVoidPointer()
+ {
+ static void *pointerToSomething = new VoidHolder();
+ return pointerToSomething;
+ }
+ void *takeVoidPointer(void *item)
+ {
+ return item;
+ }
+
+private:
+ void *m_ptr;
+};
+
+#endif // VOIDHOLDER_H
diff --git a/sources/shiboken6/tests/libsmart/CMakeLists.txt b/sources/shiboken6/tests/libsmart/CMakeLists.txt
new file mode 100644
index 000000000..95f0cffd6
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(libsmart)
+
+set(libsmart_SRC
+libsmartmacros.h
+smart.cpp smart.h
+smart_integer.h
+smart_obj.h
+smart_registry.h
+smart_sharedptr.h
+smart_test.h
+stdoptionaltestbench.cpp stdoptionaltestbench.h
+stdsharedptrtestbench.cpp stdsharedptrtestbench.h
+stduniqueptrtestbench.cpp stduniqueptrtestbench.h
+)
+
+add_library(libsmart SHARED ${libsmart_SRC})
+target_include_directories(libsmart PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_compile_definitions(libsmart PRIVATE LIBSMART_BUILD)
+set_property(TARGET libsmart PROPERTY PREFIX "")
+
diff --git a/sources/shiboken6/tests/libsmart/libsmartmacros.h b/sources/shiboken6/tests/libsmart/libsmartmacros.h
new file mode 100644
index 000000000..c1f229b6c
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/libsmartmacros.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef LIB_SMART_MACROS_H
+#define LIB_SMART_MACROS_H
+
+#include "../libminimal/libminimalmacros.h"
+
+#define LIB_SMART_EXPORT LIBMINIMAL_EXPORT
+#define LIB_SMART_IMPORT LIBMINIMAL_IMPORT
+
+#ifdef LIBSMART_BUILD
+# define LIB_SMART_API LIB_SMART_EXPORT
+#else
+# define LIB_SMART_API LIB_SMART_IMPORT
+#endif
+
+#endif // LIB_SMART_MACROS_H
diff --git a/sources/shiboken6/tests/libsmart/smart.cpp b/sources/shiboken6/tests/libsmart/smart.cpp
new file mode 100644
index 000000000..2273040f9
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart.cpp
@@ -0,0 +1,272 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "smart.h"
+
+#include <algorithm>
+#include <iostream>
+
+static inline bool verbose()
+{
+ return Registry::getInstance()->verbose();
+}
+
+void SharedPtrBase::logDefaultConstructor(const char *instantiation, const void *t)
+{
+ if (verbose())
+ std::cout << "SharedPtr<" << instantiation << "> default constructor " << t << '\n';
+}
+
+void SharedPtrBase::logConstructor(const char *instantiation, const void *t,
+ const void *pointee)
+{
+ if (verbose()) {
+ std::cout << "SharedPtr<" << instantiation << "> constructor "
+ << t << " with pointer " << pointee << '\n';
+ }
+}
+
+void SharedPtrBase::logCopyConstructor(const char *instantiation, const void *t,
+ const void *refData)
+{
+ if (verbose()) {
+ std::cout << "SharedPtr<" << instantiation << ">) copy constructor "
+ << t << " with pointer " << refData << '\n';
+ }
+}
+
+void SharedPtrBase::logAssignment(const char *instantiation, const void *t, const void *refData)
+{
+ if (verbose()) {
+ std::cout << "SharedPtr<" << instantiation << ">::operator= " << t
+ << " with pointer " << refData << "\n";
+ }
+}
+
+void SharedPtrBase::logDestructor(const char *instantiation, const void *t,
+ int remainingRefCount)
+{
+ if (verbose()) {
+ std::cout << "~SharedPtr<" << instantiation << "> " << t << ", remaining refcount "
+ << remainingRefCount << '\n';
+ }
+}
+
+Obj::Obj() : m_integer(123), m_internalInteger(new Integer)
+{
+ Registry::getInstance()->add(this);
+ if (verbose())
+ std::cout << "Obj constructor " << this << '\n';
+}
+
+Obj::~Obj()
+{
+ Registry::getInstance()->remove(this);
+ delete m_internalInteger;
+ if (verbose())
+ std::cout << "~Obj " << this << '\n';
+}
+
+
+void Obj::printObj() {
+ if (verbose()) {
+ std::cout << "Obj::printObj(): integer value: " << m_integer
+ << " internal integer value: " << m_internalInteger->value() << '\n';
+ }
+}
+
+
+SharedPtr<Obj> Obj::createSharedPtrObj()
+{
+ SharedPtr<Obj> o(new Obj);
+ return o;
+}
+
+std::vector<SharedPtr<Obj> > Obj::createSharedPtrObjList(int size)
+{
+ std::vector<SharedPtr<Obj> > r;
+ for (int i=0; i < size; i++)
+ r.push_back(createSharedPtrObj());
+ return r;
+}
+
+
+SharedPtr<Integer> Obj::createSharedPtrInteger()
+{
+ SharedPtr<Integer> o(new Integer);
+ return o;
+}
+
+SharedPtr<Smart::Integer2> Obj::createSharedPtrInteger2()
+{
+ SharedPtr<Smart::Integer2> o(new Smart::Integer2);
+ return o;
+}
+
+int Obj::takeSharedPtrToObj(SharedPtr<Obj> pObj)
+{
+ pObj->printObj();
+ return pObj->m_integer;
+}
+
+int Obj::takeSharedPtrToInteger(SharedPtr<Integer> pInt)
+{
+ if (pInt.isNull()) {
+ std::cout << "SharedPtr<Integer>(nullptr) passed!\n";
+ return -1;
+ }
+ pInt->printInteger();
+ return pInt->value();
+}
+
+int Obj::takeSharedPtrToIntegerByConstRef(const SharedPtr<Integer> &pInt)
+{
+ if (pInt.isNull()) {
+ std::cout << "SharedPtr<Integer>(nullptr) passed!\n";
+ return -1;
+ }
+ pInt->printInteger();
+ return pInt->value();
+}
+
+SharedPtr<Integer> Obj::createSharedPtrInteger(int value)
+{
+ auto *i = new Integer;
+ i->setValue(value);
+ return SharedPtr<Integer>(i);
+}
+
+SharedPtr<Integer> Obj::createNullSharedPtrInteger()
+{
+ return {};
+}
+
+SharedPtr<const Integer> Obj::createSharedPtrConstInteger()
+{
+ SharedPtr<const Integer> co(new Integer);
+ return co;
+}
+
+int Obj::takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt)
+{
+ return pInt->m_int;
+}
+
+Integer Obj::takeInteger(Integer val)
+{
+ return val;
+}
+
+Integer::Integer() : m_int(456)
+{
+ Registry::getInstance()->add(this);
+ if (verbose())
+ std::cout << "Integer constructor " << this << '\n';
+}
+
+Integer::Integer(const Integer &other)
+{
+ Registry::getInstance()->add(this);
+ if (verbose())
+ std::cout << "Integer copy constructor " << this << '\n';
+ m_int = other.m_int;
+}
+
+Integer &Integer::operator=(const Integer &other)
+{
+ Registry::getInstance()->add(this);
+ if (verbose())
+ std::cout << "Integer operator= " << this << '\n';
+ m_int = other.m_int;
+ return *this;
+}
+
+Integer::~Integer()
+{
+ Registry::getInstance()->remove(this);
+ if (verbose())
+ std::cout << "~Integer " << this << " (" << m_int << ")\n";
+}
+
+int Integer::value() const
+{
+ return m_int;
+}
+
+void Integer::setValue(int v)
+{
+ m_int = v;
+ if (verbose())
+ std::cout << "Integer::setValue(" << v << ") " << this << '\n';
+}
+
+int Integer::compare(const Integer &rhs) const
+{
+ if (m_int < rhs.m_int)
+ return -1;
+ return m_int > rhs.m_int ? 1 : 0;
+}
+
+void Integer::printInteger() const
+{
+ if (verbose())
+ std::cout << "Integer value for object " << this << " is " << m_int << '\n';
+}
+
+Registry *Registry::getInstance()
+{
+ static Registry registry;
+ return &registry;
+}
+
+Registry::Registry() = default;
+
+Registry::~Registry() = default;
+
+void Registry::add(Obj *p)
+{
+ m_objects.push_back(p);
+}
+
+void Registry::add(Integer *p)
+{
+ m_integers.push_back(p);
+}
+
+void Registry::remove(Obj *p)
+{
+ m_objects.erase(std::remove(m_objects.begin(), m_objects.end(), p), m_objects.end());
+}
+
+void Registry::remove(Integer *p)
+{
+ m_integers.erase(std::remove(m_integers.begin(), m_integers.end(), p), m_integers.end());
+}
+
+int Registry::countObjects() const
+{
+ return static_cast<int>(m_objects.size());
+}
+
+int Registry::countIntegers() const
+{
+ return static_cast<int>(m_integers.size());
+}
+
+bool Registry::verbose() const
+{
+ return m_verbose;
+}
+
+void Registry::setVerbose(bool flag)
+{
+ m_verbose = flag;
+}
+
+Smart::Integer2::Integer2()
+ : Integer ()
+{
+}
+
+Smart::Integer2::Integer2(const Smart::Integer2 &) = default;
+Smart::Integer2 &Smart::Integer2::operator=(const Integer2 &) = default;
diff --git a/sources/shiboken6/tests/libsmart/smart.h b/sources/shiboken6/tests/libsmart/smart.h
new file mode 100644
index 000000000..1f610b302
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart.h
@@ -0,0 +1,16 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SMART_H
+#define SMART_H
+
+#include "smart_sharedptr.h"
+#include "smart_integer.h"
+#include "smart_obj.h"
+#include "smart_registry.h"
+#include "smart_test.h"
+#include "stdsharedptrtestbench.h"
+#include "stdoptionaltestbench.h"
+#include "stduniqueptrtestbench.h"
+
+#endif // SMART_H
diff --git a/sources/shiboken6/tests/libsmart/smart_integer.h b/sources/shiboken6/tests/libsmart/smart_integer.h
new file mode 100644
index 000000000..42a441a00
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart_integer.h
@@ -0,0 +1,69 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SMART_INTEGER_H
+#define SMART_INTEGER_H
+
+#include "libsmartmacros.h"
+
+class LIB_SMART_API Integer {
+public:
+ Integer();
+ Integer(const Integer &other);
+ Integer &operator=(const Integer &other);
+ Integer(Integer &&other) noexcept = default;
+ Integer &operator=(Integer &&other) noexcept = default;
+ ~Integer();
+ void printInteger() const;
+
+ int value() const;
+ void setValue(int v);
+
+ int compare(const Integer &rhs) const;
+
+ int m_int; // public for testing member field access.
+};
+
+inline bool operator==(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) == 0;
+}
+
+inline bool operator!=(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) != 0;
+}
+
+inline bool operator<(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) < 0;
+}
+
+inline bool operator<=(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) <= 0;
+}
+
+inline bool operator>(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) > 0;
+}
+
+inline bool operator>=(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) >= 0;
+}
+
+namespace Smart {
+class LIB_SMART_API Integer2 : public Integer {
+public:
+ Integer2();
+ Integer2(const Integer2 &);
+ Integer2 &operator=(const Integer2 &);
+ Integer2(Integer2 &&other) = delete;
+ Integer2 &operator=(Integer2 &&other) = delete;
+ ~Integer2() = default;
+};
+} // namespace Smart
+
+#endif // SMART_INTEGER_H
diff --git a/sources/shiboken6/tests/libsmart/smart_obj.h b/sources/shiboken6/tests/libsmart/smart_obj.h
new file mode 100644
index 000000000..9f4f8425d
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart_obj.h
@@ -0,0 +1,45 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SMART_OBJ_H
+#define SMART_OBJ_H
+
+#include "libsmartmacros.h"
+#include "smart_sharedptr.h"
+
+#include <vector>
+
+class Integer;
+class Obj;
+namespace Smart { class Integer2; }
+
+// Couldn't name it Object because it caused some namespace clashes.
+class LIB_SMART_API Obj {
+public:
+ Obj();
+ Obj(const Obj &other) = delete;
+ Obj &operator=(const Obj &other) = delete;
+ Obj(Obj &&other) = delete;
+ Obj &operator=(Obj &&other) = delete;
+ virtual ~Obj();
+
+ void printObj();
+ Integer takeInteger(Integer val);
+ static SharedPtr<Obj> createSharedPtrObj();
+ std::vector<SharedPtr<Obj> > createSharedPtrObjList(int size);
+ virtual SharedPtr<Integer> createSharedPtrInteger(); // virtual for PYSIDE-1188
+ SharedPtr<const Integer> createSharedPtrConstInteger();
+ int takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt);
+ SharedPtr<Smart::Integer2> createSharedPtrInteger2();
+ int takeSharedPtrToObj(SharedPtr<Obj> pObj);
+ int takeSharedPtrToInteger(SharedPtr<Integer> pInt);
+ int takeSharedPtrToIntegerByConstRef(const SharedPtr<Integer> &pInt);
+
+ static SharedPtr<Integer> createSharedPtrInteger(int value);
+ static SharedPtr<Integer> createNullSharedPtrInteger();
+
+ int m_integer; // public for testing member field access.
+ Integer *m_internalInteger;
+};
+
+#endif // SMART_OBJ_H
diff --git a/sources/shiboken6/tests/libsmart/smart_registry.h b/sources/shiboken6/tests/libsmart/smart_registry.h
new file mode 100644
index 000000000..abf7edc84
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart_registry.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SMART_REGISTRY_H
+#define SMART_REGISTRY_H
+
+#include <vector>
+
+#include "libsmartmacros.h"
+
+class Obj;
+class Integer;
+
+// Used to track which C++ objects are alive.
+class LIB_SMART_API Registry {
+public:
+ static Registry *getInstance();
+ ~Registry();
+
+ Registry(const Registry &) = delete;
+ Registry &operator=(const Registry &) = delete;
+ Registry(Registry &&) = delete;
+ Registry &operator=(Registry &&) = delete;
+
+ void add(Obj *p);
+ void add(Integer *p);
+ void remove(Obj *p);
+ void remove(Integer *p);
+ int countObjects() const;
+ int countIntegers() const;
+ bool verbose() const;
+ void setVerbose(bool flag);
+
+protected:
+ Registry();
+
+private:
+ std::vector<Obj *> m_objects;
+ std::vector<Integer *> m_integers;
+ bool m_verbose = false;
+};
+
+#endif // SMART_REGISTRY_H
diff --git a/sources/shiboken6/tests/libsmart/smart_sharedptr.h b/sources/shiboken6/tests/libsmart/smart_sharedptr.h
new file mode 100644
index 000000000..dc665810a
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart_sharedptr.h
@@ -0,0 +1,94 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SMART_SHARED_PTR_H
+#define SMART_SHARED_PTR_H
+
+#include <memory>
+
+#include "libsmartmacros.h"
+
+struct SharedPtrBase
+{
+ LIB_SMART_API static void logDefaultConstructor(const char *instantiation, const void *t);
+ LIB_SMART_API static void logConstructor(const char *instantiation, const void *t, const void *pointee);
+ LIB_SMART_API static void logCopyConstructor(const char *instantiation, const void *t, const void *refData);
+ LIB_SMART_API static void logAssignment(const char *instantiation, const void *t, const void *refData);
+ LIB_SMART_API static void logDestructor(const char *instantiation, const void *t, int remainingRefCount);
+};
+
+template <class T>
+class SharedPtr : public SharedPtrBase {
+public:
+ LIBMINIMAL_DEFAULT_MOVE(SharedPtr)
+
+ SharedPtr() { logDefaultConstructor(typeid(T).name(), this); }
+
+ SharedPtr(T *v) : mPtr(v)
+ {
+ logConstructor(typeid(T).name(), this, v);
+ }
+
+ SharedPtr(const SharedPtr<T> &other) : mPtr(other.mPtr)
+ {
+ logCopyConstructor(typeid(T).name(), this, data());
+ }
+
+ template<class X>
+ SharedPtr(const SharedPtr<X> &other) : mPtr(other.mPtr)
+ {
+ logCopyConstructor(typeid(T).name(), this, data());
+ }
+
+ SharedPtr &operator=(const SharedPtr &other)
+ {
+ if (this != &other)
+ mPtr = other.mPtr;
+ return *this;
+ }
+
+ T *data() const
+ {
+ return mPtr.get();
+ }
+
+ int useCount() const
+ {
+ return mPtr.use_count();
+ }
+
+ void dummyMethod1()
+ {
+ }
+
+ bool isNull() const
+ {
+ return mPtr.get() == nullptr;
+ }
+
+ T& operator*() const
+ {
+ // Crashes if smart pointer is empty (just like std::shared_ptr).
+ return *mPtr;
+ }
+
+ T *operator->() const
+ {
+ return mPtr.get();
+ }
+
+ bool operator!() const
+ {
+ return !mPtr;
+ }
+
+ ~SharedPtr()
+ {
+ if (mPtr.use_count() >= 1)
+ logDestructor(typeid(T).name(), this, mPtr.use_count() - 1);
+ }
+
+ std::shared_ptr<T> mPtr;
+};
+
+#endif // SMART_SHARED_PTR_H
diff --git a/sources/shiboken6/tests/libsmart/smart_test.h b/sources/shiboken6/tests/libsmart/smart_test.h
new file mode 100644
index 000000000..89d8cbc7c
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart_test.h
@@ -0,0 +1,13 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SMART_TEST_H
+#define SMART_TEST_H
+
+namespace Test {
+
+enum DummyEnum { Dummy1, Dummy2 };
+
+}
+
+#endif // SMART_TEST_H
diff --git a/sources/shiboken6/tests/libsmart/stdoptionaltestbench.cpp b/sources/shiboken6/tests/libsmart/stdoptionaltestbench.cpp
new file mode 100644
index 000000000..69100720c
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stdoptionaltestbench.cpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "stdoptionaltestbench.h"
+
+#include <iostream>
+
+std::ostream &operator<<(std::ostream &str, const Integer &i)
+{
+ str << i.value();
+ return str;
+}
+
+template <class T>
+std::ostream &operator<<(std::ostream &str, const std::optional<T> &o)
+{
+ if (o.has_value())
+ str << o.value();
+ else
+ str << "nullopt";
+ return str;
+}
+
+StdOptionalTestBench::StdOptionalTestBench() = default;
+
+std::optional<int> StdOptionalTestBench::optionalInt() const
+{
+ return m_optionalInt;
+}
+
+void StdOptionalTestBench::setOptionalInt(const std::optional<int> &i)
+{
+ std::cout << __FUNCTION__ << ' ' << i << '\n';
+ m_optionalInt = i;
+}
+
+void StdOptionalTestBench::setOptionalIntValue(int i)
+{
+ std::cout << __FUNCTION__ << ' ' << i << '\n';
+ m_optionalInt.emplace(i);
+}
+
+std::optional<Integer> StdOptionalTestBench::optionalInteger() const
+{
+ return m_optionalInteger;
+}
+
+void StdOptionalTestBench::setOptionalInteger(const std::optional<Integer> &s)
+{
+ std::cout << __FUNCTION__ << ' ' << s << '\n';
+ m_optionalInteger = s;
+}
+
+void StdOptionalTestBench::setOptionalIntegerValue(Integer &s)
+{
+ std::cout << __FUNCTION__ << ' ' << s << '\n';
+ m_optionalInteger.emplace(s);
+}
diff --git a/sources/shiboken6/tests/libsmart/stdoptionaltestbench.h b/sources/shiboken6/tests/libsmart/stdoptionaltestbench.h
new file mode 100644
index 000000000..baa709821
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stdoptionaltestbench.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OPTIONALTEST_H
+#define OPTIONALTEST_H
+
+#include "libsmartmacros.h"
+#include "smart_integer.h"
+
+#include <optional>
+
+class LIB_SMART_API StdOptionalTestBench
+{
+public:
+ StdOptionalTestBench();
+
+ std::optional<int> optionalInt() const;
+ void setOptionalInt(const std::optional<int> &i);
+ void setOptionalIntValue(int i);
+
+ std::optional<Integer> optionalInteger() const;
+ void setOptionalInteger(const std::optional<Integer> &s);
+ void setOptionalIntegerValue(Integer &s);
+
+private:
+ std::optional<int> m_optionalInt;
+ std::optional<Integer> m_optionalInteger;
+};
+
+#endif // OPTIONALTEST_H
diff --git a/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp
new file mode 100644
index 000000000..472f807f2
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp
@@ -0,0 +1,106 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "stdsharedptrtestbench.h"
+#include "smart_integer.h"
+
+#include <iostream>
+
+StdSharedPtrTestBench::StdSharedPtrTestBench() = default;
+StdSharedPtrTestBench::~StdSharedPtrTestBench() = default;
+
+std::shared_ptr<Integer> StdSharedPtrTestBench::createInteger(int v)
+{
+ auto result = std::make_shared<Integer>();
+ result->setValue(v);
+ return result;
+}
+
+std::shared_ptr<Integer> StdSharedPtrTestBench::createNullInteger()
+{
+ return {};
+}
+
+void StdSharedPtrTestBench::printInteger(const std::shared_ptr<Integer> &p)
+{
+ std::cerr << __FUNCTION__ << ' ';
+ if (p.get())
+ std::cerr << p->value();
+ else
+ std::cerr << "nullptr";
+ std::cerr << '\n';
+}
+
+std::shared_ptr<int> StdSharedPtrTestBench::createInt(int v)
+{
+ return std::make_shared<int>(v);
+}
+
+std::shared_ptr<int> StdSharedPtrTestBench::createNullInt()
+{
+ return {};
+}
+
+void StdSharedPtrTestBench::printInt(const std::shared_ptr<int> &p)
+{
+ std::cerr << __FUNCTION__ << ' ';
+ if (p.get())
+ std::cerr << *p;
+ else
+ std::cerr << "nullptr";
+ std::cerr << '\n';
+}
+
+std::shared_ptr<double> StdSharedPtrTestBench::createDouble(double v)
+{
+ return std::make_shared<double>(v);
+}
+
+std::shared_ptr<double> StdSharedPtrTestBench::createNullDouble()
+{
+ return {};
+}
+
+void StdSharedPtrTestBench::printDouble(const std::shared_ptr<double> &p)
+{
+ std::cerr << __FUNCTION__ << ' ';
+ if (p.get())
+ std::cerr << *p;
+ else
+ std::cerr << "nullptr";
+ std::cerr << '\n';
+}
+
+std::shared_ptr<std::string> StdSharedPtrTestBench::createString(const char *text)
+{
+ return std::make_shared<std::string>(text);
+}
+
+std::shared_ptr<std::string> StdSharedPtrTestBench::createNullString()
+{
+ return {};
+}
+
+void StdSharedPtrTestBench::printString(const std::shared_ptr<std::string> &p)
+{
+ std::cerr << __FUNCTION__ << ' ';
+ if (p.get())
+ std::cerr << '"' << *p << '"';
+ else
+ std::cerr << "nullptr";
+ std::cerr << '\n';
+}
+
+StdSharedPtrVirtualMethodTester::StdSharedPtrVirtualMethodTester() = default;
+StdSharedPtrVirtualMethodTester::~StdSharedPtrVirtualMethodTester() = default;
+
+std::shared_ptr<Integer> StdSharedPtrVirtualMethodTester::callModifyInteger(const std::shared_ptr<Integer> &p)
+{
+ return doModifyInteger(p);
+}
+
+std::shared_ptr<Integer> StdSharedPtrVirtualMethodTester::doModifyInteger(std::shared_ptr<Integer> p)
+{
+ p->setValue(p->value() + 1);
+ return p;
+}
diff --git a/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h
new file mode 100644
index 000000000..9d4c207b5
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef STDSHAREDPTRTESTBENCH_H
+#define STDSHAREDPTRTESTBENCH_H
+
+#include "libsmartmacros.h"
+
+#include <memory>
+#include <string>
+
+class Integer;
+
+class LIB_SMART_API StdSharedPtrTestBench
+{
+public:
+ StdSharedPtrTestBench();
+ ~StdSharedPtrTestBench();
+
+ static std::shared_ptr<Integer> createInteger(int v = 42);
+ static std::shared_ptr<Integer> createNullInteger();
+ static void printInteger(const std::shared_ptr<Integer> &);
+
+ static std::shared_ptr<int> createInt(int v = 42);
+ static std::shared_ptr<int> createNullInt();
+ static void printInt(const std::shared_ptr<int> &);
+
+ static std::shared_ptr<double> createDouble(double v = 42);
+ static std::shared_ptr<double> createNullDouble();
+ static void printDouble(const std::shared_ptr<double> &);
+
+ static std::shared_ptr<std::string> createString(const char *text);
+ static std::shared_ptr<std::string> createNullString();
+ static void printString(const std::shared_ptr<std::string> &);
+};
+
+class LIB_SMART_API StdSharedPtrVirtualMethodTester
+{
+public:
+ StdSharedPtrVirtualMethodTester();
+ virtual ~StdSharedPtrVirtualMethodTester();
+
+ std::shared_ptr<Integer> callModifyInteger(const std::shared_ptr<Integer> &p);
+
+protected:
+ virtual std::shared_ptr<Integer> doModifyInteger(std::shared_ptr<Integer> p);
+};
+
+#endif // STDSHAREDPTRTESTBENCH_H
diff --git a/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.cpp b/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.cpp
new file mode 100644
index 000000000..df4b566fa
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.cpp
@@ -0,0 +1,133 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "stduniqueptrtestbench.h"
+#include "smart_integer.h"
+
+#include <iostream>
+
+std::ostream &operator<<(std::ostream &str, const std::unique_ptr<Integer> &p)
+{
+ str << "unique_ptr<Integer>(";
+ if (p.get())
+ str << p->value();
+ else
+ str << "nullptr";
+ str << ')';
+ return str;
+}
+
+std::ostream &operator<<(std::ostream &str, const std::unique_ptr<Smart::Integer2> &p)
+{
+ str << "unique_ptr<Integer>(";
+ if (p.get())
+ str << p->value();
+ else
+ str << "nullptr";
+ str << ')';
+ return str;
+}
+
+std::ostream &operator<<(std::ostream &str, const std::unique_ptr<int> &p)
+{
+ str << "unique_ptr<int>(";
+ if (p.get())
+ str << *p;
+ else
+ str << "nullptr";
+ str << ')';
+ return str;
+}
+
+StdUniquePtrTestBench::StdUniquePtrTestBench() = default;
+StdUniquePtrTestBench::~StdUniquePtrTestBench() = default;
+
+std::unique_ptr<Integer> StdUniquePtrTestBench::createInteger(int v)
+{
+ auto result = std::make_unique<Integer>();
+ result->setValue(v);
+ return result;
+}
+
+std::unique_ptr<Integer> StdUniquePtrTestBench::createNullInteger()
+{
+ return {};
+}
+
+void StdUniquePtrTestBench::printInteger(const std::unique_ptr<Integer> &p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
+
+void StdUniquePtrTestBench::takeInteger(std::unique_ptr<Integer> p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
+
+std::unique_ptr<int> StdUniquePtrTestBench::createInt(int v)
+{
+ return std::make_unique<int>(v);
+}
+
+std::unique_ptr<int> StdUniquePtrTestBench::createNullInt()
+{
+ return {};
+}
+
+void StdUniquePtrTestBench::printInt(const std::unique_ptr<int> &p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
+
+void StdUniquePtrTestBench::takeInt(std::unique_ptr<int> p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
+
+StdUniquePtrVirtualMethodTester::StdUniquePtrVirtualMethodTester() = default;
+
+StdUniquePtrVirtualMethodTester::~StdUniquePtrVirtualMethodTester() = default;
+
+bool StdUniquePtrVirtualMethodTester::testModifyIntegerByRef(int value, int expectedValue)
+{
+ auto p = std::make_unique<Integer>();
+ p->setValue(value);
+ const int actualValue = doModifyIntegerByRef(p);
+ return p.get() != nullptr && actualValue == expectedValue;
+}
+
+bool StdUniquePtrVirtualMethodTester::testModifyIntegerValue(int value, int expectedValue)
+{
+ auto p = std::make_unique<Integer>();
+ p->setValue(value);
+ const int actualValue = doModifyIntegerByValue(std::move(p));
+ return p.get() == nullptr && actualValue == expectedValue;
+}
+
+bool StdUniquePtrVirtualMethodTester::testCreateInteger(int value, int expectedValue)
+{
+ auto p = doCreateInteger(value);
+ return p.get() != nullptr && p->value() == expectedValue;
+}
+
+std::unique_ptr<Integer> StdUniquePtrVirtualMethodTester::doCreateInteger(int v)
+{
+ auto result = std::make_unique<Integer>();
+ result->setValue(v);
+ return result;
+}
+
+int StdUniquePtrVirtualMethodTester::doModifyIntegerByRef(const std::unique_ptr<Integer> &p)
+{
+ return p->value() + 1;
+}
+
+int StdUniquePtrVirtualMethodTester::doModifyIntegerByValue(std::unique_ptr<Integer> p)
+{
+ return p->value() + 1;
+}
+
+void StdUniquePtrTestBench::printInteger2(const std::unique_ptr<Smart::Integer2> &p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
diff --git a/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.h b/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.h
new file mode 100644
index 000000000..868c6d08c
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef STDUNIQUEPTRTESTBENCH_H
+#define STDUNIQUEPTRTESTBENCH_H
+
+#include "libsmartmacros.h"
+
+#include <memory>
+
+class Integer;
+namespace Smart {
+class Integer2;
+}
+
+class LIB_SMART_API StdUniquePtrTestBench
+{
+public:
+ StdUniquePtrTestBench();
+ ~StdUniquePtrTestBench();
+
+ static std::unique_ptr<Integer> createInteger(int v = 42);
+ static std::unique_ptr<Integer> createNullInteger();
+ static void printInteger2(const std::unique_ptr<Smart::Integer2> &p);
+ static void printInteger(const std::unique_ptr<Integer> &p);
+ static void takeInteger(std::unique_ptr<Integer> p); // Call with std::move()
+
+ static std::unique_ptr<int> createInt(int v = 42);
+ static std::unique_ptr<int> createNullInt();
+ static void printInt(const std::unique_ptr<int> &p);
+ static void takeInt(std::unique_ptr<int> p); // Call with std::move()
+};
+
+class LIB_SMART_API StdUniquePtrVirtualMethodTester
+{
+public:
+ StdUniquePtrVirtualMethodTester();
+ virtual ~StdUniquePtrVirtualMethodTester();
+
+ bool testModifyIntegerByRef(int value, int expectedValue);
+ bool testModifyIntegerValue(int value, int expectedValue);
+ bool testCreateInteger(int value, int expectedValue);
+
+protected:
+ virtual std::unique_ptr<Integer> doCreateInteger(int v);
+ virtual int doModifyIntegerByRef(const std::unique_ptr<Integer> &p);
+ virtual int doModifyIntegerByValue(std::unique_ptr<Integer> p);
+};
+
+#endif // STDUNIQUEPTRTESTBENCH_H
diff --git a/sources/shiboken6/tests/minimalbinding/CMakeLists.txt b/sources/shiboken6/tests/minimalbinding/CMakeLists.txt
new file mode 100644
index 000000000..7f132bd34
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(minimal)
+
+set(minimal_TYPESYSTEM
+${CMAKE_CURRENT_SOURCE_DIR}/typesystem_minimal.xml
+)
+
+set(minimal_SRC
+${CMAKE_CURRENT_BINARY_DIR}/minimal/minimal_module_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/minimal/containeruser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/minimal/obj_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/minimal/val_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/minimal/listuser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/minimal/spanuser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/minimal/minbooluser_wrapper.cpp
+)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/minimal-binding.txt.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/minimal-binding.txt" @ONLY)
+
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${minimal_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --project-file=${CMAKE_CURRENT_BINARY_DIR}/minimal-binding.txt
+ ${GENERATOR_EXTRA_FLAGS}
+ DEPENDS ${minimal_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for 'minimal' test binding..."
+)
+
+add_library(minimal MODULE ${minimal_SRC})
+target_include_directories(minimal PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(minimal PUBLIC libminimal libshiboken)
+set_property(TARGET minimal PROPERTY PREFIX "")
+set_property(TARGET minimal PROPERTY OUTPUT_NAME "minimal${PYTHON_EXTENSION_SUFFIX}")
+if(WIN32)
+ set_property(TARGET minimal PROPERTY SUFFIX ".pyd")
+endif()
+
+create_generator_target(minimal)
diff --git a/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py b/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py
new file mode 100644
index 000000000..946a869db
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py
@@ -0,0 +1,87 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import os
+import re
+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 shiboken6 import Shiboken # noqa: F401
+
+from shibokensupport.signature.lib.tool import build_brace_pattern
+
+"""
+This test tests the brace pattern from signature.lib.tool
+against a slower reference implementation.
+The pattern is crucial, because it is used heavily in signature.parser .
+"""
+
+
+def check(s):
+ """A slow reference parser for braces and strings"""
+ open, close = "[{(<", "]})>"
+ escape, quote = "\\", '"'
+ instring = blind = False
+ stack = []
+ for c in s:
+ if instring:
+ if blind:
+ blind = False
+ elif c == escape:
+ blind = True
+ elif c == quote:
+ instring = False
+ stack.pop()
+ continue
+ if c in open:
+ stack.append(c)
+ elif c in close:
+ pos = close.index(c)
+ if len(stack) > 0 and open[pos] == stack[len(stack) - 1]:
+ stack.pop()
+ else:
+ return False
+ elif c == escape:
+ return False
+ elif c == quote:
+ instring = True
+ stack.append(c)
+ return len(stack) == 0
+
+
+class TestBracePattern(unittest.TestCase):
+ tests = [
+ (r'{[]{()}}', True),
+ (r'[{}{})(]', False),
+ (r'[{}{} ")(" ]', True),
+ (r'[{}{} ")(\" ]', False),
+ (r'[{}{} ")(\" ]"]', True),
+ (r'a < b ( c [ d { "} \"\"}" } ] ) >', True),
+ (r'a < b ( c [ d { } ] ) >', True),
+ (r'a < b ( c [ d { "huh" } ] ) >', True),
+ (r'a < b ( c [ d { "huh\" \" \\\"" } ] ) >', True),
+ ]
+
+ def test_checkfunc(self):
+ for test, result in self.tests:
+ if result:
+ self.assertTrue(check(test))
+ else:
+ self.assertFalse(check(test))
+
+ def test_the_brace_pattern(self):
+ func = re.compile(build_brace_pattern(5, ",") + "$", re.VERBOSE).match
+ for test, result in self.tests:
+ if result:
+ self.assertTrue(func(test))
+ else:
+ self.assertFalse(func(test))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/containeruser_test.py b/sources/shiboken6/tests/minimalbinding/containeruser_test.py
new file mode 100644
index 000000000..25d683957
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/containeruser_test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# Copyright (C) 2023 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 minimal import ContainerUser
+
+
+class ContainerTest(unittest.TestCase):
+ """Simple test for converting std::vector and using an opaque container.
+ For advanced tests, see ListUser."""
+ def testVectorConversion(self):
+ v = ContainerUser.createIntVector(4)
+ self.assertEqual(ContainerUser.sumIntVector(v), 6)
+
+ def testVectorOpaqueContainer(self):
+ cu = ContainerUser()
+ oc = cu.intVector()
+ self.assertEqual(oc[0], 1)
+ oc[0] = 42
+ self.assertEqual(cu.intVector()[0], 42)
+
+ def testArrayConversion(self):
+ v = ContainerUser.createIntArray()
+ self.assertEqual(ContainerUser.sumIntArray(v), 6)
+
+ def testArrayOpaqueContainer(self):
+ cu = ContainerUser()
+ oc = cu.intArray()
+ self.assertEqual(oc[0], 1)
+ oc[0] = 42
+ self.assertEqual(cu.intArray()[0], 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/global.h b/sources/shiboken6/tests/minimalbinding/global.h
new file mode 100644
index 000000000..fc5c59a26
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/global.h
@@ -0,0 +1,10 @@
+// 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 "obj.h"
+#include "containeruser.h"
+#include "val.h"
+#include "minbool.h"
+#include "listuser.h"
+#include "spanuser.h"
+#include "typedef.h"
diff --git a/sources/shiboken6/tests/minimalbinding/listuser_test.py b/sources/shiboken6/tests/minimalbinding/listuser_test.py
new file mode 100644
index 000000000..b30bb653a
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/listuser_test.py
@@ -0,0 +1,376 @@
+#!/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 functools import reduce
+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 minimal import ListUser, Val, Obj, StdIntList
+
+
+class ExtListUser(ListUser):
+ def __init__(self):
+ super().__init__()
+ self._stdIntList = StdIntList()
+ self._stdIntList.append(1)
+ self._stdIntList.append(2)
+
+ def createIntList(self, num):
+ return list(range(0, num * 2, 2))
+
+ def sumIntList(self, intList):
+ return sum(intList) * 2
+
+ def createMinBoolList(self, mb1, mb2):
+ return [not mb1, not mb2]
+
+ def oredMinBoolList(self, minBoolList):
+ return not reduce(lambda a, b: a | b, minBoolList)
+
+ def createValList(self, num):
+ return [Val(i) for i in range(0, num * 2, 2)]
+
+ def sumValList(self, valList):
+ return sum([val.valId() for val in valList]) * 2
+
+ def createObjList(self, o1, o2):
+ o1.setObjId(o1.objId() * 2)
+ o2.setObjId(o2.objId() * 2)
+ return [o1, o2]
+
+ def sumObjList(self, objList):
+ return sum([obj.objId() for obj in objList]) * 2
+
+ def createListOfIntLists(self, num):
+ return [self.createIntList(num)] * 4
+
+ def sumListOfIntLists(self, intListList):
+ return sum([sum(line) for line in intListList]) * 2
+
+ def returnIntListByPtr(self):
+ return self._stdIntList
+
+
+class IntListConversionTest(unittest.TestCase):
+
+ def testCreateIntList(self):
+ num = 4
+ lu = ListUser()
+ lst = lu.createIntList(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), int)
+ self.assertEqual(lst, list(range(num)))
+ lst = lu.callCreateIntList(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), int)
+ self.assertEqual(lst, list(range(num)))
+
+ def testCreateIntListFromExtendedClass(self):
+ lu = ExtListUser()
+ num = 4
+ lst = lu.createIntList(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), int)
+ self.assertEqual(lst, list(range(0, num * 2, 2)))
+ lst = lu.callCreateIntList(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), int)
+ self.assertEqual(lst, list(range(0, num * 2, 2)))
+
+ def testSumIntList(self):
+ lu = ListUser()
+ lst = range(4)
+ expected = sum(lst)
+ self.assertEqual(lu.sumIntList(lst), expected)
+ self.assertEqual(lu.callSumIntList(lst), expected)
+ self.assertEqual(lu.sumIntListDefaultParam(lst), expected)
+ self.assertEqual(lu.sumIntListDefaultParamConstRef(lst), expected)
+ # PYSIDE-2454: Check container default parameters (1,2,3)
+ self.assertEqual(lu.sumIntListDefaultParam(), 6)
+ self.assertEqual(lu.sumIntListDefaultParamConstRef(), 6)
+
+ def testSumIntListFromExtendedClass(self):
+ lu = ExtListUser()
+ lst = range(4)
+ self.assertEqual(lu.sumIntList(lst), sum(lst) * 2)
+ self.assertEqual(lu.callSumIntList(lst), sum(lst) * 2)
+
+
+class MinBoolListConversionTest(unittest.TestCase):
+
+ def testCreateMinBoolList(self):
+ lu = ListUser()
+ lst = lu.createMinBoolList(True, False)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), 2)
+ for i in lst:
+ self.assertEqual(type(i), bool)
+ self.assertEqual(lst, [True, False])
+
+ lst = lu.callCreateMinBoolList(False, True)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), 2)
+ for i in lst:
+ self.assertEqual(type(i), bool)
+ self.assertEqual(lst, [False, True])
+
+ def testCreateMinBoolListFromExtendedClass(self):
+ lu = ExtListUser()
+ lst = lu.createMinBoolList(True, False)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), 2)
+ for i in lst:
+ self.assertEqual(type(i), bool)
+ self.assertEqual(lst, [False, True])
+
+ lst = lu.callCreateMinBoolList(False, True)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), 2)
+ for i in lst:
+ self.assertEqual(type(i), bool)
+ self.assertEqual(lst, [True, False])
+
+ def testOredMinBoolList(self):
+ lu = ListUser()
+ lst = [False, False, True]
+ self.assertTrue(lu.oredMinBoolList(lst))
+ self.assertTrue(lu.callOredMinBoolList(lst))
+ lst = [False, False, False]
+ self.assertFalse(lu.oredMinBoolList(lst))
+ self.assertFalse(lu.callOredMinBoolList(lst))
+
+ def testOredMinBoolListFromExtendedClass(self):
+ lu = ExtListUser()
+ lst = [False, False, True]
+ self.assertFalse(lu.oredMinBoolList(lst))
+ self.assertFalse(lu.callOredMinBoolList(lst))
+ lst = [False, False, False]
+ self.assertTrue(lu.oredMinBoolList(lst))
+ self.assertTrue(lu.callOredMinBoolList(lst))
+
+
+class ValListConversionTest(unittest.TestCase):
+
+ def testCreateValList(self):
+ num = 4
+ lu = ListUser()
+ lst = lu.createValList(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), Val)
+ self.assertEqual([val.valId() for val in lst], list(range(num)))
+ lst = lu.callCreateValList(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), Val)
+ self.assertEqual([val.valId() for val in lst], list(range(num)))
+
+ def testCreateValListFromExtendedClass(self):
+ lu = ExtListUser()
+ num = 4
+ lst = lu.createValList(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), Val)
+ self.assertEqual([val.valId() for val in lst], list(range(0, num * 2, 2)))
+ lst = lu.callCreateValList(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), Val)
+ self.assertEqual([val.valId() for val in lst], list(range(0, num * 2, 2)))
+
+ def testSumValList(self):
+ lu = ListUser()
+ lst = [Val(i) for i in range(4)]
+ self.assertEqual(lu.sumValList(lst), sum([val.valId() for val in lst]))
+ self.assertEqual(lu.callSumValList(lst), sum([val.valId() for val in lst]))
+
+ def testSumValListFromExtendedClass(self):
+ lu = ExtListUser()
+ lst = [Val(i) for i in range(4)]
+ self.assertEqual(lu.sumValList(lst), sum([val.valId() for val in lst]) * 2)
+ self.assertEqual(lu.callSumValList(lst), sum([val.valId() for val in lst]) * 2)
+
+
+class ObjListConversionTest(unittest.TestCase):
+
+ def testCreateObjList(self):
+ o1 = Obj(1)
+ o2 = Obj(2)
+ lu = ListUser()
+ lst = lu.createObjList(o1, o2)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), 2)
+ for i in lst:
+ self.assertEqual(type(i), Obj)
+ self.assertEqual(lst, [o1, o2])
+ self.assertEqual([obj.objId() for obj in lst], [1, 2])
+
+ lst = lu.callCreateObjList(o1, o2)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), 2)
+ for i in lst:
+ self.assertEqual(type(i), Obj)
+ self.assertEqual(lst, [o1, o2])
+ self.assertEqual([obj.objId() for obj in lst], [1, 2])
+
+ def testCreateObjListFromExtendedClass(self):
+ o1 = Obj(1)
+ o2 = Obj(2)
+ lu = ExtListUser()
+ lst = lu.createObjList(o1, o2)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), 2)
+ for i in lst:
+ self.assertEqual(type(i), Obj)
+ self.assertEqual(lst, [o1, o2])
+ self.assertEqual([obj.objId() for obj in lst], [2, 4])
+
+ lst = lu.callCreateObjList(o1, o2)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), 2)
+ for i in lst:
+ self.assertEqual(type(i), Obj)
+ self.assertEqual(lst, [o1, o2])
+ self.assertEqual([obj.objId() for obj in lst], [4, 8])
+
+ def testSumObjList(self):
+ lu = ListUser()
+ lst = [Obj(i) for i in list(range(4))]
+ self.assertEqual(lu.sumObjList(lst), sum([obj.objId() for obj in lst]))
+ self.assertEqual(lu.callSumObjList(lst), sum([obj.objId() for obj in lst]))
+
+ def testSumObjListFromExtendedClass(self):
+ lu = ExtListUser()
+ lst = [Obj(i) for i in list(range(4))]
+ self.assertEqual(lu.sumObjList(lst), sum([obj.objId() for obj in lst]) * 2)
+ self.assertEqual(lu.callSumObjList(lst), sum([obj.objId() for obj in lst]) * 2)
+
+
+class ListOfIntListConversionTest(unittest.TestCase):
+
+ def testCreateListOfIntLists(self):
+ num = 4
+ lu = ListUser()
+ lst = lu.createListOfIntLists(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), list)
+ self.assertEqual(i, list(range(num)))
+ for j in i:
+ self.assertEqual(type(j), int)
+ self.assertEqual(lst, [list(range(num))] * 4)
+
+ def testCreateListOfIntListsFromExtendedClass(self):
+ num = 4
+ lu = ExtListUser()
+ lst = lu.createListOfIntLists(num)
+ self.assertEqual(type(lst), list)
+ self.assertEqual(len(lst), num)
+ for i in lst:
+ self.assertEqual(type(i), list)
+ self.assertEqual(i, list(range(0, num * 2, 2)))
+ for j in i:
+ self.assertEqual(type(j), int)
+ self.assertEqual(lst, [list(range(0, num * 2, 2))] * 4)
+
+ def testSumListIntLists(self):
+ lu = ListUser()
+ lst = [range(4)] * 4
+ self.assertEqual(lu.sumListOfIntLists(lst), sum([sum(line) for line in [range(4)] * 4]))
+ self.assertEqual(lu.callSumListOfIntLists(lst), sum([sum(line) for line in [range(4)] * 4]))
+
+ def testSumListOfIntListsFromExtendedClass(self):
+ lu = ExtListUser()
+ lst = [range(4)] * 4
+ self.assertEqual(lu.sumListOfIntLists(lst),
+ sum([sum(line) for line in [range(4)] * 4]) * 2)
+ self.assertEqual(lu.callSumListOfIntLists(lst),
+ sum([sum(line) for line in [range(4)] * 4]) * 2)
+
+ def testOpaqueContainer(self):
+ lu = ListUser()
+
+ # Set via Python
+ python_list = [1, 2]
+ lu.setStdIntList(python_list)
+ self.assertEqual(len(lu.m_stdIntList), 2)
+ self.assertEqual(lu.m_stdIntList[0], 1)
+ self.assertEqual(lu.m_stdIntList[1], 2)
+
+ # Set via C++
+ cpp_list = StdIntList()
+ cpp_list.append(3)
+ cpp_list.append(4)
+ lu.setStdIntList(cpp_list)
+ self.assertEqual(len(lu.m_stdIntList), 2)
+ self.assertEqual(lu.m_stdIntList[0], 3)
+ self.assertEqual(lu.m_stdIntList[1], 4)
+
+ # Access field directly via reference
+ lu.m_stdIntList.append(5)
+ self.assertEqual(len(lu.m_stdIntList), 3)
+ self.assertEqual(lu.m_stdIntList[2], 5)
+
+ # Access list via getter
+ il = lu.getIntList()
+ il.append(6)
+ self.assertEqual(len(lu.m_stdIntList), 4)
+ self.assertEqual(lu.m_stdIntList[3], 6)
+
+ # Access a const list via getter and verify that it cannot be modified
+ const_l = lu.getConstIntList()
+ self.assertEqual(len(const_l), 4)
+ self.assertRaises(TypeError, const_l.append, 6)
+
+ def testListByPtrOpaque(self):
+ """Test a function taking C++ list by pointer for which an opaque
+ container exists."""
+ lu = ListUser()
+ python_list = [1, 2]
+ self.assertEqual(lu.modifyIntListPtr(python_list), 2)
+
+ # Pass an opaque container and verify whether it is modified by C++
+ cpp_list = StdIntList()
+ cpp_list.append(1)
+ cpp_list.append(2)
+ self.assertEqual(lu.modifyIntListPtr(cpp_list), 2)
+ self.assertEqual(len(cpp_list), 3)
+
+ def testListByPtr(self):
+ """Test a function taking C++ list by pointer for which no opaque
+ container exists."""
+ lu = ListUser()
+ python_list = [1.1, 22.2]
+ self.assertEqual(lu.modifyDoubleListPtr(python_list), 2)
+
+ def testReturnListByPtr(self):
+ """Test that a virtual function returning a list by pointer can be
+ reimplemented by a Python function returning an opaque container."""
+ lu = ExtListUser()
+ size = lu.callReturnIntListByPtr() # Call virtual from C++
+ self.assertEqual(size, 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/minbool_test.py b/sources/shiboken6/tests/minimalbinding/minbool_test.py
new file mode 100644
index 000000000..d9ce0eac0
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/minbool_test.py
@@ -0,0 +1,46 @@
+#!/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 minimal import MinBoolUser
+
+
+class DerivedMinBoolUser (MinBoolUser):
+ def returnMyselfVirtual(self):
+ return MinBoolUser()
+
+
+class MinBoolTest(unittest.TestCase):
+
+ def testMinBoolUser(self):
+ mbuTrue = MinBoolUser()
+ mbuFalse = MinBoolUser()
+ mbuTrue.setMinBool(True)
+ self.assertFalse(mbuFalse.minBool())
+ self.assertTrue(mbuTrue.minBool())
+ self.assertFalse(mbuTrue.callInvertedMinBool())
+
+ self.assertTrue(mbuTrue.minBool())
+ self.assertFalse(mbuFalse.minBool())
+ self.assertTrue(mbuTrue.minBool() != mbuFalse.minBool())
+
+ self.assertFalse(mbuFalse.minBool())
+ self.assertFalse(mbuFalse.minBool())
+ self.assertTrue(mbuTrue.minBool() != mbuFalse.minBool())
+
+ def testVirtuals(self):
+ dmbu = DerivedMinBoolUser()
+ self.assertEqual(dmbu.invertedMinBool(), True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/minimal-binding.txt.in b/sources/shiboken6/tests/minimalbinding/minimal-binding.txt.in
new file mode 100644
index 000000000..101567070
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/minimal-binding.txt.in
@@ -0,0 +1,16 @@
+[generator-project]
+
+generator-set = shiboken
+
+header-file = @CMAKE_CURRENT_SOURCE_DIR@/global.h
+typesystem-file = @minimal_TYPESYSTEM@
+
+output-directory = @CMAKE_CURRENT_BINARY_DIR@
+
+include-path = @libminimal_SOURCE_DIR@
+
+typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@
+
+enable-parent-ctor-heuristic
+use-isnull-as-nb_nonzero
+lean-headers
diff --git a/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject b/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject
new file mode 100644
index 000000000..ab19dc443
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject
@@ -0,0 +1,10 @@
+{
+ "files": ["brace_pattern_test.py",
+ "containeruser_test.py",
+ "listuser_test.py",
+ "minbool_test.py",
+ "obj_test.py",
+ "typedef_test.py",
+ "val_test.py",
+ "typesystem_minimal.xml"]
+}
diff --git a/sources/shiboken6/tests/minimalbinding/obj_test.py b/sources/shiboken6/tests/minimalbinding/obj_test.py
new file mode 100644
index 000000000..e873845de
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/obj_test.py
@@ -0,0 +1,94 @@
+#!/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 minimal import Obj
+
+
+class ExtObj(Obj):
+ def __init__(self, objId):
+ Obj.__init__(self, objId)
+ self.virtual_method_called = False
+
+ def virtualMethod(self, val):
+ self.virtual_method_called = True
+ return not Obj.virtualMethod(self, val)
+
+ def passObjectType(self, obj):
+ obj.setObjId(obj.objId() + 1)
+ return obj
+
+ def passObjectTypeReference(self, obj):
+ obj.setObjId(obj.objId() + 1)
+ return obj
+
+
+class ObjTest(unittest.TestCase):
+
+ def testNormalMethod(self):
+ objId = 123
+ obj = Obj(objId)
+ self.assertEqual(obj.objId(), objId)
+
+ def testNormalMethodFromExtendedClass(self):
+ objId = 123
+ obj = ExtObj(objId)
+ self.assertEqual(obj.objId(), objId)
+
+ def testVirtualMethod(self):
+ obj = Obj(0)
+ even_number = 8
+ self.assertEqual(obj.virtualMethod(even_number), obj.callVirtualMethod(even_number))
+
+ def testVirtualMethodFromExtendedClass(self):
+ obj = ExtObj(0)
+ even_number = 8
+ self.assertEqual(obj.virtualMethod(even_number), obj.callVirtualMethod(even_number))
+ self.assertTrue(obj.virtual_method_called)
+
+ def testPassObjectType(self):
+ obj = Obj(0)
+ self.assertEqual(obj, obj.passObjectType(obj))
+ self.assertEqual(obj, obj.callPassObjectType(obj))
+
+ def testPassObjectTypeNone(self):
+ obj = Obj(0)
+ self.assertEqual(None, obj.passObjectType(None))
+ self.assertEqual(None, obj.callPassObjectType(None))
+
+ def testPassObjectTypeReference(self):
+ obj = Obj(0)
+ self.assertEqual(obj, obj.passObjectTypeReference(obj))
+ self.assertEqual(obj, obj.callPassObjectTypeReference(obj))
+
+ def testPassObjectTypeFromExtendedClass(self):
+ obj = ExtObj(0)
+ self.assertEqual(obj.objId(), 0)
+ sameObj = obj.passObjectType(obj)
+ self.assertEqual(obj, sameObj)
+ self.assertEqual(sameObj.objId(), 1)
+ sameObj = obj.callPassObjectType(obj)
+ self.assertEqual(obj, sameObj)
+ self.assertEqual(sameObj.objId(), 2)
+
+ def testPassObjectTypeReferenceFromExtendedClass(self):
+ obj = ExtObj(0)
+ self.assertEqual(obj.objId(), 0)
+ sameObj = obj.passObjectTypeReference(obj)
+ self.assertEqual(obj, sameObj)
+ self.assertEqual(sameObj.objId(), 1)
+ sameObj = obj.callPassObjectTypeReference(obj)
+ self.assertEqual(obj, sameObj)
+ self.assertEqual(sameObj.objId(), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/spanuser_test.py b/sources/shiboken6/tests/minimalbinding/spanuser_test.py
new file mode 100644
index 000000000..6db6aa616
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/spanuser_test.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# Copyright (C) 2023 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 minimal import SpanUser
+
+
+class IntSpanTest(unittest.TestCase):
+
+ def testCreateIntSpan(self):
+ if not SpanUser.enabled():
+ return
+ expected = [1, 2, 3]
+ self.assertEqual(SpanUser.getIntSpan3(), expected)
+ self.assertEqual(SpanUser.getIntSpan(), expected)
+ self.assertEqual(SpanUser.getConstIntSpan3(), expected)
+
+ self.assertEqual(SpanUser.sumIntSpan3(expected), 6)
+ self.assertEqual(SpanUser.sumIntSpan(expected), 6)
+ self.assertEqual(SpanUser.sumConstIntSpan3(expected), 6)
+
+ def testSpanOpaqueContainer(self):
+ if not SpanUser.enabled():
+ return
+ oc = SpanUser.getIntSpan3_OpaqueContainer() # 1,2,3
+ oc[1] = 10
+ oc = SpanUser.getIntSpan3_OpaqueContainer()
+ # note: This converts to std::vector
+ self.assertEqual(SpanUser.sumIntSpan3(oc), 14)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/typedef_test.py b/sources/shiboken6/tests/minimalbinding/typedef_test.py
new file mode 100644
index 000000000..c2fc8fc12
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/typedef_test.py
@@ -0,0 +1,107 @@
+#!/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 minimal import (arrayFunc, arrayFuncInt, arrayFuncIntReturn,
+ arrayFuncIntReturnTypedef, arrayFuncIntTypedef,
+ arrayFuncReturn, arrayFuncReturnTypedef, arrayFuncTypedef)
+
+try:
+ import numpy as np
+except ImportError as e:
+ print(e)
+ np = None
+
+
+class TypedefTest(unittest.TestCase):
+
+ def setUp(self):
+ self.the_size = 8
+
+ def test_arrayFuncInt(self):
+ none = ()
+ full = range(self.the_size)
+ self.assertTrue(arrayFuncInt(none), "None is empty, arrayFuncInt should return true")
+ self.assertFalse(arrayFuncInt(full), "Full is NOT empty, arrayFuncInt should return false")
+
+ self.assertTrue(arrayFuncInt(np.array(none)),
+ "None is empty, arrayFuncInt should return true")
+ self.assertFalse(arrayFuncInt(np.array(full)),
+ "Full is NOT empty, arrayFuncInt should return false")
+
+ def test_arrayFuncIntTypedef(self):
+ none = ()
+ full = (1, 2, 3)
+ self.assertTrue(arrayFuncIntTypedef(none),
+ "None is empty, arrayFuncIntTypedef should return true")
+ self.assertFalse(arrayFuncIntTypedef(full),
+ "Full is NOT empty, arrayFuncIntTypedef should return false")
+
+ self.assertTrue(arrayFuncIntTypedef(np.array(none)),
+ "None is empty, arrayFuncIntTypedef should return true")
+ self.assertFalse(arrayFuncIntTypedef(np.array(full)),
+ "Full is NOT empty, arrayFuncIntTypedef should return false")
+
+ def test_arrayFuncIntReturn(self):
+ none = arrayFuncIntReturn(0)
+ full = arrayFuncIntReturn(self.the_size)
+ self.assertTrue((len(none) == 0), "none should be empty")
+ self.assertTrue((len(full) == self.the_size),
+ f"full should have {self.the_size} elements")
+
+ def test_arrayFuncIntReturnTypedef(self):
+ none = arrayFuncIntReturnTypedef(0)
+ full = arrayFuncIntReturnTypedef(self.the_size)
+ self.assertTrue((len(none) == 0), "none should be empty")
+ self.assertTrue((len(full) == self.the_size),
+ f"full should have {self.the_size} elements")
+
+ def test_arrayFunc(self):
+ none = ()
+ full = range(self.the_size)
+ self.assertTrue(arrayFunc(none), "None is empty, arrayFunc should return true")
+ self.assertFalse(arrayFunc(full), "Full is NOT empty, arrayFunc should return false")
+
+ self.assertTrue(arrayFunc(np.array(none)), "None is empty, arrayFunc should return true")
+ self.assertFalse(arrayFunc(np.array(full)),
+ "Full is NOT empty, arrayFunc should return false")
+
+ def test_arrayFuncTypedef(self):
+ none = ()
+ full = (1, 2, 3)
+ self.assertTrue(arrayFuncTypedef(none),
+ "None is empty, arrayFuncTypedef should return true")
+ self.assertFalse(arrayFuncTypedef(full),
+ "Full is NOT empty, arrayFuncTypedef should return false")
+
+ self.assertTrue(arrayFuncTypedef(np.array(none)),
+ "None is empty, arrayFuncTypedef should return true")
+ self.assertFalse(arrayFuncTypedef(np.array(full)),
+ "Full is NOT empty, arrayFuncTypedef should return false")
+
+ def test_arrayFuncReturn(self):
+ none = arrayFuncReturn(0)
+ full = arrayFuncReturn(self.the_size)
+ self.assertTrue((len(none) == 0), "none should be empty")
+ self.assertTrue((len(full) == self.the_size),
+ f"full should have {self.the_size} elements")
+
+ def test_arrayFuncReturnTypedef(self):
+ none = arrayFuncReturnTypedef(0)
+ full = arrayFuncReturnTypedef(self.the_size)
+ self.assertTrue((len(none) == 0), "none should be empty")
+ self.assertTrue((len(full) == self.the_size),
+ f"full should have {self.the_size} elements")
+
+
+if __name__ == '__main__':
+ if np is not None:
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml
new file mode 100644
index 000000000..e18bf8686
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<typesystem package="minimal">
+
+ <primitive-type name="MinBool" target-lang-api-name="PyBool" default-constructor="MinBool(false)">
+ <include file-name="minbool.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ return PyBool_FromLong(%in.value());
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyBool" check="PyBool_Check(%in)">
+ %out = %OUTTYPE(%in == Py_True);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <opaque-container name="std::list" opaque-containers="int:StdIntList"/>
+
+ <opaque-container name="std::vector" opaque-containers="int:StdIntVector"/>
+
+ <opaque-container name="std::array" opaque-containers="int,3:StdIntArray"/>
+
+ <?if c++20?> <!-- FIXME PYSIDE 7: Remove "if" -->
+ <opaque-container name="std::span" opaque-containers="int,3:StdIntSpan3"/>
+ <?endif?>
+
+ <object-type name="Obj"/>
+ <value-type name="Val">
+ <enum-type name="ValEnum"/>
+ </value-type>
+ <value-type name="ListUser">
+ <modify-field name="m_stdIntList" opaque-container="yes"/>
+ <modify-function signature="getIntList()">
+ <modify-argument index="return">
+ <replace-type modified-type="StdIntList"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="getConstIntList()const">
+ <modify-argument index="return">
+ <replace-type modified-type="StdIntList"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="SpanUser">
+ <?if c++20?> <!-- FIXME PYSIDE 7: Remove "if" -->
+ <modify-function signature="getIntSpan3_OpaqueContainer()">
+ <modify-argument index="return">
+ <replace-type modified-type="StdIntSpan3"/>
+ </modify-argument>
+ </modify-function>
+ <?endif?>
+ </value-type>
+
+ <value-type name="MinBoolUser"/>
+
+ <value-type name="ContainerUser">
+ <modify-function signature="intVector()">
+ <modify-argument index="return">
+ <replace-type modified-type="StdIntVector"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="intArray()">
+ <modify-argument index="return">
+ <replace-type modified-type="StdIntArray"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <!-- Test wrapping of a typedef -->
+ <function signature="arrayFuncInt(std::vector&lt;int&gt;)" />
+ <!-- Note manual expansion of the typedef -->
+ <function signature="arrayFuncIntTypedef(std::vector&lt;int&gt;)" />
+
+ <function signature="arrayFuncIntReturn(int)" />
+ <function signature="arrayFuncIntReturnTypedef(int)" />
+
+ <!-- Test wrapping of a typedef of a typedef -->
+ <function signature="arrayFunc(std::vector&lt;int&gt;)" />
+ <!-- Note manual expansion of the typedef -->
+ <function signature="arrayFuncTypedef(std::vector&lt;int&gt;)" />
+
+ <function signature="arrayFuncReturn(int)" />
+ <function signature="arrayFuncReturnTypedef(int)" />
+</typesystem>
diff --git a/sources/shiboken6/tests/minimalbinding/val_test.py b/sources/shiboken6/tests/minimalbinding/val_test.py
new file mode 100644
index 000000000..b8225a247
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/val_test.py
@@ -0,0 +1,94 @@
+#!/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 minimal import Val
+
+
+class ExtVal(Val):
+ def __init__(self, valId):
+ Val.__init__(self, valId)
+
+ def passValueType(self, val):
+ return ExtVal(val.valId() + 1)
+
+ def passValueTypePointer(self, val):
+ val.setValId(val.valId() + 1)
+ return val
+
+ def passValueTypeReference(self, val):
+ val.setValId(val.valId() + 1)
+ return val
+
+
+class ValTest(unittest.TestCase):
+
+ def testNormalMethod(self):
+ valId = 123
+ val = Val(valId)
+ self.assertEqual(val.valId(), valId)
+
+ def testPassValueType(self):
+ val = Val(123)
+ val1 = val.passValueType(val)
+ self.assertNotEqual(val, val1)
+ self.assertEqual(val1.valId(), 123)
+ val2 = val.callPassValueType(val)
+ self.assertNotEqual(val, val2)
+ self.assertEqual(val2.valId(), 123)
+
+ def testPassValueTypePointer(self):
+ val = Val(0)
+ self.assertEqual(val, val.passValueTypePointer(val))
+ self.assertEqual(val, val.callPassValueTypePointer(val))
+
+ def testPassValueTypeReference(self):
+ val = Val(0)
+ self.assertEqual(val, val.passValueTypeReference(val))
+ self.assertEqual(val, val.callPassValueTypeReference(val))
+
+ def testPassAndReceiveEnumValue(self):
+ val = Val(0)
+ self.assertEqual(val.oneOrTheOtherEnumValue(Val.One), Val.Other)
+ self.assertEqual(val.oneOrTheOtherEnumValue(Val.Other), Val.One)
+
+ def testPassValueTypeFromExtendedClass(self):
+ val = ExtVal(0)
+ val1 = val.passValueType(val)
+ self.assertNotEqual(val, val1)
+ self.assertEqual(val1.valId(), val.valId() + 1)
+ val2 = val.callPassValueType(val)
+ self.assertNotEqual(val, val2)
+ self.assertEqual(val2.valId(), val.valId() + 1)
+
+ def testPassValueTypePointerFromExtendedClass(self):
+ val = ExtVal(0)
+ self.assertEqual(val.valId(), 0)
+ sameVal = val.passValueTypePointer(val)
+ self.assertEqual(val, sameVal)
+ self.assertEqual(sameVal.valId(), 1)
+ sameVal = val.callPassValueTypePointer(val)
+ self.assertEqual(val, sameVal)
+ self.assertEqual(sameVal.valId(), 2)
+
+ def testPassValueTypeReferenceFromExtendedClass(self):
+ val = ExtVal(0)
+ self.assertEqual(val.valId(), 0)
+ sameVal = val.passValueTypeReference(val)
+ self.assertEqual(val, sameVal)
+ self.assertEqual(sameVal.valId(), 1)
+ sameVal = val.callPassValueTypeReference(val)
+ self.assertEqual(val, sameVal)
+ self.assertEqual(sameVal.valId(), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
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&lt;int,LengthUnit::Inch&gt;"/>
+ <typedef-type name="ValueWithUnitIntMillimeter" source="ValueWithUnit&lt;int,LengthUnit::Millimeter&gt;"/>
+ <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()
diff --git a/sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt b/sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt
new file mode 100644
index 000000000..11b22f038
--- /dev/null
+++ b/sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+
+# Standalone-buildable
+
+project(qtxmltosphinx)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 COMPONENTS Core)
+
+set(generator_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../generator)
+set(api_extractor_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../ApiExtractor)
+
+set(qtxmltosphinx_SRC
+ ${generator_src_dir}/qtdoc/qtxmltosphinx.cpp
+ ${api_extractor_src_dir}/codesniphelpers.cpp
+ ${api_extractor_src_dir}/textstream.cpp
+ main.cpp)
+
+add_executable(qtxmltosphinx ${qtxmltosphinx_SRC})
+
+target_include_directories(qtxmltosphinx PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${api_extractor_src_dir}
+ ${generator_src_dir}
+ ${generator_src_dir}/shiboken
+ ${generator_src_dir}/qtdoc)
+
+target_link_libraries(qtxmltosphinx PRIVATE Qt::Core)
diff --git a/sources/shiboken6/tests/qtxmltosphinx/main.cpp b/sources/shiboken6/tests/qtxmltosphinx/main.cpp
new file mode 100644
index 000000000..5b0624376
--- /dev/null
+++ b/sources/shiboken6/tests/qtxmltosphinx/main.cpp
@@ -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
+
+#include "qtxmltosphinxinterface.h"
+#include "qtxmltosphinx.h"
+
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QLoggingCategory>
+
+#include <exception>
+#include <iostream>
+
+using namespace Qt::StringLiterals;
+
+static const char help[] = R"(QtXmlToSphinx WebXML to rst converter
+
+A manual test for converting WebXML files to rst files for checking
+formatting.
+)";
+
+Q_LOGGING_CATEGORY(lcQtXmlToSphinx, "qt.xmltosphinx");
+
+static std::ostream &operator<<(std::ostream &str, const QString &s)
+{
+ str << s.toUtf8().constData();
+ return str;
+}
+
+class QtXmlToSphinxDocGenerator : public QtXmlToSphinxDocGeneratorInterface
+{
+public:
+ QtXmlToSphinxDocGenerator() = default;
+
+ QString expandFunction(const QString &) const override;
+ QString expandClass(const QString &, const QString &) const override;
+ QString resolveContextForMethod(const QString &,
+ const QString &) const override;
+ const QLoggingCategory &loggingCategory() const override;
+ QtXmlToSphinxLink resolveLink(const QtXmlToSphinxLink &link) const override;
+ Image resolveImage(const QString &href, const QString &) const;
+};
+
+// QtXmlToSphinxDocGeneratorInterface
+QString QtXmlToSphinxDocGenerator::expandFunction(const QString &) const
+{
+ return {};
+}
+
+QString QtXmlToSphinxDocGenerator::expandClass(const QString &, const QString &) const
+{
+ return {};
+}
+
+QString QtXmlToSphinxDocGenerator::resolveContextForMethod(const QString &, const QString &) const
+{
+ return {};
+}
+
+const QLoggingCategory &QtXmlToSphinxDocGenerator::loggingCategory() const
+{
+ return lcQtXmlToSphinx();
+}
+
+QtXmlToSphinxLink
+ QtXmlToSphinxDocGenerator::resolveLink(const QtXmlToSphinxLink &link) const
+{
+ return link;
+}
+
+QtXmlToSphinxDocGeneratorInterface::Image
+ QtXmlToSphinxDocGenerator::resolveImage(const QString &href, const QString &) const
+{
+ return {href, href};
+}
+
+static bool run(const QString &fileName)
+{
+ QtXmlToSphinxDocGenerator generator;
+ QtXmlToSphinxParameters parameters;
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ std::cerr << "Cannot open " << fileName << ": " << file.errorString() << '\n';
+ return false;
+ }
+ const QString xml = QString::fromUtf8(file.readAll());
+ file.close();
+ std::cout << QtXmlToSphinx(&generator, parameters, xml).result();
+ return true;
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ QCommandLineParser commandLineParser;
+ commandLineParser.setApplicationDescription(QString::fromLatin1(help));
+ commandLineParser.addHelpOption();
+ commandLineParser.addPositionalArgument(u"[file]"_s, u"WebXML file to process."_s);
+ commandLineParser.process(QCoreApplication::arguments());
+ if (commandLineParser.positionalArguments().isEmpty())
+ commandLineParser.showHelp(0); // quits
+
+ int exitCode = 1;
+ try {
+ if (run(commandLineParser.positionalArguments().constFirst()))
+ exitCode = 0;
+ } catch (const std::exception &e) {
+ std::cerr << "An exception occurred: " << e.what() << '\n';
+ }
+ return exitCode;
+}
diff --git a/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt b/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt
new file mode 100644
index 000000000..25074e716
--- /dev/null
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+
+project(qtxmltosphinxtest)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 COMPONENTS Core)
+find_package(Qt6 COMPONENTS Test)
+
+set(generator_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../generator)
+set(api_extractor_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../ApiExtractor)
+
+set(qtxmltosphinxtest_SRC
+ ${generator_src_dir}/qtdoc/qtxmltosphinx.cpp
+ ${api_extractor_src_dir}/codesniphelpers.cpp
+ ${api_extractor_src_dir}/textstream.cpp
+ qtxmltosphinxtest.cpp
+ qtxmltosphinxtest.h)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR}
+ ${api_extractor_src_dir}
+ ${generator_src_dir}
+ ${generator_src_dir}/shiboken
+ ${generator_src_dir}/qtdoc)
+
+add_executable(qtxmltosphinxtest ${qtxmltosphinxtest_SRC})
+
+target_link_libraries(qtxmltosphinxtest PRIVATE
+ Qt::Core
+ Qt::Test)
+
+add_test("qtxmltosphinx" qtxmltosphinxtest)
+if (INSTALL_TESTS)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/qtxmltosphinxtest DESTINATION ${TEST_INSTALL_DIR})
+endif()
diff --git a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
new file mode 100644
index 000000000..3ba77196f
--- /dev/null
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
@@ -0,0 +1,517 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "qtxmltosphinxtest.h"
+#include "qtxmltosphinx.h"
+#include <QtTest/QTest>
+
+#include <QtCore/QBuffer>
+#include <QtCore/QDebug>
+#include <QtCore/QLoggingCategory>
+
+using namespace Qt::StringLiterals;
+
+Q_LOGGING_CATEGORY(lcQtXmlToSphinxTest, "qt.sphinxtabletest");
+
+// QtXmlToSphinxDocGeneratorInterface
+QString QtXmlToSphinxTest::expandFunction(const QString &) const
+{
+ return {};
+}
+
+QString QtXmlToSphinxTest::expandClass(const QString &, const QString &) const
+{
+ return {};
+}
+
+QString QtXmlToSphinxTest::resolveContextForMethod(const QString &, const QString &) const
+{
+ return {};
+}
+
+const QLoggingCategory &QtXmlToSphinxTest::loggingCategory() const
+{
+ return lcQtXmlToSphinxTest();
+}
+
+QtXmlToSphinxLink QtXmlToSphinxTest::resolveLink(const QtXmlToSphinxLink &link) const
+{
+ return link;
+}
+
+QtXmlToSphinxDocGeneratorInterface::Image
+ QtXmlToSphinxTest::resolveImage(const QString &href, const QString &) const
+{
+ return {href, href};
+}
+
+QString QtXmlToSphinxTest::transformXml(const QString &xml) const
+{
+ return QtXmlToSphinx(this, m_parameters, xml).result();
+}
+
+void QtXmlToSphinxTest::testTable_data()
+{
+ QTest::addColumn<QString>("xml");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("emptyString") << QString() << QString();
+
+ // testSimpleTable
+ const char *xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ </header>
+ <row>
+ <item>
+ <para>1 1</para>
+ </item>
+ <item>
+ <para>1 2</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>2 1</para>
+ </item>
+ <item>
+ <para>2 2</para>
+ </item>
+ </row>
+</table>)";
+
+ const char *expected = R"(
+ +--------+--------+
+ |Header 1|Header 2|
+ +========+========+
+ |1 1 |1 2 |
+ +--------+--------+
+ |2 1 |2 2 |
+ +--------+--------+
+
+)";
+
+ QTest::newRow("testSimpleTable")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+
+ // testRowSpan
+ xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ </header>
+ <row>
+ <item colspan="2">
+ <para>I'm a big text!</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>2 1</para>
+ </item>
+ <item>
+ <para>2 2</para>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +---------------+--------+
+ |Header 1 |Header 2|
+ +===============+========+
+ |I'm a big text! |
+ +---------------+--------+
+ |2 1 |2 2 |
+ +---------------+--------+
+
+)";
+
+ QTest::newRow("testColSpan")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+
+ // testRowSpan
+ xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ </header>
+ <row>
+ <item rowspan="2">
+ <para>1.1</para>
+ </item>
+ <item>
+ <para>1.2</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>2 2</para>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +--------+--------+
+ |Header 1|Header 2|
+ +========+========+
+ |1.1 |1.2 |
+ + +--------+
+ | |2 2 |
+ +--------+--------+
+
+)";
+
+ QTest::newRow("testRowSpan")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+
+ // testComplexTable
+ xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ <item>
+ <para>Header 3</para>
+ </item>
+ </header>
+ <row>
+ <item rowspan="2">
+ <para>1.1</para>
+ </item>
+ <item colspan="2">
+ <para>1.2</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>2 2</para>
+ </item>
+ <item>
+ <para>2 3</para>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +--------+--------+--------+
+ |Header 1|Header 2|Header 3|
+ +========+========+========+
+ |1.1 |1.2 |
+ + +--------+--------+
+ | |2 2 |2 3 |
+ +--------+--------+--------+
+
+)";
+
+ QTest::newRow("testComplexTable")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+
+ // testRowSpan2
+ xml = R"(<table>
+ <header>
+ <item><para>h1</para></item>
+ <item><para>h2</para></item>
+ <item><para>h3</para></item>
+ <item><para>h4</para></item>
+ </header>
+ <row>
+ <item rowspan="6"><para>A</para></item>
+ <item rowspan="6"><para>B</para></item>
+ <item><para>C</para></item>
+ <item><para>D</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +--+--+--+--+
+ |h1|h2|h3|h4|
+ +==+==+==+==+
+ |A |B |C |D |
+ + + +--+--+
+ | | |E |F |
+ + + +--+--+
+ | | |E |F |
+ + + +--+--+
+ | | |E |F |
+ + + +--+--+
+ | | |E |F |
+ + + +--+--+
+ | | |E |F |
+ +--+--+--+--+
+
+)";
+
+ QTest::newRow("testRowSpan2")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+
+ // testNestedList
+ xml = R"(<table>
+ <row>
+ <item>
+ <list type="bullet">
+ <item>
+ <para>I11</para>
+ </item>
+ <item>
+ <para>I21</para>
+ </item>
+ </list>
+ </item>
+ <item>
+ <list type="bullet">
+ <item>
+ <para>I12</para>
+ </item>
+ <item>
+ <para>I22</para>
+ </item>
+ </list>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +---------+---------+
+ | * I11| * I12|
+ | * I21| * I22|
+ +---------+---------+
+
+)";
+
+ QTest::newRow("testNestedList")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+
+ // testBrokenTable
+ xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ </header>
+ <row>
+ <item>
+ <para>1.1</para>
+ </item>
+ <item>
+ <para>1.2</para>
+ </item>
+ </row>
+ <row>
+ <item colspan="2">
+ <para>2 2</para>
+ </item>
+ <item>
+ <para>2 3</para>
+ </item>
+ <item>
+ <para>2 4</para>
+ </item>
+ <item>
+ <para>2 5</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>3 1</para>
+ </item>
+ <item>
+ <para>3 2</para>
+ </item>
+ <item>
+ <para>3 3</para>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +--------+------------+
+ |Header 1|Header 2 |
+ +========+============+
+ |1.1 |1.2 |
+ +--------+------------+
+ |2 2 2 3 2 4 2 5|
+ +--------+------------+
+ |3 1 |3 2 3 3 |
+ +--------+------------+
+
+)";
+
+ QTest::newRow("testBrokenTable")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+}
+
+void QtXmlToSphinxTest::testTable()
+{
+ QFETCH(QString, xml);
+ QFETCH(QString, expected);
+
+ const QString actual = transformXml(xml);
+
+ QEXPECT_FAIL("testBrokenTable", "testBrokenTable fails", Continue);
+ QCOMPARE(actual, expected);
+}
+
+using TablePtr = std::shared_ptr<QtXmlToSphinx::Table>;
+
+Q_DECLARE_METATYPE(TablePtr);
+
+void QtXmlToSphinxTest::testTableFormatting_data()
+{
+ using TableCell = QtXmlToSphinx::TableCell;
+
+ QTest::addColumn<TablePtr>("table");
+ QTest::addColumn<QString>("expected");
+
+ TablePtr table(new QtXmlToSphinx::Table);
+ table->appendRow({TableCell("item11"), TableCell("item12")});
+ table->appendRow({TableCell(""), TableCell("item22")});
+ table->normalize();
+
+ const char *expected = R"(+------+------+
+|item11|item12|
++------+------+
+| |item22|
++------+------+
+
+)";
+
+ QTest::newRow("normal") << table << QString::fromLatin1(expected);
+
+ table.reset(new QtXmlToSphinx::Table);
+ table->appendRow({TableCell("item11"), TableCell("item12\nline2")});
+ table->appendRow({TableCell(""), TableCell("item22\nline2\nline3")});
+ table->normalize();
+
+ expected = R"(+------+------+
+|item11|item12|
+| |line2 |
++------+------+
+| |item22|
+| |line2 |
+| |line3 |
++------+------+
+
+)";
+
+ QTest::newRow("multi-line") << table << QString::fromLatin1(expected);
+}
+
+void QtXmlToSphinxTest::testTableFormatting()
+{
+ QFETCH(TablePtr, table);
+ QFETCH(QString, expected);
+
+ StringStream str;
+ table->format(str);
+ const QString actual = str.toString();
+
+ QCOMPARE(actual, expected);
+}
+
+void QtXmlToSphinxTest::testTableFormattingIoDevice_data()
+{
+ testTableFormatting_data();
+}
+
+void QtXmlToSphinxTest::testTableFormattingIoDevice()
+{
+ QFETCH(TablePtr, table);
+ QFETCH(QString, expected);
+
+ QByteArray byteArray;
+ {
+ TextStream str(&byteArray);
+ table->format(str);
+ }
+ const QString actual = QString::fromUtf8(byteArray);
+
+ QCOMPARE(actual, expected);
+}
+
+void QtXmlToSphinxTest::testSnippetExtraction_data()
+{
+ QTest::addColumn<QByteArray>("file");
+ QTest::addColumn<QLatin1StringView>("id");
+ QTest::addColumn<QString>("expected");
+
+ const char *fileCpp = R"(bla
+// ![snip1]
+snip1_line1
+// ![snip1] // ![snip2]
+snip2_line1
+snip2_line2
+// ![snip2] // ![snip3]
+)";
+
+ constexpr auto id = "snip2"_L1;
+ const QString expected = uR"(snip2_line1
+snip2_line2
+)"_s;
+
+ const char *filePython = R"(bla
+# ![snip1]
+snip1_line1
+# ![snip1] # ![snip2]
+snip2_line1
+snip2_line2
+# ![snip2] # ![snip3]
+)";
+
+ QTest::newRow("c++") << QByteArray(fileCpp) << id << expected;
+ QTest::newRow("Python") << QByteArray(filePython) << id << expected;
+}
+
+void QtXmlToSphinxTest::testSnippetExtraction()
+{
+ QFETCH(QByteArray, file);
+ QFETCH(QLatin1StringView, id);
+ QFETCH(QString, expected);
+
+ QBuffer buffer(&file);
+ QVERIFY(buffer.open(QIODevice::ReadOnly));
+ QString errorMessage;
+ QString actual = QtXmlToSphinx::readSnippet(buffer, id, &errorMessage);
+ QVERIFY2(errorMessage.isEmpty(), qPrintable(errorMessage));
+ QCOMPARE(actual, expected);
+}
+
+QTEST_APPLESS_MAIN( QtXmlToSphinxTest)
diff --git a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h
new file mode 100644
index 000000000..5108ef452
--- /dev/null
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h
@@ -0,0 +1,40 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef QTXMLTOSPHINXTEST_H
+#define QTXMLTOSPHINXTEST_H
+
+#include "qtxmltosphinxinterface.h"
+
+#include <QtCore/QObject>
+
+class QtXmlToSphinxTest : public QObject, public QtXmlToSphinxDocGeneratorInterface
+{
+ Q_OBJECT
+public:
+ // QtXmlToSphinxDocGeneratorInterface
+ QString expandFunction(const QString &) const override;
+ QString expandClass(const QString &, const QString &) const override;
+ QString resolveContextForMethod(const QString &,
+ const QString &) const override;
+ const QLoggingCategory &loggingCategory() const override;
+ QtXmlToSphinxLink resolveLink(const QtXmlToSphinxLink &link) const override;
+ Image resolveImage(const QString &href, const QString &context) const override;
+
+private slots:
+ void testTable_data();
+ void testTable();
+ void testTableFormatting_data();
+ void testTableFormatting();
+ void testTableFormattingIoDevice_data();
+ void testTableFormattingIoDevice();
+ void testSnippetExtraction_data();
+ void testSnippetExtraction();
+
+private:
+ QString transformXml(const QString &xml) const;
+
+ QtXmlToSphinxParameters m_parameters;
+};
+
+#endif // QTXMLTOSPHINXTEST_H
diff --git a/sources/shiboken6/tests/samplebinding/CMakeLists.txt b/sources/shiboken6/tests/samplebinding/CMakeLists.txt
new file mode 100644
index 000000000..fc812feb8
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/CMakeLists.txt
@@ -0,0 +1,176 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(sample)
+
+set(sample_TYPESYSTEM
+${CMAKE_CURRENT_SOURCE_DIR}/typesystem_sample.xml
+)
+
+set(sample_SRC
+${CMAKE_CURRENT_BINARY_DIR}/sample/abstractmodifications_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/abstract_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/arraymodifytest_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/base1_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/base2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/base3_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/base4_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/base5_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/base6_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/blackbox_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/brush_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/bytearray_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/bucket_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/classwithfunctionpointer_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/collector_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/comparisontester_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/color_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/ctorconvrule_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/customoverloadsequence_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/cvlistuser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/cvvaluetype_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/sbkdate_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/deleteddefaultctor_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/derived_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/derivedusingct_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/derived_someinnerclass_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/echo_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/event_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/expression_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/exceptiontest_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/friendofonlycopy_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/handleholder_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/implicitconv_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/implicitbase_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/implicittarget_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/intarray2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/intarray3_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/intlist_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/sortedoverload_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/intwrapper_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/injectcode_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/listuser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/mapuser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/mderived1_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/mderived2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/mderived3_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/mderived4_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/mderived5_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/modelindex_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/modifications_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/modifiedconstructor_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/noimplicitconversion_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/nondefaultctor_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objectmodel_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objecttype_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objecttypebyvalue_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objecttypeholder_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objecttypederived_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objecttypelayout_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objecttypeptrlist_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objecttypeoperators_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objectview_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/objtypereference_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/oddbooluser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/onlycopy_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/otherbase_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/overload_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/overload2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/pairuser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/pen_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/persistentmodelindex_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/photon_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/photon_base_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/photon_valueidentity_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/photon_valueduplicator_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/point_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/pointerholder_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/pointf_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/pointvaluelist_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/polygon_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/primitivestructpointerholder_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/privatector_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/privatedtor_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/protectedenumclass_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/protectednonpolymorphic_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/protectedpolymorphic_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/protectedpolymorphicdaughter_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/protectedpolymorphicgranddaughter_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/protectedproperty_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/protectedvirtualdestructor_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/rect_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/rectf_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/reference_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/referentmodelindex_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/toberenamedvalue_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/removednamespace1_objectoninvisiblenamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/renameduser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/sample_module_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/sample_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/sample_sample_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_ctparam_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_inlinenamespace_classwithininlinenamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_someinnerclass_okthisisrecursiveenough_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_someinnerclass_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_someotherinnerclass_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_derivedfromnamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/stdcomplex_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/simplefile_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/size_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/sizef_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/snakecasetest_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/snakecasederivedtest_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/sonofmderived1_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/spaceshipcomparisontester_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/str_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/strlist_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/time_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/templateptr_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/unremovednamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/valuewithunitdoubleinch_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/valuewithunitdoublemillimeter_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/valuewithunituser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/virtualdaughter_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/virtualdaughter2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/virtualfinaldaughter_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/virtualdtor_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/virtualmethods_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/voidholder_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/valueandvirtual_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/filter_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/data_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/intersection_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/union_wrapper.cpp
+)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sample-binding.txt.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt" @ONLY)
+
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${sample_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --project-file=${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt
+ ${GENERATOR_EXTRA_FLAGS}
+ DEPENDS ${sample_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for 'sample' test binding..."
+)
+
+add_library(sample MODULE ${sample_SRC})
+target_include_directories(sample PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(sample PUBLIC libsample libshiboken)
+set_property(TARGET sample PROPERTY PREFIX "")
+set_property(TARGET sample PROPERTY OUTPUT_NAME "sample${PYTHON_EXTENSION_SUFFIX}")
+
+if(WIN32)
+ set_property(TARGET sample PROPERTY SUFFIX ".pyd")
+endif()
+
+create_generator_target(sample)
diff --git a/sources/shiboken6/tests/samplebinding/__del___test.py b/sources/shiboken6/tests/samplebinding/__del___test.py
new file mode 100644
index 000000000..456886614
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/__del___test.py
@@ -0,0 +1,36 @@
+#!/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 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()
+
+import sample
+
+delCalled = False
+
+
+class MyObject(sample.ObjectType):
+ def __del__(self):
+ global delCalled
+ delCalled = True
+
+
+class TestDel(unittest.TestCase):
+ def testIt(self):
+ a = MyObject()
+ del a
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(delCalled)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/abstract_test.py b/sources/shiboken6/tests/samplebinding/abstract_test.py
new file mode 100644
index 000000000..89e87be1d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/abstract_test.py
@@ -0,0 +1,87 @@
+#!/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 Abstract 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 sample import Abstract
+
+
+class Incomplete(Abstract):
+ def __init__(self):
+ Abstract.__init__(self)
+
+
+class Concrete(Abstract):
+ def __init__(self):
+ Abstract.__init__(self)
+ self.pure_virtual_called = False
+ self.unpure_virtual_called = False
+
+ def pureVirtual(self):
+ self.pure_virtual_called = True
+
+ def pureVirtualReturningVoidPtr(self):
+ return 42
+
+ def unpureVirtual(self):
+ self.unpure_virtual_called = True
+
+ def virtualGettingAEnum(self, enum):
+ self.virtual_getting_enum = True
+
+
+class AbstractTest(unittest.TestCase):
+ '''Test case for Abstract class'''
+
+ def testAbstractPureVirtualMethodAvailability(self):
+ '''Test if Abstract class pure virtual method was properly wrapped.'''
+ self.assertTrue('pureVirtual' in dir(Abstract))
+
+ def testAbstractInstanciation(self):
+ '''Test if instanciation of an abstract class raises the correct exception.'''
+ self.assertRaises(NotImplementedError, Abstract)
+
+ def testUnimplementedPureVirtualMethodCall(self):
+ '''Test if calling a pure virtual method raises the correct exception.'''
+ i = Incomplete()
+ self.assertRaises(NotImplementedError, i.pureVirtual)
+
+ def testPureVirtualReturningVoidPtrReturnValue(self):
+ '''Test if a pure virtual method returning void ptr can be properly reimplemented'''
+ # Note that the semantics of reimplementing the pure virtual method in
+ # Python and calling it from C++ is undefined until it's decided how to
+ # cast the Python data types to void pointers
+ c = Concrete()
+ self.assertEqual(c.pureVirtualReturningVoidPtr(), 42)
+
+ def testReimplementedVirtualMethodCall(self):
+ '''Test if a Python override of a virtual method is correctly called from C++.'''
+ c = Concrete()
+ c.callUnpureVirtual()
+ self.assertTrue(c.unpure_virtual_called)
+
+ def testImplementedPureVirtualMethodCall(self):
+ '''Test if a Python override of a pure virtual method is correctly called from C++.'''
+ c = Concrete()
+ c.callPureVirtual()
+ self.assertTrue(c.pure_virtual_called)
+
+ def testEnumParameterOnVirtualMethodCall(self):
+ '''testEnumParameterOnVirtualMethodCall'''
+ c = Concrete()
+ c.callVirtualGettingEnum(Abstract.Short)
+ self.assertTrue(c.virtual_getting_enum)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/addedfunction_test.py b/sources/shiboken6/tests/samplebinding/addedfunction_test.py
new file mode 100644
index 000000000..0b5680143
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/addedfunction_test.py
@@ -0,0 +1,44 @@
+#!/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 added functions.'''
+
+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 SampleNamespace, ObjectType, Point
+
+
+class TestAddedFunctionsWithSimilarTypes(unittest.TestCase):
+ '''Adds new signatures very similar to already existing ones.'''
+
+ def testValueTypeReferenceAndValue(self):
+ '''In C++ we have "function(const ValueType&, double)",
+ in Python we add "function(ValueType)".'''
+ point = Point(10, 20)
+ multiplier = 4.0
+ control = (point.x() + point.y()) * multiplier
+ self.assertEqual(SampleNamespace.passReferenceToValueType(point, multiplier), control)
+ control = point.x() + point.y()
+ self.assertEqual(SampleNamespace.passReferenceToValueType(point), control)
+
+ def testObjectTypeReferenceAndPointer(self):
+ '''In C++ we have "function(const ObjectType&, int)",
+ in Python we add "function(ValueType)".'''
+ obj = ObjectType()
+ obj.setObjectName('sbrubbles')
+ multiplier = 3.0
+ control = len(obj.objectName()) * multiplier
+ self.assertEqual(SampleNamespace.passReferenceToObjectType(obj, multiplier), control)
+ control = len(obj.objectName())
+ self.assertEqual(SampleNamespace.passReferenceToObjectType(obj), control)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py b/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py
new file mode 100644
index 000000000..2a739033b
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_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 added functions with nested and multi-argument container types.'''
+
+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 sum2d, sumproduct
+
+
+class TestAddedFunctionsWithContainerArgs(unittest.TestCase):
+ '''Tests added functions with nested and multi-argument container types.'''
+
+ def testNestedContainerType(self):
+ '''Test added function with single-argument containers.'''
+ values = [[1, 2], [3, 4, 5], [6]]
+ self.assertEqual(sum2d(values), 21)
+
+ def testMultiArgContainerType(self):
+ '''Test added function with a two-argument container.'''
+ values = [(1, 2), (3, 4), (5, 6)]
+ self.assertEqual(sumproduct(values), 44)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py b/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py
new file mode 100644
index 000000000..b0ca56a6d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py
@@ -0,0 +1,98 @@
+#!/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 method arguments modifications performed as described on typesystem.'''
+
+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 Modifications, Point
+
+
+class ArgumentModificationsTest(unittest.TestCase):
+ '''Test cases for method arguments modifications performed as described on typesystem.'''
+
+ def setUp(self):
+ self.mods = Modifications()
+
+ def tearDown(self):
+ del self.mods
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testArgRemoval0(self):
+ '''Tests argument removal modifications on Modifications.argRemoval0.'''
+ # void [-> PyObject*] argRemoval0(int, bool, int = 123 [removed, new val = 321], int = 456)
+ # code-injection: returns tuple with received parameters plus removed ones
+ a0, a1, a2 = 1, True, 2
+ self.assertEqual(self.mods.argRemoval0(a0, a1), (a0, a1, 321, 456))
+ self.assertEqual(self.mods.argRemoval0(a0, a1, a2), (a0, a1, 321, a2))
+ # the other wasn't modified
+ # void argRemoval0(int, bool, int, bool)
+ self.assertEqual(self.mods.argRemoval0(0, False, 0, False), None)
+
+ def testArgRemoval1(self):
+ '''Tests argument removal modifications on Modifications.argRemoval1.'''
+ # void [-> PyObject*] argRemoval1(int, bool, Point = Point(1, 2) [removed],
+ # Point = Point(3, 4) [removed], int = 333)
+ # code-injection: returns tuple with received parameters plus removed ones
+ a0, a1, a2 = 1, True, 2
+ self.assertEqual(self.mods.argRemoval1(a0, a1), (a0, a1, Point(1, 2), Point(3, 4), 333))
+ self.assertEqual(self.mods.argRemoval1(a0, a1, a2), (a0, a1, Point(1, 2), Point(3, 4), a2))
+ # the other wasn't modified
+ # void argRemoval1(int, bool, int, bool)
+ self.assertEqual(self.mods.argRemoval1(0, False, 0, False), None)
+
+ def testArgRemoval2(self):
+ '''Tests argument removal modifications on Modifications.argRemoval2.'''
+ # void [-> PyObject*] argRemoval2(int, bool, Point = Point(1, 2)
+ # [removed], Point = Point(3, 4) [removed], int = 333)
+ # code-injection: returns tuple with received parameters plus removed ones
+ a0, a1, a2 = 1, True, 2
+ self.assertEqual(self.mods.argRemoval2(a0, a1), (a0, a1, Point(1, 2), Point(3, 4), 333))
+ self.assertEqual(self.mods.argRemoval2(a0, a1, a2), (a0, a1, Point(1, 2), Point(3, 4), a2))
+
+ def testArgRemoval3(self):
+ '''Tests argument removal modifications on Modifications.argRemoval3.'''
+ # void [-> PyObject*] argRemoval3(int, Point = Point(1, 2) [removed],
+ # bool = true, Point = Point(3, 4) [removed], int = 333)
+ # code-injection: returns tuple with received parameters plus removed ones
+ a0, a1, a2 = 1, True, 2
+ self.assertEqual(self.mods.argRemoval3(a0), (a0, Point(1, 2), True, Point(3, 4), 333))
+ self.assertEqual(self.mods.argRemoval3(a0, a1), (a0, Point(1, 2), a1, Point(3, 4), 333))
+ self.assertEqual(self.mods.argRemoval3(a0, a1, a2), (a0, Point(1, 2), a1, Point(3, 4), a2))
+
+ def testArgRemoval4(self):
+ '''Tests argument removal modifications on Modifications.argRemoval4.'''
+ # void [-> PyObject*] argRemoval4(int, Point [removed, new val = Point(6, 9)], bool,
+ # Point = Point(3, 4) [removed], int = 333)
+ # code-injection: returns tuple with received parameters plus removed ones
+ a0, a1, a2 = 1, True, 2
+ self.assertRaises(TypeError, self.mods.argRemoval4, a0)
+ self.assertEqual(self.mods.argRemoval4(a0, a1), (a0, Point(6, 9), a1, Point(3, 4), 333))
+ self.assertEqual(self.mods.argRemoval4(a0, a1, a2), (a0, Point(6, 9), a1, Point(3, 4), a2))
+
+ def testArgRemoval5(self):
+ '''Tests argument removal modifications on Modifications.argRemoval5.'''
+ # void [-> PyObject*] argRemoval5(int [removed, new val = 100], bool,
+ # Point = Point(1, 2) [removed],
+ # Point = Point(3, 4) [removed], int = 333)
+ # code-injection: returns tuple with received parameters plus removed ones
+ a0, a1, a2 = True, 2, True
+ self.assertEqual(self.mods.argRemoval5(a0), (100, a0, Point(1, 2), Point(3, 4), 333))
+ self.assertEqual(self.mods.argRemoval5(a0, a1), (100, a0, Point(1, 2), Point(3, 4), a1))
+ # void [-> PyObject*] argRemoval5(int [removed, new val = 200], bool, int, bool)
+ # code-injection: returns tuple with received parameters plus removed ones
+ self.assertEqual(self.mods.argRemoval5(a0, a1, a2), (200, a0, a1, a2))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/array_numpy_test.py b/sources/shiboken6/tests/samplebinding/array_numpy_test.py
new file mode 100644
index 000000000..0d73bca1c
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/array_numpy_test.py
@@ -0,0 +1,47 @@
+#!/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 NumPy Array types.'''
+
+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()
+import sample
+
+hasNumPy = False
+
+try:
+ import numpy
+ hasNumPy = True
+except ImportError:
+ pass
+
+
+class ArrayTester(unittest.TestCase):
+ '''Test case for NumPy arrays.'''
+
+ def testIntArray(self):
+ intList = numpy.array([1, 2, 3, 4], dtype='int32')
+ self.assertEqual(sample.sumIntArray(intList), 10)
+
+ def testDoubleArray(self):
+ doubleList = numpy.array([1, 2, 3, 4], dtype='double')
+ self.assertEqual(sample.sumDoubleArray(doubleList), 10)
+
+ def testIntMatrix(self):
+ intMatrix = numpy.array([[1, 2, 3], [4, 5, 6]], dtype='int32')
+ self.assertEqual(sample.sumIntMatrix(intMatrix), 21)
+
+ def testDoubleMatrix(self):
+ doubleMatrix = numpy.array([[1, 2, 3], [4, 5, 6]], dtype='double')
+ self.assertEqual(sample.sumDoubleMatrix(doubleMatrix), 21)
+
+
+if __name__ == '__main__' and hasNumPy:
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/array_sequence_test.py b/sources/shiboken6/tests/samplebinding/array_sequence_test.py
new file mode 100644
index 000000000..ad65d58db
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/array_sequence_test.py
@@ -0,0 +1,36 @@
+#!/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 Array types (PySequence).'''
+
+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()
+import sample
+
+
+class ArrayTester(unittest.TestCase):
+ '''Test case for arrays.'''
+
+ def testIntArray(self):
+ intList = [1, 2, 3, 4]
+ self.assertEqual(sample.sumIntArray(intList), 10)
+
+ def testIntArrayModified(self):
+ intList = [1, 2, 3, 4]
+ tester = sample.ArrayModifyTest()
+ self.assertEqual(tester.sumIntArray(4, intList), 10)
+
+ def testDoubleArray(self):
+ doubleList = [1.2, 2.3, 3.4, 4.5]
+ self.assertEqual(sample.sumDoubleArray(doubleList), 11.4)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/bug_554_test.py b/sources/shiboken6/tests/samplebinding/bug_554_test.py
new file mode 100644
index 000000000..a7e7a7210
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/bug_554_test.py
@@ -0,0 +1,25 @@
+#!/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
+
+'''Unit test for bug#554'''
+
+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 sample import ObjectType
+
+
+class Bug554:
+ def crash(self):
+ class Crasher(ObjectType):
+ pass
+
+
+if __name__ == '__main__':
+ bug = Bug554()
+ bug.crash()
diff --git a/sources/shiboken6/tests/samplebinding/bug_704_test.py b/sources/shiboken6/tests/samplebinding/bug_704_test.py
new file mode 100644
index 000000000..c470fe723
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/bug_704_test.py
@@ -0,0 +1,36 @@
+#!/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 ObjectType
+
+
+class NewStyle(object):
+ def name(self):
+ return "NewStyle"
+
+
+def defineNewStyle():
+ class MyObjectNew(ObjectType, NewStyle):
+ pass
+
+
+class ObjectTypeTest(unittest.TestCase):
+ '''Test cases to avoid declaring Shiboken classes with multiple inheritance
+ from old style classes.'''
+
+ def testObjectTypeNewStype(self):
+ defineNewStyle()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/bytearray_test.py b/sources/shiboken6/tests/samplebinding/bytearray_test.py
new file mode 100644
index 000000000..e51a899fa
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/bytearray_test.py
@@ -0,0 +1,129 @@
+#!/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 ByteArray
+
+
+class ByteArrayBufferProtocolTest(unittest.TestCase):
+ '''Tests ByteArray implementation of Python buffer protocol.'''
+
+ def testByteArrayBufferProtocol(self):
+ # Tests ByteArray implementation of Python buffer protocol using the Path().is_dir
+ # function with a unicode object or other object implementing the Python buffer protocol.
+ Path(str(ByteArray('/tmp'))).is_dir()
+
+
+class ByteArrayConcatenationOperatorTest(unittest.TestCase):
+ '''Test cases for ByteArray concatenation with '+' operator.'''
+
+ def testConcatByteArrayAndPythonString(self):
+ # Test concatenation of a ByteArray with a Python string, in this order.
+ ba = ByteArray('foo')
+ result = ba + '\x00bar'
+ self.assertEqual(type(result), ByteArray)
+ self.assertEqual(result, 'foo\x00bar')
+
+ def testConcatPythonStringAndByteArray(self):
+ # Test concatenation of a Python string with a ByteArray, in this order.
+ concat_python_string_add_qbytearray_worked = True # noqa: F841
+ ba = ByteArray('foo')
+ result = 'bar\x00' + ba
+ self.assertEqual(type(result), ByteArray)
+ self.assertEqual(result, 'bar\x00foo')
+
+
+class ByteArrayOperatorEqual(unittest.TestCase):
+ '''TestCase for operator ByteArray == ByteArray.'''
+
+ def testDefault(self):
+ # ByteArray() == ByteArray()
+ obj1 = ByteArray()
+ obj2 = ByteArray()
+ self.assertEqual(obj1, obj2)
+
+ def testSimple(self):
+ # ByteArray(some_string) == ByteArray(some_string)
+ string = 'egg snakes'
+ self.assertEqual(ByteArray(string), ByteArray(string))
+
+ def testPyString(self):
+ # ByteArray(string) == string
+ string = 'my test string'
+ self.assertEqual(ByteArray(string), string)
+
+ def testQString(self):
+ # ByteArray(string) == string
+ string = 'another test string'
+ self.assertEqual(ByteArray(string), string)
+
+
+class ByteArrayOperatorAt(unittest.TestCase):
+ '''TestCase for operator ByteArray[]'''
+
+ def testInRange(self):
+ # ByteArray[x] where x is a valid index.
+ string = 'abcdefgh'
+ obj = ByteArray(string)
+ for i in range(len(string)):
+ self.assertEqual(obj[i], bytes(string[i], "UTF8"))
+
+ def testInRangeReverse(self):
+ # ByteArray[x] where x is a valid index (reverse order).
+ string = 'abcdefgh'
+ obj = ByteArray(string)
+ for i in range(len(string) - 1, 0, -1):
+ self.assertEqual(obj[i], bytes(string[i], "UTF8"))
+
+ def testOutOfRange(self):
+ # ByteArray[x] where x is out of index.
+ string = '1234567'
+ obj = ByteArray(string)
+ self.assertRaises(IndexError, lambda: obj[len(string)])
+
+ def testNullStrings(self):
+ ba = ByteArray('\x00')
+ self.assertEqual(ba.at(0), '\x00')
+ self.assertEqual(ba[0], bytes('\x00', "UTF8"))
+
+
+class ByteArrayOperatorLen(unittest.TestCase):
+ '''Test case for __len__ operator of ByteArray'''
+
+ def testBasic(self):
+ '''ByteArray __len__'''
+ self.assertEqual(len(ByteArray()), 0)
+ self.assertEqual(len(ByteArray('')), 0)
+ self.assertEqual(len(ByteArray(' ')), 1)
+ self.assertEqual(len(ByteArray('yabadaba')), 8)
+
+
+class ByteArrayAndPythonStr(unittest.TestCase):
+ '''Test case for __str__ operator of ByteArray'''
+
+ def testStrOperator(self):
+ '''ByteArray __str__'''
+ self.assertEqual(ByteArray().__str__(), '')
+ self.assertEqual(ByteArray('').__str__(), '')
+ self.assertEqual(ByteArray('aaa').__str__(), 'aaa')
+
+ def testPythonStrAndNull(self):
+ s1 = bytes('123\000321', "UTF8")
+ ba = ByteArray(s1)
+ s2 = ba.data()
+ self.assertEqual(s1, s2)
+ self.assertEqual(type(s1), type(s2))
+ self.assertEqual(s1, ba)
+ self.assertNotEqual(type(s1), type(ba))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/child_return_test.py b/sources/shiboken6/tests/samplebinding/child_return_test.py
new file mode 100644
index 000000000..f0ac70626
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/child_return_test.py
@@ -0,0 +1,43 @@
+#!/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
+
+'''The BlackBox class has cases of ownership transference between C++ and Python.'''
+
+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 ObjectType
+
+
+class ReturnOfChildTest(unittest.TestCase):
+ '''The BlackBox class has cases of ownership transference between C++ and Python.'''
+
+ def testKillParentKeepingChild(self):
+ '''Ownership transference from Python to C++ and back again.'''
+ o1 = ObjectType.createWithChild()
+ child = o1.children()[0]
+ del o1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertRaises(RuntimeError, child.objectName)
+
+ def testKillParentKeepingChild2(self):
+ '''Ownership transference from Python to C++ and back again.'''
+ o1 = ObjectType.createWithChild()
+ child = o1.findChild("child")
+ del o1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertRaises(RuntimeError, child.objectName)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/class_fields_test.py b/sources/shiboken6/tests/samplebinding/class_fields_test.py
new file mode 100644
index 000000000..1eeb3d446
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/class_fields_test.py
@@ -0,0 +1,173 @@
+#!/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
+
+'''Simple test case for accessing the exposed C++ class fields.'''
+
+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 Derived, Point, ObjectType
+
+
+class TestAccessingCppFields(unittest.TestCase):
+ '''Simple test case for accessing the exposed C++ class fields.'''
+
+ def testAccessingPrimitiveTypeField(self):
+ '''Reads and writes a primitive type (in this case an 'int') field.'''
+ d = Derived()
+ self.assertEqual(type(d.primitiveField), int)
+
+ # attribution
+ old_value = d.primitiveField
+ new_value = 2255
+ d.primitiveField = new_value
+ self.assertEqual(d.primitiveField, new_value)
+ self.assertNotEqual(d.primitiveField, old_value)
+
+ # attribution with a convertible type
+ value = 1.2
+ d.primitiveField = value
+ self.assertEqual(d.primitiveField, int(value))
+
+ # attribution with invalid type
+ self.assertRaises(TypeError, lambda: setattr(d, 'primitiveField', None))
+
+ def testAccessingRenamedFields(self):
+ '''Reads and writes a renamed field.'''
+ d = Derived()
+ self.assertEqual(type(d.renamedField), int)
+ old_value = d.renamedField
+ new_value = 2255
+ d.renamedField = new_value
+ self.assertEqual(d.renamedField, new_value)
+ self.assertNotEqual(d.renamedField, old_value)
+
+ def testAccessingReadOnlyFields(self):
+ '''Tests a read-only field.'''
+ d = Derived()
+ self.assertEqual(type(d.readOnlyField), int)
+ old_value = d.readOnlyField
+ try:
+ d.readOnlyField = 25555
+ except AttributeError:
+ pass
+ self.assertEqual(d.readOnlyField, old_value)
+
+ def testAccessingUsersPrimitiveTypeField(self):
+ '''Reads and writes an user's primitive type (in this case an 'Complex') field.'''
+ d = Derived()
+ self.assertEqual(type(d.userPrimitiveField), complex)
+
+ # attribution
+ old_value = d.userPrimitiveField
+ new_value = complex(1.1, 2.2)
+ d.userPrimitiveField = new_value
+ self.assertEqual(d.userPrimitiveField, new_value)
+ self.assertNotEqual(d.userPrimitiveField, old_value)
+
+ # attribution with invalid type
+ self.assertRaises(TypeError, lambda: setattr(d, 'userPrimitiveField', None))
+
+ def testAccessingValueTypeField(self):
+ '''Reads and writes a value type (in this case a 'Point') field.'''
+ d = Derived()
+ self.assertEqual(type(d.valueTypeField), Point)
+
+ # attribution
+ old_value = d.valueTypeField # noqa: F841
+ new_value = Point(-10, 537)
+ d.valueTypeField = new_value
+ self.assertEqual(d.valueTypeField, new_value)
+
+ #object modify
+ d.valueTypeField.setX(10)
+ d.valueTypeField.setY(20)
+ self.assertEqual(d.valueTypeField.x(), 10)
+ self.assertEqual(d.valueTypeField.y(), 20)
+
+ # attribution with invalid type
+ self.assertRaises(TypeError, lambda: setattr(d, 'valueTypeField', 123))
+
+ def testAccessingObjectTypeField(self):
+ '''Reads and writes a object type (in this case an 'ObjectType') field.'''
+ d = Derived()
+
+ # attribution
+ old_value = d.objectTypeField
+ new_value = ObjectType()
+ d.objectTypeField = new_value
+ self.assertEqual(d.objectTypeField, new_value)
+ self.assertNotEqual(d.objectTypeField, old_value)
+
+ # attribution with a convertible type
+ value = None
+ d.objectTypeField = value
+ self.assertEqual(d.objectTypeField, value)
+
+ # attribution with invalid type
+ self.assertRaises(TypeError, lambda: setattr(d, 'objectTypeField', 123))
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountingAccessingObjectTypeField(self):
+ '''Accessing a object type field should respect the reference counting rules.'''
+ d = Derived()
+
+ # attributing object to instance's field should increase its reference count
+ o1 = ObjectType()
+ refcount1 = sys.getrefcount(o1)
+ d.objectTypeField = o1
+ self.assertEqual(d.objectTypeField, o1)
+ self.assertEqual(sys.getrefcount(d.objectTypeField), refcount1 + 1)
+
+ # attributing a new object to instance's field should decrease the previous
+ # object's reference count
+ o2 = ObjectType()
+ refcount2 = sys.getrefcount(o2)
+ d.objectTypeField = o2
+ self.assertEqual(d.objectTypeField, o2)
+ self.assertEqual(sys.getrefcount(o1), refcount1)
+ self.assertEqual(sys.getrefcount(d.objectTypeField), refcount2 + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountingOfReferredObjectAfterDeletingReferrer(self):
+ '''Deleting the object referring to other object should decrease the
+ reference count of the referee.'''
+ d = Derived()
+ o = ObjectType()
+ refcount = sys.getrefcount(o)
+ d.objectTypeField = o
+ self.assertEqual(sys.getrefcount(o), refcount + 1)
+ del d
+ self.assertEqual(sys.getrefcount(o), refcount)
+
+ def testStaticField(self):
+ self.assertEqual(Derived.staticPrimitiveField, 0)
+
+ def testAccessingUnsignedIntBitField(self):
+ d = Derived()
+
+ # attribution
+ old_value = d.bitField
+ new_value = 1
+ d.bitField = new_value
+ self.assertEqual(d.bitField, new_value)
+ self.assertNotEqual(d.bitField, old_value)
+
+ # attribution with a convertible type
+ value = 1.2
+ d.bitField = value
+ self.assertEqual(d.bitField, int(value))
+
+ # attribution with invalid type
+ self.assertRaises(TypeError, lambda: setattr(d, 'bitField', None))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/collector_test.py b/sources/shiboken6/tests/samplebinding/collector_test.py
new file mode 100644
index 000000000..4caebc62a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/collector_test.py
@@ -0,0 +1,60 @@
+#!/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 class' shift operators.'''
+
+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, IntWrapper, ObjectType
+
+
+class CollectorTest(unittest.TestCase):
+ '''Test cases for Collector class' shift operators.'''
+
+ def testLShiftOperatorSingleUse(self):
+ '''Test case for using the Collector.__lshift__ operator just one time.'''
+ collector = Collector()
+ collector << 13
+ self.assertEqual(collector.size(), 1)
+ self.assertEqual(collector.items(), [13])
+
+ def testLShiftOperatorMultipleUses(self):
+ '''Test case for using the Collector.__lshift__ operator many times in the same line.'''
+ collector = Collector()
+ collector << 2 << 3 << 5 << 7 << 11
+ self.assertEqual(collector.size(), 5)
+ self.assertEqual(collector.items(), [2, 3, 5, 7, 11])
+
+
+class CollectorExternalOperator(unittest.TestCase):
+ '''Test cases for external operators of Collector'''
+
+ def testLShiftExternal(self):
+ '''Collector external operator'''
+ collector = Collector()
+ collector << IntWrapper(5)
+ self.assertEqual(collector.size(), 1)
+ self.assertEqual(collector.items(), [5])
+
+
+class CollectorObjectType(unittest.TestCase):
+ '''Test cases for Collector ObjectType'''
+
+ def testBasic(self):
+ '''Collector << ObjectType # greedy collector'''
+ collector = Collector()
+ obj = ObjectType()
+ collector << obj
+ self.assertEqual(collector.items()[0], obj.identifier())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/complex_test.py b/sources/shiboken6/tests/samplebinding/complex_test.py
new file mode 100644
index 000000000..454aff100
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/complex_test.py
@@ -0,0 +1,66 @@
+#!/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 Complex 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()
+
+import sample
+from sample import Point
+
+
+class ComplexTest(unittest.TestCase):
+ '''Test case for conversions between C++ Complex class to Python complex class'''
+
+ def testFunctionReturningComplexObject(self):
+ '''Test function returning a C++ Complex object.'''
+ cpx = sample.transmutePointIntoComplex(Point(5.0, 2.3))
+ self.assertEqual(cpx, complex(5.0, 2.3))
+
+ def testFunctionReceivingComplexObjectAsArgument(self):
+ '''Test function returning a C++ Complex object.'''
+ pt = sample.transmuteComplexIntoPoint(complex(1.2, 3.4))
+ # these assertions intentionally avoids to test the == operator,
+ # it should have its own test cases.
+ self.assertEqual(pt.x(), 1.2)
+ self.assertEqual(pt.y(), 3.4)
+
+ def testComplexList(self):
+ '''Test list of C++ Complex objects conversion to a list of Python complex objects.'''
+ # the global function gimmeComplexList() is expected to return a list
+ # containing the following Complex values: [0j, 1.1+2.2j, 1.3+2.4j]
+ cpxlist = sample.gimmeComplexList()
+ self.assertEqual(cpxlist, [complex(), complex(1.1, 2.2), complex(1.3, 2.4)])
+
+ def testSumComplexPair(self):
+ '''Test sum of a tuple containing two complex objects.'''
+ cpx1 = complex(1.2, 3.4)
+ cpx2 = complex(5.6, 7.8)
+ self.assertEqual(sample.sumComplexPair((cpx1, cpx2)), cpx1 + cpx2)
+
+ def testUsingTuples(self):
+ cpx1, cpx2 = (1.2, 3.4), (5.6, 7.8)
+ self.assertEqual(sample.sumComplexPair((cpx1, cpx2)),
+ sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
+ cpx1, cpx2 = (1, 3), (5, 7)
+ self.assertEqual(sample.sumComplexPair((cpx1, cpx2)),
+ sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
+ cpx1, cpx2 = (1.2, 3), (5.6, 7)
+ self.assertEqual(sample.sumComplexPair((cpx1, cpx2)),
+ sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
+ cpx1, cpx2 = (1, 2, 3), (4, 5, 7)
+ self.assertRaises(TypeError, sample.sumComplexPair, (cpx1, cpx2))
+ cpx1, cpx2 = ('1', '2'), ('4', '5')
+ self.assertRaises(TypeError, sample.sumComplexPair, (cpx1, cpx2))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/conversion_operator_test.py b/sources/shiboken6/tests/samplebinding/conversion_operator_test.py
new file mode 100644
index 000000000..7e76245b1
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/conversion_operator_test.py
@@ -0,0 +1,37 @@
+#!/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 implicit conversion generated by conversion operator.'''
+
+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 Time, StrList
+
+
+class ConversionOperatorTest(unittest.TestCase):
+ '''Test cases for implicit conversion generated by conversion operator.'''
+
+ def testConversionOperator(self):
+ '''Time defined an conversion operator for Str, so passing a Time object
+ to a method expecting a Str should work.'''
+ t = Time(1, 2, 3)
+ t_str = t.toString()
+ sl = StrList()
+
+ # StrList.append expects a Str object.
+ sl.append(t)
+
+ self.assertEqual(len(sl), 1)
+ self.assertEqual(sl[0], t_str)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/copy_test.py b/sources/shiboken6/tests/samplebinding/copy_test.py
new file mode 100644
index 000000000..db539d1b9
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/copy_test.py
@@ -0,0 +1,65 @@
+#!/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 deep copy of objects'''
+
+import copy
+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()
+
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
+
+from sample import Point
+
+
+class SimpleCopy(unittest.TestCase):
+ '''Simple copy of objects'''
+
+ def testCopy(self):
+ point = Point(0.1, 2.4)
+ new_point = copy.copy(point)
+
+ self.assertTrue(point is not new_point)
+ self.assertEqual(point, new_point)
+
+
+class DeepCopy(unittest.TestCase):
+ '''Deep copy with shiboken objects'''
+
+ def testDeepCopy(self):
+ '''Deep copy of value types'''
+ point = Point(3.1, 4.2)
+ new_point = copy.deepcopy([point])[0]
+
+ self.assertTrue(point is not new_point)
+ self.assertEqual(point, new_point)
+
+
+class PicklingTest(unittest.TestCase):
+ '''Support pickling'''
+
+ def testSimple(self):
+ '''Simple pickling and unpickling'''
+
+ point = Point(10.2, 43.5)
+
+ data = pickle.dumps(point)
+ new_point = pickle.loads(data)
+
+ self.assertEqual(point, new_point)
+ self.assertTrue(point is not new_point)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py b/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py
new file mode 100644
index 000000000..5e2695d72
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py
@@ -0,0 +1,30 @@
+#!/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 proper generation of constructor altered by conversion-rule tag.'''
+
+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 CtorConvRule
+
+
+class TestCtorConvRule(unittest.TestCase):
+ '''Simple test case for CtorConvRule'''
+
+ def testCtorConvRule(self):
+ '''Test CtorConvRule argument modification through conversion-rule tag.'''
+ value = 123
+ obj = CtorConvRule(value)
+ self.assertEqual(obj.value(), value + 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/cyclic_test.py b/sources/shiboken6/tests/samplebinding/cyclic_test.py
new file mode 100644
index 000000000..4e4ae2603
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/cyclic_test.py
@@ -0,0 +1,89 @@
+#!/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 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 ObjectType
+from sample import ObjectView
+from sample import ObjectModel
+
+
+class ObjTest(unittest.TestCase):
+
+ def test_cyclic_dependency_withParent(self):
+ """Create 2 objects with a cyclic dependency, so that they can
+ only be removed by the garbage collector, and then invoke the
+ garbage collector in a different thread.
+ """
+ class CyclicChildObject(ObjectType):
+ def __init__(self, parent):
+ super(CyclicChildObject, self).__init__(parent)
+ self._parent = parent
+
+ class CyclicObject(ObjectType):
+ def __init__(self):
+ super(CyclicObject, self).__init__()
+ CyclicChildObject(self)
+
+ # turn off automatic garbage collection, to be able to trigger it
+ # at the 'right' time
+ gc.disable()
+ alive = lambda: sum(isinstance(o, CyclicObject) for o in gc.get_objects()) # noqa: E731
+
+ #
+ # first proof that the wizard is only destructed by the garbage
+ # collector
+ #
+ cycle = CyclicObject()
+ self.assertTrue(alive())
+ del cycle
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: the semantics of gc.enable/gc.disable is different for PyPy
+ self.assertTrue(alive())
+ gc.collect()
+ self.assertFalse(alive())
+
+ def test_cyclic_dependency_withKeepRef(self):
+ """Create 2 objects with a cyclic dependency, so that they can
+ only be removed by the garbage collector, and then invoke the
+ garbage collector in a different thread.
+ """
+ class CyclicChildObject(ObjectView):
+ def __init__(self, model):
+ super(CyclicChildObject, self).__init__(None)
+ self.setModel(model)
+
+ class CyclicObject(ObjectModel):
+ def __init__(self):
+ super(CyclicObject, self).__init__()
+ self._view = CyclicChildObject(self)
+
+ # turn off automatic garbage collection, to be able to trigger it
+ # at the 'right' time
+ gc.disable()
+ alive = lambda: sum(isinstance(o, CyclicObject) for o in gc.get_objects()) # noqa: E731
+
+ #
+ # first proof that the wizard is only destructed by the garbage
+ # collector
+ #
+ cycle = CyclicObject()
+ self.assertTrue(alive())
+ del cycle
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: the semantics of gc.enable/gc.disable is different for PyPy
+ self.assertTrue(alive())
+ gc.collect()
+ self.assertFalse(alive())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/date_test.py b/sources/shiboken6/tests/samplebinding/date_test.py
new file mode 100644
index 000000000..2b6efcf18
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/date_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
+
+'''Test cases for python conversions types '''
+
+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 datetime import date
+
+from sample import SbkDate
+
+
+class DateConversionTest(unittest.TestCase):
+
+ def testConstructorWithDateObject(self):
+ pyDate = date(2010, 12, 12)
+ cDate = SbkDate(pyDate)
+ self.assertTrue(cDate.day(), pyDate.day)
+ self.assertTrue(cDate.month(), pyDate.month)
+ self.assertTrue(cDate.year(), pyDate.year)
+
+ def testToPythonFunction(self):
+ cDate = SbkDate(2010, 12, 12)
+ pyDate = cDate.toPython()
+ self.assertTrue(cDate.day(), pyDate.day)
+ self.assertTrue(cDate.month(), pyDate.month)
+ self.assertTrue(cDate.year(), pyDate.year)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/decisor_test.py b/sources/shiboken6/tests/samplebinding/decisor_test.py
new file mode 100644
index 000000000..0d39c5f96
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/decisor_test.py
@@ -0,0 +1,52 @@
+#!/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 method overload decisor.'''
+
+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 SampleNamespace, Point, ObjectType, ObjectModel
+
+
+class DecisorTest(unittest.TestCase):
+ '''Test cases for the method overload decisor.'''
+
+ def testCallWithInvalidParametersSideA(self):
+ '''Call a method missing with the last argument missing.
+ This can trigger the bug #262, which means using an argument
+ not provided by the user.'''
+ pt = Point()
+ # This exception may move from a TypeError to a ValueError.
+ self.assertRaises((TypeError, ValueError), SampleNamespace.forceDecisorSideA, pt)
+
+ def testCallWithInvalidParametersSideB(self):
+ '''Same as the previous test, but with an integer as first argument,
+ just to complicate things for the overload method decisor.'''
+ pt = Point()
+ # This exception may move from a TypeError to a ValueError.
+ self.assertRaises((TypeError, ValueError), SampleNamespace.forceDecisorSideB, 1, pt)
+
+ def testDecideCallWithInheritance(self):
+ '''Call methods overloads that receive parent and inheritor classes' instances.'''
+ objecttype = ObjectType()
+ objectmodel = ObjectModel()
+ self.assertEqual(ObjectModel.receivesObjectTypeFamily(objecttype),
+ ObjectModel.ObjectTypeCalled)
+ self.assertNotEqual(ObjectModel.receivesObjectTypeFamily(objecttype),
+ ObjectModel.ObjectModelCalled)
+ self.assertEqual(ObjectModel.receivesObjectTypeFamily(objectmodel),
+ ObjectModel.ObjectModelCalled)
+ self.assertNotEqual(ObjectModel.receivesObjectTypeFamily(objectmodel),
+ ObjectModel.ObjectTypeCalled)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/delete_test.py b/sources/shiboken6/tests/samplebinding/delete_test.py
new file mode 100644
index 000000000..57a792ae2
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/delete_test.py
@@ -0,0 +1,28 @@
+#!/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()
+
+import sample
+from shiboken6 import Shiboken
+
+
+class DeleteTest(unittest.TestCase):
+ def testNonCppWrapperClassDelete(self):
+ """Would segfault when shiboken.delete called on obj not created from Python."""
+ obj = sample.ObjectType()
+ child = obj.createChild(None)
+ Shiboken.delete(child)
+ assert not Shiboken.isValid(child)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/deprecated_test.py b/sources/shiboken6/tests/samplebinding/deprecated_test.py
new file mode 100644
index 000000000..c371df94f
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/deprecated_test.py
@@ -0,0 +1,26 @@
+#!/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
+import warnings
+
+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 ObjectType
+
+
+class TestDeprecatedCall(unittest.TestCase):
+ def testCallWithError(self):
+ o = ObjectType()
+ warnings.simplefilter('error')
+ self.assertRaises(DeprecationWarning, o.deprecatedFunction)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/derived_test.py b/sources/shiboken6/tests/samplebinding/derived_test.py
new file mode 100644
index 000000000..346f29136
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/derived_test.py
@@ -0,0 +1,143 @@
+#!/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 Derived 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()
+
+import sample
+from sample import Abstract, Derived, DerivedUsingCt, OverloadedFuncEnum
+
+
+class Deviant(Derived):
+ def __init__(self):
+ Derived.__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 'Deviant'
+
+
+class ImplementVirtualWithOutParameter(Derived):
+ def __init__(self, value):
+ super().__init__()
+ self._value = value
+
+ def virtualWithOutParameter(self):
+ return self._value
+
+
+class DerivedTest(unittest.TestCase):
+ '''Test case for Derived class'''
+
+ def testParentClassMethodsAvailability(self):
+ '''Test if Derived class really inherits its methods from parent.'''
+ inherited_methods = set(['callPureVirtual', 'callUnpureVirtual',
+ 'id_', 'pureVirtual', 'unpureVirtual'])
+ self.assertTrue(inherited_methods.issubset(dir(Derived)))
+
+ def testOtherOverloadedMethodCall(self):
+ '''Another test to check overloaded method calling, just to double check.'''
+ derived = Derived()
+
+ result = derived.otherOverloaded(1, 2, True, 3.3)
+ self.assertEqual(type(result), Derived.OtherOverloadedFuncEnum)
+ self.assertEqual(result, sample.Derived.OtherOverloadedFunc_iibd)
+
+ result = derived.otherOverloaded(1, 2.2)
+ self.assertEqual(type(result), Derived.OtherOverloadedFuncEnum)
+ self.assertEqual(result, Derived.OtherOverloadedFunc_id)
+
+ def testOverloadedMethodCallWithDifferentNumericTypes(self):
+ '''Test if the correct overloaded method accepts a different numeric type as argument.'''
+ derived = Derived()
+ result = derived.overloaded(1.1, 2.2)
+ self.assertEqual(type(result), OverloadedFuncEnum)
+
+ def testOverloadedMethodCallWithWrongNumberOfArguments(self):
+ '''Test if a call to an overloaded method with the wrong number of arguments
+ raises an exception.'''
+ derived = Derived()
+ self.assertRaises(TypeError, derived.otherOverloaded, 1, 2, True)
+
+ def testReimplementedPureVirtualMethodCall(self):
+ '''Test if a Python override of a implemented pure virtual method is
+ correctly called from C++.'''
+ d = Deviant()
+ 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 = Deviant()
+ d.callUnpureVirtual()
+ self.assertTrue(d.unpure_virtual_called)
+
+ def testVirtualMethodCallString(self):
+ '''Test virtual method call returning string.'''
+ d = Derived()
+ self.assertEqual(d.className(), 'Derived')
+ self.assertEqual(d.getClassName(), 'Derived')
+
+ def testReimplementedVirtualMethodCallReturningString(self):
+ '''Test if a Python override of a reimplemented virtual method is
+ correctly called from C++.'''
+ d = Deviant()
+ self.assertEqual(d.className(), 'Deviant')
+ self.assertEqual(d.getClassName(), 'Deviant')
+
+ def testSingleArgument(self):
+ '''Test singleArgument call.'''
+ d = Derived()
+ self.assertTrue(d.singleArgument(False))
+ self.assertTrue(not d.singleArgument(True))
+
+ def testMethodCallWithDefaultValue(self):
+ '''Test method call with default value.'''
+ d = Derived()
+ self.assertEqual(d.defaultValue(3), 3.1)
+ self.assertEqual(d.defaultValue(), 0.1)
+
+ def testCallToMethodWithAbstractArgument(self):
+ '''Call to method that expects an Abstract argument.'''
+ objId = 123
+ d = Derived(objId)
+ self.assertEqual(Abstract.getObjectId(d), objId)
+
+ def testObjectCreationWithParentType(self):
+ '''Derived class creates an instance of itself in C++ and returns it as
+ a pointer to its ancestor Abstract.'''
+ obj = Derived.createObject()
+ self.assertEqual(type(obj), Derived)
+
+ def testDerivedUsingCt(self):
+ '''Test whether a constructor of the base class declared by using works'''
+ obj = DerivedUsingCt(42)
+ self.assertEqual(obj.value(), 42)
+
+ def testVirtualWithOutParameter(self):
+ d = Derived()
+ self.assertEqual(d.callVirtualWithOutParameter(), 42)
+
+ d = ImplementVirtualWithOutParameter(1)
+ self.assertEqual(d.callVirtualWithOutParameter(), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/duck_punching_test.py b/sources/shiboken6/tests/samplebinding/duck_punching_test.py
new file mode 100644
index 000000000..aa21a0f7e
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/duck_punching_test.py
@@ -0,0 +1,158 @@
+#!/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 virtual methods.'''
+
+import os
+import sys
+import types
+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 VirtualMethods, SimpleFile, Point
+
+
+def MethodTypeCompat(func, instance):
+ return types.MethodType(func, instance)
+
+
+class Duck(VirtualMethods):
+ def __init__(self):
+ VirtualMethods.__init__(self)
+
+
+class Monkey(SimpleFile):
+ def __init__(self, filename):
+ SimpleFile.__init__(self, filename)
+
+
+class DuckPunchingTest(unittest.TestCase):
+ '''Test case for duck punching (aka "monkey patching").'''
+
+ def setUp(self):
+ self.multiplier = 2.0
+ self.duck_method_called = False
+ self.call_counter = 0
+
+ def testMonkeyPatchOnVirtualMethod(self):
+ '''Injects new 'virtualMethod0' on a VirtualMethods instance and makes C++ call it.'''
+ vm = VirtualMethods()
+ pt, val, cpx, b = Point(1.1, 2.2), 4, complex(3.3, 4.4), True
+
+ result1 = vm.virtualMethod0(pt, val, cpx, b)
+ result2 = vm.callVirtualMethod0(pt, val, cpx, b)
+ self.assertEqual(result1, result2)
+ self.assertEqual(result1, VirtualMethods.virtualMethod0(vm, pt, val, cpx, b))
+
+ def myVirtualMethod0(obj, pt, val, cpx, b):
+ self.duck_method_called = True
+ return VirtualMethods.virtualMethod0(obj, pt, val, cpx, b) * self.multiplier
+ vm.virtualMethod0 = MethodTypeCompat(myVirtualMethod0, vm)
+
+ result1 = vm.callVirtualMethod0(pt, val, cpx, b)
+ self.assertTrue(self.duck_method_called)
+
+ result2 = vm.virtualMethod0(pt, val, cpx, b)
+ self.assertEqual(result1, result2)
+ self.assertEqual(result1,
+ VirtualMethods.virtualMethod0(vm, pt, val, cpx, b) * self.multiplier)
+
+ # This is done to decrease the refcount of the vm object
+ # allowing the object wrapper to be deleted before the
+ # BindingManager. This is useful when compiling Shiboken
+ # for debug, since the BindingManager destructor has an
+ # assert that checks if the wrapper mapper is empty.
+ vm.virtualMethod0 = None
+
+ def testMonkeyPatchOnVirtualMethodWithInheritance(self):
+ '''Injects new 'virtualMethod0' on an object that inherits from
+ VirtualMethods and makes C++ call it.'''
+ duck = Duck()
+ pt, val, cpx, b = Point(1.1, 2.2), 4, complex(3.3, 4.4), True
+
+ result1 = duck.virtualMethod0(pt, val, cpx, b)
+ result2 = duck.callVirtualMethod0(pt, val, cpx, b)
+ self.assertEqual(result1, result2)
+ self.assertEqual(result1, VirtualMethods.virtualMethod0(duck, pt, val, cpx, b))
+
+ def myVirtualMethod0(obj, pt, val, cpx, b):
+ self.duck_method_called = True
+ return VirtualMethods.virtualMethod0(obj, pt, val, cpx, b) * self.multiplier
+ duck.virtualMethod0 = MethodTypeCompat(myVirtualMethod0, duck)
+
+ result1 = duck.callVirtualMethod0(pt, val, cpx, b)
+ self.assertTrue(self.duck_method_called)
+
+ result2 = duck.virtualMethod0(pt, val, cpx, b)
+ self.assertEqual(result1, result2)
+ self.assertEqual(result1,
+ VirtualMethods.virtualMethod0(duck, pt, val, cpx, b) * self.multiplier)
+
+ duck.virtualMethod0 = None
+
+ def testMonkeyPatchOnMethodWithStaticAndNonStaticOverloads(self):
+ '''Injects new 'exists' on a SimpleFile instance and makes C++ call it.'''
+ simplefile = SimpleFile('foobar')
+
+ # Static 'exists'
+ simplefile.exists('sbrubbles')
+ self.assertFalse(self.duck_method_called)
+ # Non-static 'exists'
+ simplefile.exists()
+ self.assertFalse(self.duck_method_called)
+
+ def myExists(obj):
+ self.duck_method_called = True
+ return False
+ simplefile.exists = MethodTypeCompat(myExists, simplefile)
+
+ # Static 'exists' was overridden by the monkey patch, which accepts 0 arguments
+ self.assertRaises(TypeError, simplefile.exists, 'sbrubbles')
+ # Monkey patched exists
+ simplefile.exists()
+ self.assertTrue(self.duck_method_called)
+
+ simplefile.exists = None
+
+ def testMonkeyPatchOnMethodWithStaticAndNonStaticOverloadsWithInheritance(self):
+ '''Injects new 'exists' on an object that inherits from SimpleFile and makes C++ call it.'''
+ monkey = Monkey('foobar')
+
+ # Static 'exists'
+ monkey.exists('sbrubbles')
+ self.assertFalse(self.duck_method_called)
+ # Non-static 'exists'
+ monkey.exists()
+ self.assertFalse(self.duck_method_called)
+
+ def myExists(obj):
+ self.duck_method_called = True
+ return False
+ monkey.exists = MethodTypeCompat(myExists, monkey)
+
+ # Static 'exists' was overridden by the monkey patch, which accepts 0 arguments
+ self.assertRaises(TypeError, monkey.exists, 'sbrubbles')
+ # Monkey patched exists
+ monkey.exists()
+ self.assertTrue(self.duck_method_called)
+
+ monkey.exists = None
+
+ def testForInfiniteRecursion(self):
+ def myVirtualMethod0(obj, pt, val, cpx, b):
+ self.call_counter += 1
+ return VirtualMethods.virtualMethod0(obj, pt, val, cpx, b)
+ vm = VirtualMethods()
+ vm.virtualMethod0 = MethodTypeCompat(myVirtualMethod0, vm)
+ pt, val, cpx, b = Point(1.1, 2.2), 4, complex(3.3, 4.4), True
+ vm.virtualMethod0(pt, val, cpx, b)
+ self.assertEqual(self.call_counter, 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/echo_test.py b/sources/shiboken6/tests/samplebinding/echo_test.py
new file mode 100644
index 000000000..f1859260e
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/echo_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 <add-function> with const char* as argument'''
+
+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 Echo
+
+
+class TestEcho(unittest.TestCase):
+ '''Simple test case for Echo.echo'''
+
+ def testEcho(self):
+ '''Test function added with const char * as arg'''
+ x = 'Foobar'
+ y = Echo().echo(x)
+ self.assertEqual(x, y)
+
+ def testCallOperator(self):
+ e = Echo()
+ self.assertEqual(e("Hello", 3), "Hello3")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/enum_test.py b/sources/shiboken6/tests/samplebinding/enum_test.py
new file mode 100644
index 000000000..276b8d894
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/enum_test.py
@@ -0,0 +1,138 @@
+#!/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 Python representation of C++ enums.'''
+
+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()
+
+# This is needed after the introduction of BUILD_DIR.
+
+import sample
+from sample import SampleNamespace, ObjectType, Event
+
+
+def createTempFile():
+ import tempfile
+ return tempfile.SpooledTemporaryFile(mode='rw')
+
+
+class EnumTest(unittest.TestCase):
+ '''Test case for Python representation of C++ enums.'''
+
+ def testHashability(self):
+ self.assertEqual(hash(SampleNamespace.TwoIn), hash(SampleNamespace.TwoOut))
+ self.assertNotEqual(hash(SampleNamespace.TwoIn), hash(SampleNamespace.OneIn))
+
+ def testEnumValuesInsideEnum(self):
+ '''Enum values should be accessible inside the enum as well as outside.'''
+ for value_name in SampleNamespace.Option.__members__:
+ enum_item1 = getattr(SampleNamespace.Option, value_name)
+ enum_item2 = getattr(SampleNamespace, value_name)
+ self.assertEqual(enum_item1, enum_item2)
+
+ def testPassingIntegerOnEnumArgument(self):
+ '''Tries to use an integer in place of an enum argument.'''
+ self.assertRaises(TypeError, SampleNamespace.getNumber, 1)
+
+ def testBuildingEnumFromIntegerValue(self):
+ '''Tries to build the proper enum using an integer.'''
+ SampleNamespace.getNumber(SampleNamespace.Option(1))
+
+ def testBuildingEnumWithDefaultValue(self):
+ '''Enum constructor with default value'''
+ enum = SampleNamespace.Option()
+ self.assertEqual(enum, SampleNamespace.None_)
+
+ def testEnumConversionToAndFromPython(self):
+ '''Conversion of enum objects from Python to C++ back again.'''
+ enumout = SampleNamespace.enumInEnumOut(SampleNamespace.TwoIn)
+ self.assertTrue(enumout, SampleNamespace.TwoOut)
+ self.assertEqual(repr(enumout), repr(SampleNamespace.TwoOut))
+
+ def testEnumConstructorWithTooManyParameters(self):
+ '''Calling the constructor of non-extensible enum with the wrong number of parameters.'''
+ self.assertRaises((TypeError, ValueError), SampleNamespace.InValue, 13, 14)
+
+ def testEnumConstructorWithNonNumberParameter(self):
+ '''Calling the constructor of non-extensible enum with a string.'''
+ self.assertRaises((TypeError, ValueError), SampleNamespace.InValue, '1')
+
+ def testEnumItemAsDefaultValueToIntArgument(self):
+ '''Calls function with an enum item as default value to an int argument.'''
+ self.assertEqual(SampleNamespace.enumItemAsDefaultValueToIntArgument(),
+ SampleNamespace.ZeroIn)
+ self.assertEqual(SampleNamespace.enumItemAsDefaultValueToIntArgument(SampleNamespace.ZeroOut), # noqa E:501
+ SampleNamespace.ZeroOut)
+ self.assertEqual(SampleNamespace.enumItemAsDefaultValueToIntArgument(123), 123)
+
+ def testAnonymousGlobalEnums(self):
+ '''Checks availability of anonymous global enum items.'''
+ self.assertEqual(sample.AnonymousGlobalEnum_Value0, 0)
+ self.assertEqual(sample.AnonymousGlobalEnum_Value1, 1)
+
+ def testAnonymousClassEnums(self):
+ '''Checks availability of anonymous class enum items.'''
+ self.assertEqual(SampleNamespace.AnonymousClassEnum_Value0, 0)
+ self.assertEqual(SampleNamespace.AnonymousClassEnum_Value1, 1)
+
+ def testEnumClasses(self):
+ # C++ 11: values of enum classes need to be fully qualified to match C++
+ sum = Event.EventTypeClass.Value1 + Event.EventTypeClass.Value2
+ self.assertEqual(sum, 1)
+
+ def testSetEnum(self):
+ event = Event(Event.ANY_EVENT)
+ self.assertEqual(event.eventType(), Event.ANY_EVENT)
+ event.setEventType(Event.BASIC_EVENT)
+ self.assertEqual(event.eventType(), Event.BASIC_EVENT)
+ event.setEventTypeByConstRef(Event.SOME_EVENT)
+ self.assertEqual(event.eventType(), Event.SOME_EVENT)
+ event.setEventTypeByConstPtr(Event.BASIC_EVENT)
+ self.assertEqual(event.eventType(), Event.BASIC_EVENT)
+
+ def testEnumArgumentWithDefaultValue(self):
+ '''Option enumArgumentWithDefaultValue(Option opt = UnixTime);'''
+ self.assertEqual(SampleNamespace.enumArgumentWithDefaultValue(), SampleNamespace.UnixTime)
+ self.assertEqual(SampleNamespace.enumArgumentWithDefaultValue(SampleNamespace.RandomNumber), # noqa E:501
+ SampleNamespace.RandomNumber)
+
+
+class MyEvent(Event):
+ def __init__(self):
+ Event.__init__(self, Event.EventType(3))
+
+
+class OutOfBoundsTest(unittest.TestCase):
+ def testValue(self):
+ e = MyEvent()
+ self.assertEqual(repr(e.eventType()), "<EventType.ANY_EVENT: 3>")
+
+
+class EnumOverloadTest(unittest.TestCase):
+ '''Test case for overloads involving enums'''
+
+ def testWithInt(self):
+ '''Overload with Enums and ints with default value'''
+ o = ObjectType()
+
+ self.assertEqual(o.callWithEnum('', Event.ANY_EVENT, 9), 81)
+ self.assertEqual(o.callWithEnum('', 9), 9)
+
+
+class EnumOperators(unittest.TestCase):
+ '''Test case for operations on enums'''
+
+ def testInequalitySameObject(self):
+ self.assertFalse(Event.ANY_EVENT != Event.ANY_EVENT)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py b/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py
new file mode 100644
index 000000000..42ae23961
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py
@@ -0,0 +1,51 @@
+#!/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()
+
+import sample
+from shiboken_test_helper import objectFullname
+
+from shibokensupport.signature import get_signature
+
+
+class TestEnumFromRemovedNamespace(unittest.TestCase):
+
+ def testNames(self):
+ # Test if invisible namespace does not appear on type name
+ self.assertEqual(objectFullname(sample.RemovedNamespace1_Enum),
+ "sample.RemovedNamespace1_Enum")
+ self.assertEqual(objectFullname(sample.ObjectOnInvisibleNamespace),
+ "sample.ObjectOnInvisibleNamespace")
+
+ # Function arguments
+ signature = get_signature(sample.ObjectOnInvisibleNamespace.toInt)
+ self.assertEqual(objectFullname(signature.parameters['e'].annotation),
+ "sample.RemovedNamespace1_Enum")
+ signature = get_signature(sample.ObjectOnInvisibleNamespace.consume)
+ self.assertEqual(objectFullname(signature.parameters['other'].annotation),
+ "sample.ObjectOnInvisibleNamespace")
+
+ def testGlobalFunctionFromRemovedNamespace(self):
+ self.assertEqual(sample.mathSum(1, 2), 3)
+
+ def testEnumPromotedToUpperNamespace(self):
+ sample.UnremovedNamespace
+ sample.UnremovedNamespace.RemovedNamespace3_Enum
+ sample.UnremovedNamespace.RemovedNamespace3_Enum_Value0
+ sample.UnremovedNamespace.RemovedNamespace3_AnonymousEnum_Value0
+
+ def testNestedFunctionFromRemovedNamespace(self):
+ self.assertEqual(sample.UnremovedNamespace.nestedMathSum(1, 2), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py b/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py
new file mode 100644
index 000000000..8e13d5d46
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py
@@ -0,0 +1,49 @@
+#!/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
+
+'''Simple event loop dispatcher test.'''
+
+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 ObjectType, Event
+
+
+class NoOverride(ObjectType):
+
+ pass
+
+
+class Override(ObjectType):
+
+ def __init__(self):
+ ObjectType.__init__(self)
+ self.called = False
+
+ def event(self, event):
+ self.called = True
+ return True
+
+
+class TestEventLoop(unittest.TestCase):
+
+ def testEventLoop(self):
+ '''Calling virtuals in a event loop'''
+ objs = [ObjectType(), NoOverride(), Override()]
+
+ evaluated = ObjectType.processEvent(objs,
+ Event(Event.BASIC_EVENT))
+
+ self.assertEqual(evaluated, 3)
+ self.assertTrue(objs[2].called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py b/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py
new file mode 100644
index 000000000..8b854fca6
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py
@@ -0,0 +1,77 @@
+#!/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
+from random import random
+import sys
+import time
+import threading
+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 ObjectType, Event
+
+
+class Producer(ObjectType):
+
+ def __init__(self):
+ ObjectType.__init__(self)
+ self.data = None
+ self.read = False
+
+ def event(self, event):
+ self.data = random()
+
+ while not self.read:
+ time.sleep(0.01)
+
+ return True
+
+
+class Collector(threading.Thread):
+
+ def __init__(self, objects):
+ threading.Thread.__init__(self)
+ self.max_runs = len(objects)
+ self.objects = objects
+ self.data = []
+
+ def run(self):
+ i = 0
+ while i < self.max_runs:
+ if self.objects[i].data is not None:
+ self.data.append(self.objects[i].data)
+ self.objects[i].read = True
+ i += 1
+ time.sleep(0.01)
+
+
+class TestEventLoopWithThread(unittest.TestCase):
+ '''Communication between a python thread and an simple
+ event loop in C++'''
+
+ def testBasic(self):
+ '''Allowing threads and calling virtuals from C++'''
+ number = 10
+ objs = [Producer() for x in range(number)]
+ thread = Collector(objs)
+
+ thread.start()
+
+ evaluated = ObjectType.processEvent(objs,
+ Event(Event.BASIC_EVENT))
+
+ thread.join()
+
+ producer_data = [x.data for x in objs]
+ self.assertEqual(evaluated, number)
+ self.assertEqual(producer_data, thread.data)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/exception_test.py b/sources/shiboken6/tests/samplebinding/exception_test.py
new file mode 100644
index 000000000..d9e6b377f
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/exception_test.py
@@ -0,0 +1,71 @@
+#!/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 ExceptionTest
+
+
+class CppExceptionTest(unittest.TestCase):
+
+ def testVoid(self):
+ exceptionCount = 0
+ et = ExceptionTest()
+
+ et.voidThrowStdException(False)
+
+ try:
+ et.voidThrowStdException(True)
+ except: # noqa: E722
+ exceptionCount += 1
+
+ et.voidThrowInt(False)
+
+ try:
+ et.voidThrowInt(True)
+ except: # noqa: E722
+ exceptionCount += 1
+
+ self.assertEqual(exceptionCount, 2)
+
+ def testReturnValue(self):
+ exceptionCount = 0
+ et = ExceptionTest()
+
+ result = et.intThrowStdException(False)
+
+ try:
+ result = et.intThrowStdException(True)
+ except: # noqa: E722
+ exceptionCount += 1
+
+ result = et.intThrowInt(False)
+
+ try:
+ result = et.intThrowInt(True) # noqa: F841
+ except: # noqa: E722
+ exceptionCount += 1
+
+ self.assertEqual(exceptionCount, 2)
+
+ def testModifications(self):
+ """PYSIDE-1995, test whether exceptions are propagated
+ when return ownership modifications are generated."""
+ exceptionCount = 0
+ try:
+ et = ExceptionTest.create(True) # noqa: F841
+ except: # noqa: E722
+ exceptionCount += 1
+ self.assertEqual(exceptionCount, 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/filter_test.py b/sources/shiboken6/tests/samplebinding/filter_test.py
new file mode 100644
index 000000000..df805093f
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/filter_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
+
+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 Data, Intersection, Union
+
+
+class TestFilters(unittest.TestCase):
+
+ def testAnd(self):
+
+ f1 = Data(Data.Name, "joe")
+ f2 = Union()
+
+ inter = f1 & f2
+
+ self.assertEqual(type(inter), Intersection)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/global.h b/sources/shiboken6/tests/samplebinding/global.h
new file mode 100644
index 000000000..64806417a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/global.h
@@ -0,0 +1,73 @@
+// 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 "abstract.h"
+#include "blackbox.h"
+#include "bytearray.h"
+#include "bucket.h"
+#include "collector.h"
+#include "complex.h"
+#include "ctorconvrule.h"
+#include "ctparam.h"
+#include "cvlist.h"
+#include "sbkdate.h"
+#include "derived.h"
+#include "derivedusingct.h"
+#include "echo.h"
+#include "exceptiontest.h"
+#include "functions.h"
+#include "implicitconv.h"
+#include "nontypetemplate.h"
+#include "overloadsort.h"
+#include "handle.h"
+#include "injectcode.h"
+#include "list.h"
+#include "listuser.h"
+#include "mapuser.h"
+#include "modelindex.h"
+#include "modifications.h"
+#include "modified_constructor.h"
+#include "multiple_derived.h"
+#include "noimplicitconversion.h"
+#include "nondefaultctor.h"
+#include "objectmodel.h"
+#include "objecttype.h"
+#include "objecttypebyvalue.h"
+#include "objecttypeholder.h"
+#include "objecttypelayout.h"
+#include "objecttypeoperators.h"
+#include "objectview.h"
+#include "oddbool.h"
+#include "onlycopy.h"
+#include "overload.h"
+#include "pairuser.h"
+#include "pen.h"
+#include "photon.h"
+#include "point.h"
+#include "pointf.h"
+#include "pointerholder.h"
+#include "polygon.h"
+#include "privatector.h"
+#include "privatedtor.h"
+#include "protected.h"
+#include "rect.h"
+#include "reference.h"
+#include "renaming.h"
+#include "removednamespaces.h"
+#include "sample.h"
+#include "samplenamespace.h"
+#include "stdcomplex.h"
+#include "simplefile.h"
+#include "size.h"
+#include "snakecasetest.h"
+#include "str.h"
+#include "strlist.h"
+#include "sometime.h"
+#include "templateptr.h"
+#include "transform.h"
+#include "typesystypedef.h"
+#include "virtualmethods.h"
+#include "voidholder.h"
+#include "valueandvirtual.h"
+#include "expression.h"
+#include "filter.h"
diff --git a/sources/shiboken6/tests/samplebinding/handleholder_test.py b/sources/shiboken6/tests/samplebinding/handleholder_test.py
new file mode 100644
index 000000000..af22328c5
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/handleholder_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 case for a class that holds a unknown handle object.
+ Test case for BUG #1105.
+'''
+
+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
+
+
+class HandleHolderTest(unittest.TestCase):
+ def testCreation(self):
+ holder = HandleHolder(HandleHolder.createHandle())
+ holder2 = HandleHolder(HandleHolder.createHandle())
+ self.assertEqual(holder.compare(holder2), False)
+
+ def testTransfer(self):
+ holder = HandleHolder()
+ holder2 = HandleHolder(holder.handle())
+ self.assertTrue(holder.compare(holder2))
+
+ def testUseDefinedType(self):
+ holder = HandleHolder(8)
+ holder2 = HandleHolder(holder.handle2())
+ self.assertTrue(holder.compare2(holder2))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/hashabletype_test.py b/sources/shiboken6/tests/samplebinding/hashabletype_test.py
new file mode 100644
index 000000000..c41f5cc06
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/hashabletype_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 cases for __hash__'''
+
+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 ObjectType, Str
+
+
+class HashableTest(unittest.TestCase):
+
+ def testStrHash(self):
+ h = {}
+ s = Str("Hi")
+ h[s] = 2
+ self.assertTrue(h.get(s), 2)
+
+ def testObjectTypeHash(self):
+ h = {}
+ o = ObjectType()
+ h[o] = 2
+ self.assertTrue(h.get(o), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ignorederefop_test.py b/sources/shiboken6/tests/samplebinding/ignorederefop_test.py
new file mode 100644
index 000000000..feb78d045
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ignorederefop_test.py
@@ -0,0 +1,22 @@
+# 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 Reference
+
+
+class TestLackOfDereferenceOperators (unittest.TestCase):
+ def testIf(self):
+ r = Reference()
+ self.assertFalse(hasattr(r, "__mul__"))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py b/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py
new file mode 100644
index 000000000..081666281
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py
@@ -0,0 +1,136 @@
+#!/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 inplicit converting C++ numeric types.'''
+
+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()
+import sys
+import sample
+
+# Hardcode the limits of the underlying C-types depending on architecture and memory
+# model (taking MSVC using LLP64 into account).
+cIntMin = -2147483648
+cIntMax = 2147483647
+cLongMin = cIntMin
+cLongMax = cIntMax
+maxRepresentableInt = sys.maxsize
+is64bitArchitecture = maxRepresentableInt > 2**32
+if is64bitArchitecture and sys.platform != 'win32':
+ cLongMin = -9223372036854775808
+ cLongMax = 9223372036854775807
+
+
+class NumericTester(unittest.TestCase):
+ '''Helper class for numeric comparison testing'''
+
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
+ def check_value(self, source, expected, callback, desired_type=None):
+ result = callback(source)
+ self.assertEqual(result, expected)
+
+ if desired_type:
+ self.assertEqual(type(result), desired_type)
+
+
+class FloatImplicitConvert(NumericTester):
+ '''Test case for implicit converting C++ numeric types.'''
+
+ def testFloatAsInt(self):
+ '''Float as Int'''
+ self.check_value(3.14, 3, sample.acceptInt, int)
+ self.assertRaises(OverflowError, sample.acceptInt, cIntMax + 400)
+
+ def testFloatAsLong(self):
+ '''Float as Long'''
+ #C++ longs are python ints for us
+ self.check_value(3.14, 3, sample.acceptLong, int)
+ self.assertRaises(OverflowError, sample.acceptLong, cLongMax + 400)
+
+ def testFloatAsUInt(self):
+ '''Float as unsigned Int'''
+ self.check_value(3.14, 3, sample.acceptUInt, int)
+ self.assertRaises(OverflowError, sample.acceptUInt, -3.14)
+
+ def testFloatAsULong(self):
+ '''Float as unsigned Long'''
+ #FIXME Breaking with SystemError "bad argument to internal function"
+ self.check_value(3.14, 3, sample.acceptULong, int)
+ self.assertRaises(OverflowError, sample.acceptULong, -3.14)
+
+ def testFloatAsDouble(self):
+ '''Float as double'''
+ self.check_value(3.14, 3.14, sample.acceptDouble, float)
+
+
+class IntImplicitConvert(NumericTester):
+ '''Test case for implicit converting C++ numeric types.'''
+
+ def testIntAsInt(self):
+ '''Int as Int'''
+ self.check_value(3, 3, sample.acceptInt, int)
+
+ def testIntAsLong(self):
+ '''Int as Long'''
+ self.check_value(3, 3, sample.acceptLong, int)
+
+ # cLongMax goes here as CPython implements int as a C long
+ self.check_value(cLongMax, cLongMax, sample.acceptLong, int)
+ self.check_value(cLongMin, cLongMin, sample.acceptLong, int)
+
+ def testIntAsUInt(self):
+ '''Int as unsigned Int'''
+ self.check_value(3, 3, sample.acceptUInt, int)
+ self.assertRaises(OverflowError, sample.acceptUInt, -3)
+
+ def testIntAsULong(self):
+ '''Int as unsigned Long'''
+ self.check_value(3, 3, sample.acceptULong, int)
+ self.assertRaises(OverflowError, sample.acceptULong, -3)
+
+ def testFloatAsDouble(self):
+ '''Float as double'''
+ self.check_value(3.14, 3.14, sample.acceptDouble, float)
+
+
+class LongImplicitConvert(NumericTester):
+ '''Test case for implicit converting C++ numeric types.'''
+
+ def testLongAsInt(self):
+ '''Long as Int'''
+ self.check_value(24224, 24224, sample.acceptInt, int)
+ self.assertRaises(OverflowError, sample.acceptInt, cIntMax + 20)
+
+ def testLongAsLong(self):
+ '''Long as Long'''
+ self.check_value(2405, 2405, sample.acceptLong, int)
+ self.assertRaises(OverflowError, sample.acceptLong, cLongMax + 20)
+
+ def testLongAsUInt(self):
+ '''Long as unsigned Int'''
+ self.check_value(260, 260, sample.acceptUInt, int)
+ self.assertRaises(OverflowError, sample.acceptUInt, -42)
+
+ def testLongAsULong(self):
+ '''Long as unsigned Long'''
+ self.check_value(128, 128, sample.acceptULong, int)
+ self.assertRaises(OverflowError, sample.acceptULong, -334)
+
+ def testLongAsDouble(self):
+ '''Float as double'''
+ self.check_value(42, 42, sample.acceptDouble, float)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/implicitconv_test.py b/sources/shiboken6/tests/samplebinding/implicitconv_test.py
new file mode 100644
index 000000000..ebafe0c52
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/implicitconv_test.py
@@ -0,0 +1,46 @@
+#!/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 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 ImplicitConv, ObjectType
+
+
+class ImplicitConvTest(unittest.TestCase):
+ '''Test case for implicit conversions'''
+
+ def testImplicitConversions(self):
+ '''Test if overloaded function call decisor takes implicit conversions into account.'''
+ ic = ImplicitConv.implicitConvCommon(ImplicitConv())
+ self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorNone)
+
+ ic = ImplicitConv.implicitConvCommon(3)
+ self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorOne)
+ self.assertEqual(ic.objId(), 3)
+
+ ic = ImplicitConv.implicitConvCommon(ImplicitConv.CtorThree)
+ self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorThree)
+
+ obj = ObjectType()
+ ic = ImplicitConv.implicitConvCommon(obj)
+ self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorObjectTypeReference)
+
+ ic = ImplicitConv.implicitConvCommon(42.42)
+ self.assertEqual(ic.value(), 42.42)
+
+ ic = ImplicitConv(None)
+ self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorPrimitiveType)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py b/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py
new file mode 100644
index 000000000..28d62486a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py
@@ -0,0 +1,30 @@
+#!/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 finding scope in cases involving inheritance.'''
+
+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 SampleNamespace
+
+
+class ScopeAndInheritanceTest(unittest.TestCase):
+ '''Test cases for finding scope in cases involving inheritance.'''
+
+ def testMethodCorrectlyWrapper(self):
+ '''A method returning a type declared in the scope of the method's
+ class parent must be found and the method correctly exported.'''
+ meth = getattr(SampleNamespace.DerivedFromNamespace, # noqa: F841
+ 'methodReturningTypeFromParentScope')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/injectcode_test.py b/sources/shiboken6/tests/samplebinding/injectcode_test.py
new file mode 100644
index 000000000..f673a7807
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/injectcode_test.py
@@ -0,0 +1,119 @@
+#!/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 std::list container 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 InjectCode
+
+
+class MyInjectCode(InjectCode):
+ def __init__(self):
+ InjectCode.__init__(self)
+ self.multiplier = 2
+
+ def arrayMethod(self, values):
+ return self.multiplier * sum(values)
+
+
+class InjectCodeTest(unittest.TestCase):
+
+ @unittest.skipIf(hasattr(sys, "pypy_version_info"),
+ "PyPy type objects cannot be modified (yet) after creation")
+ def testTypeNativeBeginning_TypeTargetBeginning(self):
+ ic = InjectCode()
+ self.assertEqual(str(ic), "Hi! I'm the inject code dummy class.")
+
+ def testFunctionTargetBeginning_FunctionTargetEnd(self):
+ ic = InjectCode()
+ ret = ic.simpleMethod1(2, 1)
+ self.assertEqual(ret, "4end")
+ ret = ic.simpleMethod1(4, 2)
+ self.assertEqual(ret, "7end")
+
+ def testFunctionTargetBeginning(self):
+ ic = InjectCode()
+ ret = ic.simpleMethod2()
+ self.assertEqual(ret, "_end")
+
+ def testArgsModification(self):
+ ic = InjectCode()
+ ret = ic.overloadedMethod(["1", "2", "3", "4"])
+ self.assertEqual(ret, "1234")
+ ret = ic.overloadedMethod(2, 0.5)
+ self.assertEqual(ret, "2.5")
+ ret = ic.overloadedMethod(6, True)
+ self.assertEqual(ret, "6true")
+
+ def testArgsModification2(self):
+ ic = InjectCode()
+ ret = ic.simpleMethod3(["1", "2", "3", "4"])
+ self.assertEqual(ret, "1234")
+
+ def testArgumentRemovalAndArgumentTypeModification(self):
+ '''A method has its first argument removed and the second modified.'''
+ ic = InjectCode()
+ values = (1, 2, 3, 4, 5)
+ result = ic.arrayMethod(values)
+ self.assertEqual(result, sum(values))
+
+ def testCallVirtualMethodWithArgumentRemovalAndArgumentTypeModification(self):
+ '''A virtual method has its first argument removed and the second modified.'''
+ ic = InjectCode()
+ values = (1, 2, 3, 4, 5)
+ result = ic.callArrayMethod(values)
+ self.assertEqual(result, sum(values))
+
+ def testCallReimplementedVirtualMethodWithArgumentRemovalAndArgumentTypeModification(self):
+ '''Calls a reimplemented virtual method that had its first argument removed
+ and the second modified.'''
+ ic = MyInjectCode()
+ values = (1, 2, 3, 4, 5)
+ result = ic.callArrayMethod(values)
+ self.assertEqual(result, ic.multiplier * sum(values))
+
+ def testUsageOfTypeSystemCheckVariableOnPrimitiveType(self):
+ '''When the sequence item is convertible to an integer -1 is returned,
+ or -2 if its not convertible.'''
+ ic = InjectCode()
+ values = (1, 2, 3, 4, '5', 6.7)
+ result = ic.arrayMethod(values)
+
+ ints = [v for v in values if isinstance(v, int)]
+ floats = [-1 for v in values if isinstance(v, float)]
+ other = [-2 for v in values if not isinstance(v, int) and not isinstance(v, float)]
+ self.assertEqual(result, sum(ints + floats + other))
+
+
+class IntArrayTest(unittest.TestCase):
+ '''Test case for converting python sequence to int array'''
+
+ def testBasic(self):
+ '''Shiboken::sequenceToIntArray - basic case'''
+ args = [1, 2, 3, 4]
+ ic = InjectCode()
+ self.assertEqual(sum(args) + len(args), ic.sumArrayAndLength(args))
+
+ def testEmpty(self):
+ '''Shiboken::sequenceToIntArray - empty sequence'''
+ args = []
+ ic = InjectCode()
+ self.assertEqual(sum(args) + len(args), ic.sumArrayAndLength(args))
+
+ def testWithZero(self):
+ '''Shiboken::sequenceToIntArray - count only up to zero'''
+ args = [1, 2, 0, 3]
+ ic = InjectCode()
+ self.assertEqual(sum([1, 2]) + len([1, 2]), ic.sumArrayAndLength(args))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/innerclass_test.py b/sources/shiboken6/tests/samplebinding/innerclass_test.py
new file mode 100644
index 000000000..721f33483
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/innerclass_test.py
@@ -0,0 +1,23 @@
+#!/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 Derived
+
+
+class TestInnerClass(unittest.TestCase):
+ def testInstaciate(self):
+ d = Derived.SomeInnerClass() # noqa: F841
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/intlist_test.py b/sources/shiboken6/tests/samplebinding/intlist_test.py
new file mode 100644
index 000000000..defa9ca71
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/intlist_test.py
@@ -0,0 +1,80 @@
+#!/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 IntList
+
+
+class IntListTest(unittest.TestCase):
+
+ def testAutoFunctionsToBaseList(self):
+ lst = IntList()
+ self.assertEqual(len(lst), 0)
+ lst.append(10)
+ self.assertEqual(lst[0], 10)
+ lst.append(20)
+ self.assertEqual(lst[1], 20)
+ lst.append(30)
+ self.assertEqual(lst[2], 30)
+ lst[1] = 25
+ self.assertEqual(lst[0], 10)
+ self.assertEqual(lst[1], 25)
+ self.assertEqual(lst[2], 30)
+ self.assertEqual(len(lst), 3)
+
+ def testIntListCtor_NoParams(self):
+ '''IntList constructor receives no parameter.'''
+ il = IntList()
+ self.assertEqual(len(il), 0)
+ self.assertEqual(il.constructorUsed(), IntList.NoParamsCtor)
+
+ def testIntListCtor_int(self):
+ '''IntList constructor receives an integer.'''
+ value = 123
+ il = IntList(value)
+ self.assertEqual(len(il), 1)
+ self.assertEqual(il[0], value)
+ self.assertEqual(il.constructorUsed(), IntList.IntCtor)
+
+ def testIntListCtor_IntList(self):
+ '''IntList constructor receives an IntList object.'''
+ il1 = IntList(123)
+ il2 = IntList(il1)
+ self.assertEqual(len(il1), len(il2))
+ for i in range(len(il1)):
+ self.assertEqual(il1[i], il2[i])
+ self.assertEqual(il2.constructorUsed(), IntList.CopyCtor)
+
+ def testIntListCtor_ListOfInts(self):
+ '''IntList constructor receives an integer list.'''
+ ints = [123, 456]
+ il = IntList(ints)
+ self.assertEqual(len(il), len(ints))
+ for i in range(len(il)):
+ self.assertEqual(il[i], ints[i])
+ self.assertEqual(il.constructorUsed(), IntList.ListOfIntCtor)
+
+ def testIntListAttributeTypeCheck(self):
+ '''Attribute values to IntList.'''
+ il = IntList([0, 1, 2])
+ self.assertEqual(len(il), 3)
+ il[0] = 123
+ self.assertEqual(len(il), 3)
+ self.assertEqual(il[0], 123)
+ il[1] = 432.1
+ self.assertEqual(len(il), 3)
+ self.assertEqual(il[1], int(432.1))
+ self.assertRaises(TypeError, il.__setitem__, 2, '78')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/intwrapper_test.py b/sources/shiboken6/tests/samplebinding/intwrapper_test.py
new file mode 100644
index 000000000..d883adf47
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/intwrapper_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 shiboken_paths import init_paths
+init_paths()
+
+from sample import IntWrapper
+
+
+class IntWrapperTest(unittest.TestCase):
+
+ def testOperators(self):
+ ten1 = IntWrapper(10)
+ ten2 = IntWrapper(10)
+ twenty = IntWrapper(20)
+ self.assertTrue(ten1 == ten2)
+ self.assertTrue(ten1 != twenty)
+ self.assertTrue(ten1 + ten2 == twenty)
+ self.assertTrue(ten1 - ten2 == IntWrapper(0))
+ i = IntWrapper(ten1.toInt())
+ i += ten2
+ self.assertTrue(i == twenty)
+ i -= ten2
+ self.assertTrue(i == ten1)
+
+ def testAddPyMethodDef(self):
+ """Test of added free function (PYSIDE-1905)."""
+ i = IntWrapper(10)
+ self.assertEqual(i.add_ints(10, 20), 30)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py b/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py
new file mode 100644
index 000000000..bb35b2bb1
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/invalid_virtual_return_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 case for returning invalid types in a virtual function'''
+
+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 ObjectModel, ObjectType, ObjectView
+
+import warnings
+
+
+class MyObject(ObjectType):
+ pass
+
+
+class ListModelWrong(ObjectModel):
+
+ def __init__(self, parent=None):
+ ObjectModel.__init__(self, parent)
+ self.obj = 0
+
+ def data(self):
+ warnings.simplefilter('error')
+ # Shouldn't segfault. Must set TypeError
+ return self.obj
+
+
+class ModelWrongReturnTest(unittest.TestCase):
+
+ def testWrongTypeReturn(self):
+ model = ListModelWrong()
+ view = ObjectView(model)
+ self.assertRaises(RuntimeWarning, view.getRawModelData) # calls model.data()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/keep_reference_test.py b/sources/shiboken6/tests/samplebinding/keep_reference_test.py
new file mode 100644
index 000000000..10591fec6
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/keep_reference_test.py
@@ -0,0 +1,63 @@
+#!/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 ObjectModel, ObjectView
+
+
+class TestKeepReference(unittest.TestCase):
+ '''Test case for objects that keep references to other object without
+ owning them (e.g. model/view relationships).'''
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReferenceCounting(self):
+ '''Tests reference count of model-like object referred by view-like objects.'''
+ model1 = ObjectModel()
+ refcount1 = sys.getrefcount(model1)
+ view1 = ObjectView()
+ view1.setModel(model1)
+ self.assertEqual(sys.getrefcount(view1.model()), refcount1 + 1)
+
+ view2 = ObjectView()
+ view2.setModel(model1)
+ self.assertEqual(sys.getrefcount(view2.model()), refcount1 + 2)
+
+ model2 = ObjectModel()
+ view2.setModel(model2)
+ self.assertEqual(sys.getrefcount(view1.model()), refcount1 + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReferenceCountingWhenDeletingReferrer(self):
+ '''Tests reference count of model-like object referred by deceased view-like object.'''
+ model = ObjectModel()
+ refcount1 = sys.getrefcount(model)
+ view = ObjectView()
+ view.setModel(model)
+ self.assertEqual(sys.getrefcount(view.model()), refcount1 + 1)
+
+ del view
+ self.assertEqual(sys.getrefcount(model), refcount1)
+
+ def testReferreedObjectSurvivalAfterContextEnd(self):
+ '''Model-like object assigned to a view-like object must survive
+ after get out of context.'''
+ def createModelAndSetToView(view):
+ model = ObjectModel()
+ model.setObjectName('created model')
+ view.setModel(model)
+ view = ObjectView()
+ createModelAndSetToView(view)
+ model = view.model() # noqa: F841
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/list_test.py b/sources/shiboken6/tests/samplebinding/list_test.py
new file mode 100644
index 000000000..b668bfd90
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/list_test.py
@@ -0,0 +1,104 @@
+#!/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 std::list container 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 ListUser, Point, PointF
+
+
+class ExtendedListUser(ListUser):
+ def __init__(self):
+ ListUser.__init__(self)
+ self.create_list_called = False
+
+ def createList(self):
+ self.create_list_called = True
+ return [2, 3, 5, 7, 13]
+
+
+class ListConversionTest(unittest.TestCase):
+ '''Test case for std::list container conversions'''
+
+ def testReimplementedVirtualMethodCall(self):
+ '''Test if a Python override of a virtual method is correctly called from C++.'''
+ lu = ExtendedListUser()
+ lst = lu.callCreateList()
+ self.assertTrue(lu.create_list_called)
+ self.assertEqual(type(lst), list)
+ for item in lst:
+ self.assertEqual(type(item), int)
+
+ def testPrimitiveConversionInsideContainer(self):
+ '''Test primitive type conversion inside conversible std::list container.'''
+ cpx0 = complex(1.2, 3.4)
+ cpx1 = complex(5.6, 7.8)
+ lst = ListUser.createComplexList(cpx0, cpx1)
+ self.assertEqual(type(lst), list)
+ for item in lst:
+ self.assertEqual(type(item), complex)
+ self.assertEqual(lst, [cpx0, cpx1])
+
+ def testSumListIntegers(self):
+ '''Test method that sums a list of integer values.'''
+ lu = ListUser()
+ lst = [3, 5, 7]
+ result = lu.sumList(lst)
+ self.assertEqual(result, sum(lst))
+
+ def testSumListFloats(self):
+ '''Test method that sums a list of float values.'''
+ lu = ListUser()
+ lst = [3.3, 4.4, 5.5]
+ result = lu.sumList(lst)
+ self.assertEqual(result, sum(lst))
+
+ def testConversionInBothDirections(self):
+ '''Test converting a list from Python to C++ and back again.'''
+ lu = ListUser()
+ lst = [3, 5, 7]
+ lu.setList(lst)
+ result = lu.getList()
+ self.assertEqual(result, lst)
+
+ def testConversionInBothDirectionsWithSimilarContainer(self):
+ '''Test converting a tuple, instead of the expected list,
+ from Python to C++ and back again.'''
+ lu = ListUser()
+ lst = (3, 5, 7)
+ lu.setList(lst)
+ result = lu.getList()
+ self.assertNotEqual(result, lst)
+ self.assertEqual(result, list(lst))
+
+ def testConversionOfListOfObjectsPassedAsArgument(self):
+ '''Calls method with a Python list of wrapped objects to be converted to a C++ list.'''
+ mult = 3
+ pts0 = (Point(1.0, 2.0), Point(3.3, 4.4), Point(5, 6))
+ pts1 = (Point(1.0, 2.0), Point(3.3, 4.4), Point(5, 6))
+ ListUser.multiplyPointList(pts1, mult)
+ for pt0, pt1 in zip(pts0, pts1):
+ self.assertEqual(pt0.x() * mult, pt1.x())
+ self.assertEqual(pt0.y() * mult, pt1.y())
+
+ def testConversionOfInvalidLists(self):
+ mult = 3
+ pts = (Point(1.0, 2.0), 3, Point(5, 6))
+ self.assertRaises(TypeError, ListUser.multiplyPointList, pts, mult)
+
+ def testOverloadMethodReceivingRelatedContainerTypes(self):
+ self.assertEqual(ListUser.ListOfPointF, ListUser.listOfPoints([PointF()]))
+ self.assertEqual(ListUser.ListOfPoint, ListUser.listOfPoints([Point()]))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/lock_test.py b/sources/shiboken6/tests/samplebinding/lock_test.py
new file mode 100644
index 000000000..acd47634a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/lock_test.py
@@ -0,0 +1,78 @@
+#!/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
+
+'''Simple test with a blocking C++ method that should allow python
+ threads to run.'''
+
+import os
+import sys
+import threading
+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 Bucket
+
+
+class Unlocker(threading.Thread):
+
+ def __init__(self, bucket):
+ threading.Thread.__init__(self)
+ self.bucket = bucket
+
+ def run(self):
+ while not self.bucket.locked():
+ pass
+
+ self.bucket.unlock()
+
+
+class MyBucket(Bucket):
+
+ def __init__(self):
+ Bucket.__init__(self)
+
+ def virtualBlockerMethod(self):
+ self.lock()
+ return True
+
+
+class TestLockUnlock(unittest.TestCase):
+
+ def testBasic(self):
+ '''Locking in C++ and releasing in a python thread'''
+ bucket = Bucket()
+ unlocker = Unlocker(bucket)
+
+ unlocker.start()
+ bucket.lock()
+ unlocker.join()
+
+ def testVirtualBlocker(self):
+ '''Same as the basic case but blocker method is a C++ virtual called from C++.'''
+ bucket = Bucket()
+ unlocker = Unlocker(bucket)
+
+ unlocker.start()
+ result = bucket.callVirtualBlockerMethodButYouDontKnowThis()
+ unlocker.join()
+ self.assertTrue(result)
+
+ def testReimplementedVirtualBlocker(self):
+ '''Same as the basic case but blocker method is a C++ virtual reimplemented
+ in Python and called from C++.'''
+ mybucket = MyBucket()
+ unlocker = Unlocker(mybucket)
+
+ unlocker.start()
+ result = mybucket.callVirtualBlockerMethodButYouDontKnowThis()
+ unlocker.join()
+ self.assertTrue(result)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/map_test.py b/sources/shiboken6/tests/samplebinding/map_test.py
new file mode 100644
index 000000000..fa99ad2e7
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/map_test.py
@@ -0,0 +1,63 @@
+#!/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 std::map container 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 MapUser
+
+
+class ExtendedMapUser(MapUser):
+ def __init__(self):
+ MapUser.__init__(self)
+ self.create_map_called = False
+
+ def createMap(self):
+ self.create_map_called = True
+ return {'two': (complex(2.2, 2.2), 2),
+ 'three': (complex(3.3, 3.3), 3),
+ 'five': (complex(5.5, 5.5), 5),
+ 'seven': (complex(7.7, 7.7), 7)}
+
+
+class MapConversionTest(unittest.TestCase):
+ '''Test case for std::map container conversions'''
+
+ def testReimplementedVirtualMethodCall(self):
+ '''Test if a Python override of a virtual method is correctly called from C++.'''
+ mu = ExtendedMapUser()
+ map_ = mu.callCreateMap()
+ self.assertTrue(mu.create_map_called)
+ self.assertEqual(type(map_), dict)
+ for key, value in map_.items():
+ self.assertEqual(type(key), str)
+ self.assertEqual(type(value[0]), complex)
+ self.assertEqual(type(value[1]), int)
+
+ def testConversionInBothDirections(self):
+ '''Test converting a map from Python to C++ and back again.'''
+ mu = MapUser()
+ map_ = {'odds': [2, 4, 6], 'evens': [3, 5, 7], 'primes': [3, 4, 6]}
+ mu.setMap(map_)
+ result = mu.getMap()
+ self.assertEqual(result, map_)
+
+ def testConversionMapIntKeyValueTypeValue(self):
+ '''C++ signature: MapUser::passMapIntValueType(const std::map<int, const ByteArray>&)'''
+ mu = MapUser()
+ map_ = {0: 'string'}
+ result = mu.passMapIntValueType(map_)
+ self.assertEqual(map_, result)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/metaclass_test.py b/sources/shiboken6/tests/samplebinding/metaclass_test.py
new file mode 100644
index 000000000..4d7eeda96
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/metaclass_test.py
@@ -0,0 +1,52 @@
+# 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 Point
+
+
+class MetaA(type):
+ pass
+
+
+class A(object):
+ __metaclass__ = MetaA
+
+
+MetaB = type(Point)
+B = Point
+
+
+class MetaC(MetaA, MetaB):
+ pass
+
+
+class C(A, B):
+ __metaclass__ = MetaC
+
+
+class D(C):
+ pass
+
+
+class TestMetaClass(unittest.TestCase):
+ def testIt(self):
+ w1 = C() # works
+ w1.setX(1)
+ w1.setY(2)
+
+ w2 = D() # should work!
+ w2.setX(3)
+ w2.setY(4)
+
+ w3 = w1 + w2
+ self.assertEqual(w3.x(), 4)
+ self.assertEqual(w3.y(), 6)
diff --git a/sources/shiboken6/tests/samplebinding/mi_virtual_methods_test.py b/sources/shiboken6/tests/samplebinding/mi_virtual_methods_test.py
new file mode 100644
index 000000000..8d324db59
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/mi_virtual_methods_test.py
@@ -0,0 +1,68 @@
+#!/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 virtual methods in multiple inheritance scenarios'''
+
+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 VirtualMethods, ObjectType, Event
+
+
+class ImplementsNone(ObjectType, VirtualMethods):
+ '''Implements no virtual methods'''
+
+ def __init__(self):
+ ObjectType.__init__(self)
+ VirtualMethods.__init__(self)
+
+
+class ImplementsBoth(ObjectType, VirtualMethods):
+ '''Implements ObjectType.event and VirtualMethods.sum1'''
+
+ def __init__(self):
+ ObjectType.__init__(self)
+ VirtualMethods.__init__(self)
+ self.event_processed = False
+
+ def event(self, event):
+ self.event_processed = True
+ return True
+
+ def sum1(self, arg0, arg1, arg2):
+ return (arg0 + arg1 + arg2) * 2
+
+
+class CppVirtualTest(unittest.TestCase):
+ '''Virtual method defined in c++ called from C++'''
+
+ def testCpp(self):
+ '''C++ calling C++ virtual method in multiple inheritance scenario'''
+ obj = ImplementsNone()
+ self.assertTrue(ObjectType.processEvent([obj], Event(Event.BASIC_EVENT)))
+ self.assertRaises(AttributeError, getattr, obj, 'event_processed')
+
+ self.assertEqual(obj.callSum0(1, 2, 3), 6)
+
+
+class PyVirtualTest(unittest.TestCase):
+ '''Virtual method reimplemented in python called from C++'''
+
+ def testEvent(self):
+ '''C++ calling Python reimplementation of virtual in multiple inheritance'''
+ obj = ImplementsBoth()
+ self.assertTrue(ObjectType.processEvent([obj], Event(Event.BASIC_EVENT)))
+ self.assertTrue(obj.event_processed)
+
+ self.assertEqual(obj.callSum1(1, 2, 3), 12)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/mixed_mi_test.py b/sources/shiboken6/tests/samplebinding/mixed_mi_test.py
new file mode 100644
index 000000000..fa8481600
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/mixed_mi_test.py
@@ -0,0 +1,54 @@
+#!/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 multiple inheritance in mixed Python/C++ scenarios'''
+
+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 ObjectType
+
+
+class Base(object):
+ '''Base Python class'''
+
+ def __init__(self):
+ self.name = ''
+
+ def pythonName(self):
+ return self.name
+
+ def setPythonName(self, name):
+ self.name = name
+
+
+class Child(Base, ObjectType):
+ '''Dummy class with mixed parents'''
+
+ def __init__(self):
+ Base.__init__(self)
+ ObjectType.__init__(self)
+
+
+class MixedInheritanceTest(unittest.TestCase):
+
+ def testMixed(self):
+ '''Mixed Python/C++ multiple inheritance'''
+ obj = Child()
+
+ obj.setObjectName('aaa')
+ self.assertEqual(obj.objectName(), 'aaa')
+
+ obj.setPythonName('python')
+ self.assertEqual(obj.pythonName(), 'python')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/modelindex_test.py b/sources/shiboken6/tests/samplebinding/modelindex_test.py
new file mode 100644
index 000000000..e23503eff
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/modelindex_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
+
+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 ModelIndex, ReferentModelIndex, PersistentModelIndex
+
+
+class TestCastOperator(unittest.TestCase):
+
+ def testCastOperatorReturningValue(self):
+ index = PersistentModelIndex()
+ index.setValue(123)
+ self.assertEqual(index.value(), 123)
+ self.assertEqual(index.value(), ModelIndex.getValue(index))
+
+ def testCastOperatorReturningReference(self):
+ index = ReferentModelIndex()
+ index.setValue(123)
+ self.assertEqual(index.value(), 123)
+ self.assertEqual(index.value(), ModelIndex.getValue(index))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/modelview_test.py b/sources/shiboken6/tests/samplebinding/modelview_test.py
new file mode 100644
index 000000000..b5663a04e
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/modelview_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
+
+'''Test case for objects that keep references to other object without owning them
+ (e.g. model/view relationships).'''
+
+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 ObjectModel, ObjectType, ObjectView
+
+
+object_name = 'test object'
+
+
+class MyObject(ObjectType):
+ pass
+
+
+class ListModelKeepsReference(ObjectModel):
+ def __init__(self, parent=None):
+ ObjectModel.__init__(self, parent)
+ self.obj = MyObject()
+ self.obj.setObjectName(object_name)
+
+ def data(self):
+ return self.obj
+
+
+class ListModelDoesntKeepsReference(ObjectModel):
+ def data(self):
+ obj = MyObject()
+ obj.setObjectName(object_name)
+ return obj
+
+
+class ModelViewTest(unittest.TestCase):
+
+ def testListModelDoesntKeepsReference(self):
+ model = ListModelDoesntKeepsReference()
+ view = ObjectView(model)
+ obj = view.getRawModelData()
+ self.assertEqual(type(obj), MyObject)
+ self.assertEqual(obj.objectName(), object_name)
+
+ def testListModelKeepsReference(self):
+ model = ListModelKeepsReference()
+ view = ObjectView(model)
+ obj = view.getRawModelData()
+ self.assertEqual(type(obj), MyObject)
+ self.assertEqual(obj.objectName(), object_name)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/modifications_test.py b/sources/shiboken6/tests/samplebinding/modifications_test.py
new file mode 100644
index 000000000..dced14396
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/modifications_test.py
@@ -0,0 +1,224 @@
+#!/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 method modifications performed as described on type system. '''
+
+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 Modifications, Point, ByteArray
+
+
+class ExtModifications(Modifications):
+ def __init__(self):
+ Modifications.__init__(self)
+ self.multiplier = 3.0
+ self.increment = 10.0
+
+ def name(self):
+ return 'ExtModifications'
+
+ def differenceOfPointCoordinates(self, point):
+ ok, res = Modifications.differenceOfPointCoordinates(self, point)
+ return ok, res * self.multiplier + self.increment
+
+
+class ModificationsTest(unittest.TestCase):
+ '''Test cases for method modifications performed as described on type system. '''
+
+ def setUp(self):
+ self.mods = Modifications()
+
+ def tearDown(self):
+ del self.mods
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testRenamedMethodAvailability(self):
+ '''Test if Modification class really have renamed the 'className'
+ virtual method to 'name'.'''
+ self.assertTrue('className' not in dir(Modifications))
+ self.assertTrue('name' in dir(Modifications))
+
+ def testReimplementationOfRenamedVirtualMethod(self):
+ '''Test if class inheriting from Modification class have the reimplementation
+ of renamed virtual method called.'''
+ em = ExtModifications()
+ self.assertEqual(self.mods.name(), 'Modifications')
+ self.assertEqual(em.name(), 'ExtModifications')
+
+ def testRegularMethodRenaming(self):
+ '''Test if Modifications::cppMultiply was correctly renamed to calculateArea.'''
+ self.assertTrue('cppMultiply' not in dir(Modifications))
+ self.assertTrue('calculateArea' in dir(Modifications))
+ self.assertEqual(self.mods.calculateArea(3, 6), 3 * 6)
+
+ def testRegularMethodRemoval(self):
+ '''Test if 'Modifications::exclusiveCppStuff' was removed from Python bindings.'''
+ self.assertTrue('exclusiveCppStuff' not in dir(Modifications))
+
+ def testArgumentRemoval(self):
+ '''Test if second argument of Modifications::doublePlus(int, int) was removed.'''
+ self.assertRaises(TypeError, self.mods.doublePlus, 3, 7)
+ self.assertEqual(self.mods.doublePlus(7), 14)
+
+ def testDefaultValueRemoval(self):
+ '''Test if default value was removed from first argument of
+ Modifications::increment(int).'''
+ self.assertRaises(TypeError, self.mods.increment)
+ self.assertEqual(self.mods.increment(7), 8)
+
+ def testDefaultValueReplacement(self):
+ '''Test if default values for both arguments of Modifications::power(int, int)
+ were modified.'''
+ # original default values: int power(int base = 1, int exponent = 0);
+ self.assertNotEqual(self.mods.power(4), 1)
+ # modified default values: int power(int base = 2, int exponent = 1);
+ self.assertEqual(self.mods.power(), 2)
+ self.assertEqual(self.mods.power(3), 3)
+ self.assertEqual(self.mods.power(5, 3), 5**3)
+
+ def testSetNewDefaultValue(self):
+ '''Test if default value was correctly set to 10 for first argument of
+ Modifications::timesTen(int).'''
+ self.assertEqual(self.mods.timesTen(7), 70)
+ self.assertEqual(self.mods.timesTen(), 100)
+
+ def testArgumentRemovalAndReturnTypeModificationWithTypesystemTemplates1(self):
+ '''Test modifications to method signature and return value using type
+ system templates (case 1).'''
+ result, ok = self.mods.pointToPair(Point(2, 5))
+ self.assertEqual(type(ok), bool)
+ self.assertEqual(type(result), tuple)
+ self.assertEqual(len(result), 2)
+ self.assertEqual(type(result[0]), float)
+ self.assertEqual(type(result[1]), float)
+ self.assertEqual(result[0], 2.0)
+ self.assertEqual(result[1], 5.0)
+
+ def testArgumentRemovalAndReturnTypeModificationWithTypesystemTemplates2(self):
+ '''Test modifications to method signature and return value using
+ type system templates (case 2).'''
+ result, ok = self.mods.multiplyPointCoordsPlusValue(Point(2, 5), 4.1)
+ self.assertEqual(type(ok), bool)
+ self.assertEqual(type(result), float)
+ self.assertEqual(result, 14.1)
+
+ def testOverloadedMethodModifications(self):
+ '''Tests modifications to an overloaded method'''
+ # overloaded(int, bool[removed], int, double)
+ self.assertEqual(self.mods.overloaded(1, 2, 3.1), Modifications.Overloaded_ibid)
+ # overloaded(int, bool, int[removed,default=321], int)
+ self.assertEqual(self.mods.overloaded(1, True, 2), Modifications.Overloaded_ibii)
+ # the others weren't modified
+ self.assertEqual(self.mods.overloaded(1, True, 2, False), Modifications.Overloaded_ibib)
+ self.assertEqual(self.mods.overloaded(1, False, 2, Point(3, 4)),
+ Modifications.Overloaded_ibiP)
+ self.assertRaises(TypeError, self.mods.overloaded, 1, True, Point(2, 3), Point(4, 5))
+ self.assertEqual(self.mods.over(1, True, Point(2, 3), Point(4, 5)),
+ Modifications.Overloaded_ibPP)
+
+ def testPointArrayModification(self):
+ points = (Point(1, 1), Point(2, 2))
+ summedPoint = Point(1, 1) + Point(2, 2)
+ self.assertEqual(self.mods.sumPointArray(points), summedPoint)
+
+ def testTypeSystemVariableReplacementInFunctionModification(self):
+ ba = ByteArray('12345')
+ self.assertEqual(self.mods.getSize(ba), len(ba))
+ self.assertEqual(self.mods.getSize(ba, 20), 20)
+
+ def testNoNulPointerTag(self):
+ point = Point(12, 34)
+ self.assertEqual(self.mods.sumPointCoordinates(point), 12 + 34)
+ self.assertRaises(TypeError, self.mods.sumPointCoordinates, None)
+
+ def testNonConversionRuleForArgumentWithDefaultValue(self):
+ status, obj = self.mods.nonConversionRuleForArgumentWithDefaultValue()
+ self.assertTrue(status)
+ self.assertEqual(obj, self.mods.getObject())
+ self.assertEqual(obj.objectName(), 'MyObject')
+
+ def testInjectCodeWithConversionVariableForUserPrimitive(self):
+ self.assertTrue(Modifications.invertBoolean(False))
+ self.assertFalse(Modifications.invertBoolean(True))
+
+ def testConversionRuleForReturnType(self):
+ x, y = 11, 2
+ diff = float(abs(x - y))
+ point = Point(x, y)
+
+ ok, res = self.mods.differenceOfPointCoordinates(point)
+ self.assertTrue(isinstance(ok, bool))
+ self.assertTrue(isinstance(res, float))
+ self.assertEqual(res, diff)
+
+ ok, res = self.mods.callDifferenceOfPointCoordinates(point)
+ self.assertTrue(isinstance(ok, bool))
+ self.assertTrue(isinstance(res, float))
+ self.assertEqual(res, diff)
+
+ ok, res = self.mods.differenceOfPointCoordinates(None)
+ self.assertTrue(isinstance(ok, bool))
+ self.assertTrue(isinstance(res, float))
+ self.assertEqual(res, 0.0)
+
+ ok, res = self.mods.callDifferenceOfPointCoordinates(None)
+ self.assertTrue(isinstance(ok, bool))
+ self.assertTrue(isinstance(res, float))
+ self.assertEqual(res, 0.0)
+
+ def testConversionRuleForReturnTypeOnExtendedClass(self):
+ x, y = 11, 2
+ diff = float(abs(x - y))
+ point = Point(x, y)
+ em = ExtModifications()
+
+ ok, res = em.differenceOfPointCoordinates(point)
+ self.assertTrue(isinstance(ok, bool))
+ self.assertTrue(isinstance(res, float))
+ self.assertEqual(res, diff * em.multiplier + em.increment)
+
+ ok, res = em.callDifferenceOfPointCoordinates(point)
+ self.assertTrue(isinstance(ok, bool))
+ self.assertTrue(isinstance(res, float))
+ self.assertEqual(res, diff * em.multiplier + em.increment)
+
+ ok, res = em.differenceOfPointCoordinates(None)
+ self.assertTrue(isinstance(ok, bool))
+ self.assertTrue(isinstance(res, float))
+ self.assertEqual(res, em.increment)
+
+ ok, res = em.callDifferenceOfPointCoordinates(None)
+ self.assertTrue(isinstance(ok, bool))
+ self.assertTrue(isinstance(res, float))
+ self.assertEqual(res, em.increment)
+
+ def testDefaultValueModifications(self):
+ # PSYIDE-1095: setEnumValue() has the default value modified to
+ # calling defaultEnumValue() which returns Modifications.TestEnumValue2.
+ # This used to generated broken code since defaultEnumValue() was
+ # qualified by the enum scope.
+ modifications = Modifications()
+ modifications.setEnumValue()
+ self.assertEqual(modifications.enumValue(), Modifications.TestEnumValue2)
+
+ def testSetGetAttro(self):
+ modifications = Modifications()
+ self.assertFalse(modifications.wasSetAttroCalled())
+ setattr(modifications, 'Foo', 'Bar')
+ self.assertTrue(modifications.wasSetAttroCalled())
+ self.assertEqual(getattr(modifications, 'Foo'), 'Bar')
+ self.assertTrue(modifications.wasGetAttroCalled())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/modified_constructor_test.py b/sources/shiboken6/tests/samplebinding/modified_constructor_test.py
new file mode 100644
index 000000000..9791a3491
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/modified_constructor_test.py
@@ -0,0 +1,28 @@
+#!/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 cases for ConstructorWithModifiedArgument 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 sample import ModifiedConstructor
+
+
+class ConstructorWithModifiedArgumentTest(unittest.TestCase):
+ '''Test cases for ConstructorWithModifiedArgument class.'''
+
+ def testConstructorWithModifiedArgument(self):
+ sampleClass = ModifiedConstructor("10")
+ self.assertTrue(sampleClass.retrieveValue(), 10)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py b/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py
new file mode 100644
index 000000000..dcb487f1a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py
@@ -0,0 +1,233 @@
+#!/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 modified virtual methods.'''
+
+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 VirtualMethods, Str
+
+
+class ExtendedVirtualMethods(VirtualMethods):
+ def __init__(self):
+ VirtualMethods.__init__(self)
+ self.name_called = False
+ self.sum0_called = False
+ self.sum1_called = False
+ self.sum2_called = False
+ self.sum3_called = False
+ self.sum4_called = False
+ self.sumThree_called = False
+ self.callMe_called = 0
+ self.multiplier = 12345
+
+ def sum0(self, a0, a1, a2):
+ self.sum0_called = True
+ return VirtualMethods.sumThree(self, a0, a1, a2) * self.multiplier
+
+ def sumThree(self, a0, a1, a2):
+ self.sumThree_called = True
+ return VirtualMethods.sumThree(self, a0, a1, a2) * self.multiplier
+
+ def sum1(self, a0, a1, a2):
+ self.sum1_called = True
+ return VirtualMethods.sum1(self, a0, a1, a2) * self.multiplier
+
+ def sum2(self, a0, a1):
+ self.sum2_called = True
+ return VirtualMethods.sum2(self, a0, a1) * self.multiplier
+
+ def sum3(self, a0, a1):
+ self.sum3_called = True
+ return VirtualMethods.sum3(self, a0, a1) * self.multiplier
+
+ def sum4(self, a0, a1):
+ self.sum4_called = True
+ return VirtualMethods.sum4(self, a0, a1) * self.multiplier
+
+ def name(self):
+ self.name_called = True
+ return Str('ExtendedVirtualMethods')
+
+ def callMe(self):
+ self.callMe_called += 1
+
+ def getMargins(self):
+ return tuple([m * 2 for m in VirtualMethods.getMargins(self)])
+
+
+class VirtualMethodsTest(unittest.TestCase):
+ '''Test case for modified virtual methods.'''
+
+ def setUp(self):
+ self.vm = VirtualMethods()
+ self.evm = ExtendedVirtualMethods()
+
+ def tearDown(self):
+ del self.vm
+ del self.evm
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testModifiedVirtualMethod0(self):
+ '''Renamed virtual method.'''
+ a0, a1, a2 = 2, 3, 5
+ result0 = self.vm.callSum0(a0, a1, a2)
+ result1 = self.vm.sumThree(a0, a1, a2)
+ self.assertEqual(result0, a0 + a1 + a2)
+ self.assertEqual(result0, result1)
+ self.assertRaises(AttributeError, getattr, self.vm, 'sum0')
+
+ def testReimplementedModifiedVirtualMethod0(self):
+ '''Override of a renamed virtual method.'''
+ a0, a1, a2 = 2, 3, 5
+ result0 = self.vm.callSum0(a0, a1, a2)
+ result1 = self.vm.sumThree(a0, a1, a2)
+ result2 = self.evm.callSum0(a0, a1, a2)
+ self.assertEqual(result0, result1)
+ self.assertEqual(result0 * self.evm.multiplier, result2)
+ self.assertTrue(self.evm.sumThree_called)
+ self.assertFalse(self.evm.sum0_called)
+
+ def testModifiedVirtualMethod1(self):
+ '''Virtual method with three arguments and the last one
+ changed to have the default value set to 1000.'''
+ a0, a1, a2 = 2, 3, 5
+ result0 = self.vm.sum1(a0, a1)
+ self.assertEqual(result0, a0 + a1 + 1000)
+ result1 = self.vm.sum1(a0, a1, a2)
+ result2 = self.vm.callSum1(a0, a1, a2)
+ self.assertEqual(result1, result2)
+
+ def testReimplementedModifiedVirtualMethod1(self):
+ '''Override of the virtual method with three arguments and
+ the last one changed to have the default value set to 1000.'''
+ a0, a1 = 2, 3
+ result0 = self.vm.sum1(a0, a1)
+ result1 = self.evm.callSum1(a0, a1, 1000)
+ self.assertEqual(result0 * self.evm.multiplier, result1)
+ self.assertTrue(self.evm.sum1_called)
+
+ def testModifiedVirtualMethod2(self):
+ '''Virtual method originally with three arguments, the last
+ one was removed and the default value set to 2000.'''
+ a0, a1 = 1, 2
+ result0 = self.vm.sum2(a0, a1)
+ self.assertEqual(result0, a0 + a1 + 2000)
+ result1 = self.vm.sum2(a0, a1)
+ result2 = self.vm.callSum2(a0, a1, 2000)
+ self.assertEqual(result1, result2)
+ self.assertRaises(TypeError, self.vm.sum2, 1, 2, 3)
+
+ def testReimplementedModifiedVirtualMethod2(self):
+ '''Override of the virtual method originally with three arguments,
+ the last one was removed and the default value set to 2000.'''
+ a0, a1 = 1, 2
+ ignored = 54321
+ result0 = self.vm.sum2(a0, a1)
+ result1 = self.evm.callSum2(a0, a1, ignored)
+ self.assertEqual(result0 * self.evm.multiplier, result1)
+ self.assertTrue(self.evm.sum2_called)
+
+ def testModifiedVirtualMethod3(self):
+ '''Virtual method originally with three arguments have the second
+ one removed and replaced by custom code that replaces it by the sum
+ of the first and the last arguments.'''
+ a0, a1 = 1, 2
+ result0 = self.vm.sum3(a0, a1)
+ self.assertEqual(result0, a0 + (a0 + a1) + a1)
+ result1 = self.vm.callSum3(a0, 10, a1)
+ self.assertNotEqual(result0, result1)
+ result2 = self.vm.callSum3(a0, a0 + a1, a1)
+ self.assertEqual(result0, result2)
+ self.assertRaises(TypeError, self.vm.sum3, 1, 2, 3)
+
+ def testReimplementedModifiedVirtualMethod3(self):
+ '''Override of the virtual method originally with three arguments
+ have the second one removed and replaced by custom code that
+ replaces it by the sum of the first and the last arguments.'''
+ a0, a1 = 1, 2
+ ignored = 54321
+ result0 = self.vm.sum3(a0, a1)
+ result1 = self.evm.callSum3(a0, ignored, a1)
+ self.assertEqual(result0 * self.evm.multiplier, result1)
+ self.assertTrue(self.evm.sum3_called)
+
+ def testModifiedVirtualMethod4(self):
+ '''Virtual method originally with three arguments, the
+ last one was removed and the default value set to 3000.'''
+ a0, a1 = 1, 2
+ default_value = 3000
+ result0 = self.vm.sum4(a0, a1)
+ self.assertEqual(result0, a0 + default_value + a1)
+ removed_arg_value = 100
+ result1 = self.vm.callSum4(a0, removed_arg_value, a1)
+ self.assertEqual(result1, a0 + removed_arg_value + a1)
+ self.assertRaises(TypeError, self.vm.sum4, 1, 2, 3)
+
+ def testReimplementedModifiedVirtualMethod4(self):
+ '''Override of the virtual method originally with three arguments,
+ the last one was removed and the default value set to 3000.
+ The method was modified with code injection on the binding override
+ (the one that receives calls from C++ with the original signature
+ and forwards it to Python overrides) that subtracts the value of the
+ second argument (removed in Python) from the value of the first
+ before sending them to Python.'''
+ a0, a1 = 1, 2
+ removed_arg_value = 2011
+ default_value = 3000
+ result = self.evm.callSum4(a0, removed_arg_value, a1)
+ self.assertEqual(result,
+ (a0 - removed_arg_value + a1 + default_value) * self.evm.multiplier)
+ self.assertTrue(self.evm.sum4_called)
+
+ def testOverridenMethodResultModification(self):
+ '''Injected code modifies the result of a call to a virtual
+ method overridden in Python.'''
+ orig_name = self.vm.callName()
+ self.assertEqual(orig_name, 'VirtualMethods')
+ name = self.evm.callName()
+ self.assertEqual(name, 'PimpedExtendedVirtualMethods')
+ self.assertEqual(name, Str('PimpedExtendedVirtualMethods'))
+ self.assertTrue(self.evm.name_called)
+
+ def testInjectCodeCallsPythonVirtualMethodOverride(self):
+ '''When injected code calls the Python override by itself
+ no code for the method call should be generated.'''
+ self.evm.callCallMe()
+ self.assertEqual(self.evm.callMe_called, 1)
+
+ def testAllArgumentsRemoved(self):
+ values = (10, 20, 30, 40)
+ self.vm.setMargins(*values)
+ self.assertEqual(self.vm.getMargins(), values)
+
+ def testAllArgumentsRemovedCallVirtual(self):
+ values = (10, 20, 30, 40)
+ self.vm.setMargins(*values)
+ self.assertEqual(self.vm.callGetMargins(), values)
+
+ def testExtendedAllArgumentsRemoved(self):
+ values = (10, 20, 30, 40)
+ self.evm.setMargins(*values)
+ double = tuple([m * 2 for m in values])
+ self.assertEqual(self.evm.getMargins(), double)
+
+ def testExtendedAllArgumentsRemovedCallVirtual(self):
+ values = (10, 20, 30, 40)
+ self.evm.setMargins(*values)
+ double = tuple([m * 2 for m in values])
+ self.assertEqual(self.evm.callGetMargins(), double)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py b/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py
new file mode 100644
index 000000000..fc6b26c3f
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py
@@ -0,0 +1,97 @@
+#!/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 multiple inheritance'''
+
+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 ObjectType, Point, Str
+
+
+class SimpleUseCase(ObjectType, Str):
+ def __init__(self, name):
+ ObjectType.__init__(self)
+ Str.__init__(self, name)
+
+
+class SimpleUseCaseReverse(Str, ObjectType):
+ def __init__(self, name):
+ ObjectType.__init__(self)
+ Str.__init__(self, name)
+
+
+class SimpleUseCase2(SimpleUseCase):
+ def __init__(self, name):
+ SimpleUseCase.__init__(self, name)
+
+
+class ComplexUseCase(SimpleUseCase2, Point):
+ def __init__(self, name):
+ SimpleUseCase2.__init__(self, name)
+ Point.__init__(self)
+
+
+class ComplexUseCaseReverse(Point, SimpleUseCase2):
+ def __init__(self, name):
+ SimpleUseCase2.__init__(self, name)
+ Point.__init__(self)
+
+
+class MultipleCppDerivedTest(unittest.TestCase):
+ def testInstantiation(self):
+ s = SimpleUseCase("Hi")
+ self.assertEqual(s, "Hi")
+ s.setObjectName(s)
+ self.assertEqual(s.objectName(), "Hi")
+
+ def testInstantiation2(self):
+ s = SimpleUseCase2("Hi")
+ self.assertEqual(s, "Hi")
+ s.setObjectName(s)
+ self.assertEqual(s.objectName(), "Hi")
+
+ def testComplexInstantiation(self):
+ c = ComplexUseCase("Hi")
+ self.assertEqual(c, "Hi")
+ c.setObjectName(c)
+ self.assertEqual(c.objectName(), "Hi")
+ c.setX(2)
+ self.assertEqual(c.x(), 2)
+
+
+class MultipleCppDerivedReverseTest(unittest.TestCase):
+ def testInstantiation(self):
+ s = SimpleUseCaseReverse("Hi")
+ self.assertEqual(s, "Hi")
+ s.setObjectName(s)
+ self.assertEqual(s.objectName(), "Hi")
+
+ def testInstantiation2(self):
+ s = SimpleUseCase2("Hi")
+ self.assertEqual(s, "Hi")
+ s.setObjectName(s)
+ self.assertEqual(s.objectName(), "Hi")
+
+ def testComplexInstantiation(self):
+ # PYSIDE-1564: This test can no longer work because of this MRO:
+ # ('ComplexUseCaseReverse', 'Point', 'SimpleUseCase2', 'SimpleUseCase',
+ # 'ObjectType', 'Str', 'Object', 'object')
+ # By multiple inheritance Point would be called first but has no argument.
+ with self.assertRaises(TypeError):
+ c = ComplexUseCaseReverse("Hi") # noqa: F841
+ # c.setObjectName(c)
+ # self.assertEqual(c.objectName(), "Hi")
+ # c.setX(2);
+ # self.assertEqual(c, Point(2, 0))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/multiple_derived_test.py b/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
new file mode 100644
index 000000000..7497714a8
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
@@ -0,0 +1,223 @@
+#!/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 multiple inheritance'''
+
+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 Base1, Base2
+from sample import MDerived1, MDerived2, MDerived3, MDerived4, MDerived5, SonOfMDerived1
+
+
+class ExtMDerived1(MDerived1):
+ def __init__(self):
+ MDerived1.__init__(self)
+ self.multiplier = 20
+ self.base2Method_called = False
+
+ def base2Method(self):
+ return Base2.base2Method(self) * self.multiplier
+
+
+class MultipleDerivedTest(unittest.TestCase):
+ '''Test cases for multiple inheritance'''
+
+ def testIsInstance(self):
+ '''MDerived1 is instance of its parents Base1 and Base2.'''
+ a = MDerived1()
+ self.assertTrue(isinstance(a, MDerived1))
+ self.assertTrue(isinstance(a, Base1))
+ self.assertTrue(isinstance(a, Base2))
+
+ def testIsSubclass(self):
+ '''MDerived1 is subclass of its parents Base1 and Base2.'''
+ self.assertTrue(issubclass(MDerived1, Base1))
+ self.assertTrue(issubclass(MDerived1, Base2))
+
+ def testCallToFunctionWithBase1ArgumentThatCastsBackToMDerived1(self):
+ '''MDerived1 is passed as an Base1 argument to a method that returns
+ it casted back to MDerived1.'''
+ a = MDerived1()
+ b = MDerived1.transformFromBase1(a)
+ self.assertEqual(a, b)
+
+ def testCallToFunctionWithBase2ArgumentThatCastsBackToMDerived1(self):
+ '''MDerived1 is passed as an Base2 argument to a method that returns
+ it casted back to MDerived1.'''
+ a = MDerived1()
+ b = MDerived1.transformFromBase2(a)
+ self.assertEqual(a, b)
+
+ def testPythonClassIsInstance(self):
+ '''Python defined class ExtMDerived1 is instance of its parents
+ MDerived1, Base1 and Base2.'''
+ a = ExtMDerived1()
+ self.assertTrue(isinstance(a, ExtMDerived1))
+ self.assertTrue(isinstance(a, MDerived1))
+ self.assertTrue(isinstance(a, Base1))
+ self.assertTrue(isinstance(a, Base2))
+
+ def testPythonClassIsSubclass(self):
+ '''Python defined class ExtMDerived1 is subclass of its parents
+ MDerived1, Base1 and Base2.'''
+ self.assertTrue(issubclass(ExtMDerived1, MDerived1))
+ self.assertTrue(issubclass(ExtMDerived1, Base1))
+ self.assertTrue(issubclass(ExtMDerived1, Base2))
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived1ToBases(self):
+ '''MDerived1 is casted by C++ to its parents and the binding must return the
+ MDerived1 wrapper.'''
+ a = MDerived1()
+ refcnt = sys.getrefcount(a)
+ b1 = a.castToBase1()
+ b2 = a.castToBase2()
+ self.assertTrue(isinstance(b1, MDerived1))
+ self.assertTrue(isinstance(b2, MDerived1))
+ self.assertEqual(a, b1)
+ self.assertEqual(a, b2)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromExtMDerived1ToMDerived1Bases(self):
+ '''Python defined class ExtMDerived1 is casted by C++ to MDerived1 parents
+ and the binding must return the correct ExtMDerived1 instance.'''
+ a = ExtMDerived1()
+ refcnt = sys.getrefcount(a)
+ b1 = a.castToBase1()
+ self.assertTrue(isinstance(b1, MDerived1))
+ self.assertTrue(isinstance(b1, ExtMDerived1))
+ b2 = a.castToBase2()
+ self.assertTrue(isinstance(b2, MDerived1))
+ self.assertTrue(isinstance(b2, ExtMDerived1))
+ self.assertEqual(a, b1)
+ self.assertEqual(a, b2)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromSonOfMDerived1ToBases(self):
+ '''SonOfMDerived1 is casted by C++ to its parents and the binding must return
+ the SonOfMDerived1 wrapper.'''
+ a = SonOfMDerived1()
+ refcnt = sys.getrefcount(a)
+ md1 = a.castToMDerived1()
+ b1 = a.castToBase1()
+ b2 = a.castToBase2()
+ self.assertTrue(isinstance(md1, SonOfMDerived1))
+ self.assertTrue(isinstance(b2, SonOfMDerived1))
+ self.assertTrue(isinstance(b2, SonOfMDerived1))
+ self.assertEqual(a, md1)
+ self.assertEqual(a, b1)
+ self.assertEqual(a, b2)
+ self.assertEqual(sys.getrefcount(a), refcnt + 3)
+
+ def testReimplementedBase2VirtualMethodOnClassInheritingFromMDerived1(self):
+ a = ExtMDerived1()
+ value = a.base2Method()
+ self.assertTrue(value, Base2.base2Method(a) * a.multiplier)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived2ToBases(self):
+ '''MDerived2 is casted by C++ to its parents and the binding must
+ return the MDerived2 wrapper.'''
+ a = MDerived2()
+ refcnt = sys.getrefcount(a)
+ b3 = a.castToBase3()
+ b4 = a.castToBase4()
+ b5 = a.castToBase5()
+ b6 = a.castToBase6()
+ self.assertTrue(isinstance(b3, MDerived2))
+ self.assertTrue(isinstance(b4, MDerived2))
+ self.assertTrue(isinstance(b5, MDerived2))
+ self.assertTrue(isinstance(b6, MDerived2))
+ self.assertEqual(a, b3)
+ self.assertEqual(a, b4)
+ self.assertEqual(a, b5)
+ self.assertEqual(a, b6)
+ self.assertEqual(sys.getrefcount(a), refcnt + 4)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived3ToBases(self):
+ '''MDerived3 is casted by C++ to its parents and the binding must
+ return the MDerived3 wrapper.'''
+ a = MDerived3()
+ refcnt = sys.getrefcount(a)
+ md1 = a.castToMDerived1()
+ md2 = a.castToMDerived2()
+ b1 = a.castToBase1()
+ b2 = a.castToBase2()
+ b3 = a.castToBase3()
+ b4 = a.castToBase4()
+ b5 = a.castToBase5()
+ b6 = a.castToBase6()
+ self.assertTrue(isinstance(md1, MDerived3))
+ self.assertTrue(isinstance(md2, MDerived3))
+ self.assertTrue(isinstance(b1, MDerived3))
+ self.assertTrue(isinstance(b2, MDerived3))
+ self.assertTrue(isinstance(b3, MDerived3))
+ self.assertTrue(isinstance(b4, MDerived3))
+ self.assertTrue(isinstance(b5, MDerived3))
+ self.assertTrue(isinstance(b6, MDerived3))
+ self.assertEqual(a, md1)
+ self.assertEqual(a, md2)
+ self.assertEqual(a, b1)
+ self.assertEqual(a, b2)
+ self.assertEqual(a, b3)
+ self.assertEqual(a, b4)
+ self.assertEqual(a, b5)
+ self.assertEqual(a, b6)
+ self.assertEqual(sys.getrefcount(a), refcnt + 8)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived4ToBases(self):
+ '''MDerived4 is casted by C++ to its parents and the binding must
+ return the MDerived4 wrapper.'''
+ a = MDerived4()
+ refcnt = sys.getrefcount(a)
+ b3 = a.castToBase3()
+ b4 = a.castToBase4()
+ self.assertTrue(isinstance(b3, MDerived4))
+ self.assertTrue(isinstance(b4, MDerived4))
+ self.assertEqual(a, b3)
+ self.assertEqual(a, b4)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived5ToBases(self):
+ '''MDerived5 is casted by C++ to its parents and the binding must
+ return the MDerived5 wrapper.'''
+ a = MDerived5()
+ refcnt = sys.getrefcount(a)
+ b3 = a.castToBase3()
+ b4 = a.castToBase4()
+ self.assertTrue(isinstance(b3, MDerived5))
+ self.assertTrue(isinstance(b4, MDerived5))
+ self.assertEqual(a, b3)
+ self.assertEqual(a, b4)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCastFromMDerived3ToBase3(self):
+ '''MDerived3 is casted by C++ to Base3 grandparent using both the inherited
+ and reimplement castToBase3 methods.'''
+ a = MDerived3()
+ refcnt = sys.getrefcount(a)
+ b3_reimplemented = a.castToBase3()
+ b3_inherited = MDerived2.castToBase3(a)
+ self.assertTrue(isinstance(b3_reimplemented, MDerived3))
+ self.assertTrue(isinstance(b3_inherited, MDerived3))
+ self.assertEqual(a, b3_reimplemented)
+ self.assertEqual(a, b3_inherited)
+ self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/namespace_test.py b/sources/shiboken6/tests/samplebinding/namespace_test.py
new file mode 100644
index 000000000..64a6792ac
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/namespace_test.py
@@ -0,0 +1,68 @@
+#!/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 std::map container 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 SampleNamespace
+from shiboken_test_helper import objectFullname
+
+from shibokensupport.signature import get_signature
+
+# For tests of invisible namespaces, see
+# enumfromremovednamespace_test.py / removednamespaces.h
+
+
+class TestVariablesUnderNamespace(unittest.TestCase):
+ def testIt(self):
+ self.assertEqual(SampleNamespace.variableInNamespace, 42)
+
+
+class TestClassesUnderNamespace(unittest.TestCase):
+ def testIt(self):
+ c1 = SampleNamespace.SomeClass() # noqa F841
+ e1 = SampleNamespace.SomeClass.ProtectedEnum() # noqa F841
+ c2 = SampleNamespace.SomeClass.SomeInnerClass() # noqa F841
+ e2 = SampleNamespace.SomeClass.SomeInnerClass.ProtectedEnum() # noqa F841
+ c3 = SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough() # noqa F841
+ e3 = SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum(0) # noqa F841
+
+ def testFunctionAddedOnNamespace(self):
+ res = SampleNamespace.ImInsideANamespace(2, 2)
+ self.assertEqual(res, 4)
+
+ def testTpNames(self):
+ self.assertEqual(str(SampleNamespace.SomeClass),
+ "<class 'sample.SampleNamespace.SomeClass'>")
+ self.assertEqual(str(SampleNamespace.SomeClass.ProtectedEnum),
+ "<enum 'ProtectedEnum'>")
+ self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.ProtectedEnum),
+ "<enum 'ProtectedEnum'>")
+ self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough),
+ "<class 'sample.SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough'>") # noqa: E501
+ self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum), # noqa: E501
+ "<enum 'NiceEnum'>")
+
+ # Test if enum inside of class is correct represented
+ an = objectFullname(get_signature(SampleNamespace.enumInEnumOut).parameters['in_'].annotation) # noqa: E501
+ self.assertEqual(an, "sample.SampleNamespace.InValue")
+ an = objectFullname(get_signature(SampleNamespace.enumAsInt).parameters['value'].annotation)
+ self.assertEqual(an, "sample.SampleNamespace.SomeClass.PublicScopedEnum")
+
+ def testInlineNamespaces(self):
+ cls = SampleNamespace.ClassWithinInlineNamespace()
+ cls.setValue(SampleNamespace.EWIN_Value1)
+ self.assertEqual(cls.value(), SampleNamespace.EWIN_Value1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/newdivision_test.py b/sources/shiboken6/tests/samplebinding/newdivision_test.py
new file mode 100644
index 000000000..0e7dfbee1
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/newdivision_test.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 shiboken_paths import init_paths
+init_paths()
+
+from sample import Point
+
+
+class TestNewDivision(unittest.TestCase):
+
+ def testIt(self):
+ p = Point(4, 4)
+ p2 = p / 2
+ self.assertEqual(p2, Point(2, 2))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/nondefaultctor_test.py b/sources/shiboken6/tests/samplebinding/nondefaultctor_test.py
new file mode 100644
index 000000000..bc8d29e50
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/nondefaultctor_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 ...'''
+
+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 NonDefaultCtor
+
+
+class DerivedNonDefaultCtor (NonDefaultCtor):
+ def returnMyselfVirtual(self):
+ return NonDefaultCtor(self.value() + 1)
+
+
+class AnotherDerivedNonDefaultCtor (NonDefaultCtor):
+ def __init__(self, some_string):
+ pass
+
+
+class NonDefaultCtorTest(unittest.TestCase):
+
+ def testNonDefaultCtor(self):
+ c = NonDefaultCtor(2)
+ # these functions returns NonDefaultCtor by value, so a PyObjecy is created every time
+ self.assertNotEqual(c.returnMyself(), c)
+ self.assertEqual(c.returnMyself().value(), 2)
+ self.assertNotEqual(c.returnMyself(3), c)
+ self.assertEqual(c.returnMyself(3).value(), 2)
+ self.assertNotEqual(c.returnMyself(4, c), c)
+ self.assertEqual(c.returnMyself(4, c).value(), 2)
+
+ def testVirtuals(self):
+ c = DerivedNonDefaultCtor(3)
+ # these functions returns NonDefaultCtor by value, so a PyObjecy is created every time
+ self.assertNotEqual(c.returnMyselfVirtual(), c)
+ self.assertEqual(c.returnMyselfVirtual().value(), 4)
+ self.assertEqual(c.callReturnMyselfVirtual().value(), 4)
+
+ def testCtorOverload(self):
+ c = AnotherDerivedNonDefaultCtor("testing") # noqa: F841
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py b/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py
new file mode 100644
index 000000000..a10547728
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py
@@ -0,0 +1,41 @@
+#!/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
+
+hasNumPy = False
+
+try:
+ import numpy
+ hasNumPy = True
+except ImportError:
+ pass
+
+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 IntArray2, IntArray3
+
+
+class NonTypeTemplateTest(unittest.TestCase):
+
+ def testNonTypeTemplate(self):
+ array2 = IntArray2(3)
+ self.assertEqual(array2.sum(), 6)
+ array3 = IntArray3(5)
+ self.assertEqual(array3.sum(), 15)
+
+ def testArrayInitializer(self):
+ if not hasNumPy:
+ return
+ array3 = IntArray3(numpy.array([1, 2, 3], dtype='int32'))
+ self.assertEqual(array3.sum(), 6)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/nonzero_test.py b/sources/shiboken6/tests/samplebinding/nonzero_test.py
new file mode 100644
index 000000000..7be239fc4
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/nonzero_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
+
+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 Color, Brush
+
+
+class TestNonZeroOperator(unittest.TestCase):
+ def testColor(self):
+ """Color has a Qt-style isNull()"""
+ c = Color()
+ self.assertFalse(c)
+ c = Color(2)
+ self.assertTrue(c)
+
+ def testBrush(self):
+ """Brush enables its operator bool in the typesystem XML"""
+ b = Brush()
+ self.assertFalse(b)
+ b = Brush(Color(2))
+ self.assertTrue(b)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/numericaltypedef_test.py b/sources/shiboken6/tests/samplebinding/numericaltypedef_test.py
new file mode 100644
index 000000000..f714a4fc8
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/numericaltypedef_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
+
+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 SizeF
+
+
+class NumericalTypedefTest(unittest.TestCase):
+
+ def testNumericalTypedefExact(self):
+ width, height = (1.1, 2.2)
+ size = SizeF(width, height)
+ self.assertEqual(size.width(), width)
+ self.assertEqual(size.height(), height)
+
+ def testNumericalTypedefConvertible(self):
+ width, height = (1, 2)
+ size = SizeF(width, height)
+ self.assertEqual(size.width(), float(width))
+ self.assertEqual(size.height(), float(height))
+
+ def testNumericalTypedefOfUnsignedShort(self):
+ self.assertEqual(SizeF.passTypedefOfUnsignedShort(123), 123)
+ self.assertEqual(SizeF.passTypedefOfUnsignedShort(321), 321)
+ self.assertNotEqual(SizeF.passTypedefOfUnsignedShort(123), 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/numpy_test.py b/sources/shiboken6/tests/samplebinding/numpy_test.py
new file mode 100644
index 000000000..42094a463
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/numpy_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 sys
+
+try:
+ import sysconfig
+ if bool(sysconfig.get_config_var('Py_DEBUG')):
+ sys.exit(0)
+ import numpy
+except: # noqa: E722
+ sys.exit(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 PointF
+
+
+class TestNumpyTypes(unittest.TestCase):
+
+ def testNumpyConverted(self):
+ x, y = (0.1, 0.2)
+ p = PointF(float(numpy.float32(x)), float(numpy.float32(y)))
+ self.assertAlmostEqual(p.x(), x)
+ self.assertAlmostEqual(p.y(), y)
+
+ def testNumpyAsIs(self):
+ x, y = (0.1, 0.2)
+ p = PointF(numpy.float32(x), numpy.float32(y))
+ self.assertAlmostEqual(p.x(), x)
+ self.assertAlmostEqual(p.y(), y)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttype_test.py b/sources/shiboken6/tests/samplebinding/objecttype_test.py
new file mode 100644
index 000000000..ead68ba13
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/objecttype_test.py
@@ -0,0 +1,110 @@
+#!/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 ObjectType class of object-type with privates copy constructor and = operator.'''
+
+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()
+import sys
+
+from sample import ObjectType, Str
+from shiboken6 import Shiboken
+
+
+class ObjectTypeTest(unittest.TestCase):
+ '''Test cases ObjectType class of object-type with privates copy constructor and = operator.'''
+
+ def testObjectTypeSetObjectNameWithStrVariable(self):
+ '''ObjectType.setObjectName with Str variable as argument.'''
+ s = Str('object name')
+ o = ObjectType()
+ o.setObjectName(s)
+ self.assertEqual(str(o.objectName()), str(s))
+
+ def testObjectTypeSetObjectNameWithStrInstantiation(self):
+ '''ObjectType.setObjectName with Str instantiation as argument.'''
+ s = 'object name'
+ o = ObjectType()
+ o.setObjectName(Str(s))
+ self.assertEqual(str(o.objectName()), s)
+
+ def testObjectTypeSetObjectNameWithPythonString(self):
+ '''ObjectType.setObjectName with Python string as argument.'''
+ o = ObjectType()
+ o.setObjectName('object name')
+ self.assertEqual(str(o.objectName()), 'object name')
+
+ def testNullOverload(self):
+ o = ObjectType()
+ o.setObject(None)
+ self.assertEqual(o.callId(), 0)
+ o.setNullObject(None)
+ self.assertEqual(o.callId(), 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testParentFromCpp(self):
+ o = ObjectType()
+ self.assertEqual(sys.getrefcount(o), 2)
+ o.getCppParent().setObjectName('parent')
+ self.assertEqual(sys.getrefcount(o), 3)
+ o.getCppParent().setObjectName('parent')
+ self.assertEqual(sys.getrefcount(o), 3)
+ o.getCppParent().setObjectName('parent')
+ self.assertEqual(sys.getrefcount(o), 3)
+ o.getCppParent().setObjectName('parent')
+ self.assertEqual(sys.getrefcount(o), 3)
+ o.getCppParent().setObjectName('parent')
+ self.assertEqual(sys.getrefcount(o), 3)
+ o.destroyCppParent()
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ def testNextInFocusChainCycle(self):
+ parent = ObjectType()
+ child = ObjectType(parent)
+ next_focus = child.nextInFocusChain() # noqa: F841
+
+ Shiboken.invalidate(parent)
+
+ def testNextInFocusChainCycleList(self):
+ '''As above but in for a list of objects'''
+ parents = []
+ children = []
+ focus_chains = []
+ for i in range(10):
+ parent = ObjectType()
+ child = ObjectType(parent)
+ next_focus = child.nextInFocusChain()
+ parents.append(parent)
+ children.append(child)
+ focus_chains.append(next_focus)
+
+ Shiboken.invalidate(parents)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testClassDecref(self):
+ # Bug was that class PyTypeObject wasn't decrefed when instance died
+ before = sys.getrefcount(ObjectType)
+
+ for i in range(1000):
+ obj = ObjectType()
+ Shiboken.delete(obj)
+
+ after = sys.getrefcount(ObjectType)
+
+ self.assertLess(abs(before - after), 5)
+
+ def testInvalidProperty(self):
+ o = ObjectType()
+ with self.assertRaises(AttributeError):
+ o.typo
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py b/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py
new file mode 100644
index 000000000..285e2313b
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py
@@ -0,0 +1,50 @@
+#!/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 ObjectType
+
+
+class NamedArgsTest(unittest.TestCase):
+
+ def testOneArgument(self):
+ p = ObjectType()
+ o = ObjectType(parent=p)
+ self.assertEqual(o.parent(), p)
+
+ def testMoreArguments(self):
+ o = ObjectType()
+
+ o.setObjectSplittedName("", prefix="pys", suffix="ide")
+ self.assertEqual(o.objectName(), "pyside")
+
+ o.setObjectSplittedName("", suffix="ide", prefix="pys")
+ self.assertEqual(o.objectName(), "pyside")
+
+ o.setObjectNameWithSize(name="pyside", size=6)
+ self.assertEqual(o.objectName(), "pyside")
+
+ o.setObjectNameWithSize(size=6, name="pyside")
+ self.assertEqual(o.objectName(), "pyside")
+
+ def testUseDefaultValues(self):
+ o = ObjectType()
+
+ o.setObjectNameWithSize(size=3)
+ self.assertEqual(o.objectName(), "<un") # use name='unknown' default argument
+
+ o.setObjectSplittedName("")
+ self.assertEqual(o.objectName(), "<unknown>") # user prefix='<unk' and suffix='nown>'
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py b/sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py
new file mode 100644
index 000000000..8f74af3ab
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/objecttypebyvalue_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 shiboken_paths import init_paths
+init_paths()
+
+from sample import ObjectTypeByValue
+
+
+class ObjectTypeByValueTest (unittest.TestCase):
+ def testIt(self):
+ factory = ObjectTypeByValue()
+ obj = factory.returnSomeKindOfMe()
+ # This should crash!
+ obj.prop.protectedValueTypeProperty.setX(1.0)
+ # just to make sure it will segfault
+ obj.prop.protectedValueTypeProperty.setY(2.0)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py b/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py
new file mode 100644
index 000000000..677b89281
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py
@@ -0,0 +1,301 @@
+#!/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 cases for ObjectTypeLayout 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 ObjectType, ObjectTypeLayout
+
+
+class ObjectTypeLayoutTest(unittest.TestCase):
+ '''Test cases for ObjectTypeLayout class.'''
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testOwnershipOverride(self):
+ lt = ObjectTypeLayout()
+
+ o1 = ObjectType(lt)
+ o1.setObjectName('o1')
+
+ self.assertEqual(sys.getrefcount(o1), 3)
+ lt.takeChild('o1')
+ self.assertEqual(sys.getrefcount(o1), 2)
+
+ def testSetNullLayout(self):
+ '''ObjectType.setLayout(0).'''
+ o2 = ObjectType()
+ o2.setLayout(None)
+
+ def testSetNullLayoutToObjectTypeCreatedInCpp(self):
+ '''ObjectType.setLayout(0) to object created in C++.'''
+ o1 = ObjectType.create()
+ o1.setLayout(None)
+
+ def testObjectTypeLayout(self):
+ '''ObjectType.setLayout.'''
+ p1 = ObjectType()
+ c1 = ObjectType()
+ c2 = ObjectType()
+ c3 = ObjectType()
+ layout = ObjectTypeLayout()
+ layout.addObject(c1)
+ layout.addObject(c2)
+ layout.addObject(c3)
+ self.assertEqual(c1.parent(), None)
+ self.assertEqual(c2.parent(), None)
+ self.assertEqual(c3.parent(), None)
+
+ p1.setLayout(layout)
+ del p1 # This must kill c1, c2 and c3
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ self.assertRaises(RuntimeError, c1.objectName)
+ self.assertRaises(RuntimeError, c2.objectName)
+ self.assertRaises(RuntimeError, c3.objectName)
+ self.assertRaises(RuntimeError, layout.objectName)
+
+ def testObjectTypeLayoutWithObjectsCreatedInCpp(self):
+ '''ObjectType.setLayout with objects created in C++.'''
+ p1 = ObjectType.create()
+ c1 = ObjectType.create()
+ c2 = ObjectType.create()
+ c3 = ObjectType.create()
+ layout = ObjectTypeLayout()
+ layout.addObject(c1)
+ layout.addObject(c2)
+ layout.addObject(c3)
+ self.assertEqual(c1.parent(), None)
+ self.assertEqual(c2.parent(), None)
+ self.assertEqual(c3.parent(), None)
+
+ p1.setLayout(layout)
+ del p1 # This must kill c1, c2 and c3
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ self.assertRaises(RuntimeError, c1.objectName)
+ self.assertRaises(RuntimeError, c2.objectName)
+ self.assertRaises(RuntimeError, c3.objectName)
+ self.assertRaises(RuntimeError, layout.objectName)
+
+ def testObjectTypeLayoutTransference(self):
+ '''Transfer a layout from one ObjectType to another, so that all the items in
+ the layout get reparented.'''
+ p1 = ObjectType()
+ p2 = ObjectType()
+ c1 = ObjectType()
+ c2 = ObjectType()
+
+ layout = ObjectTypeLayout()
+ layout.addObject(c1)
+ layout.addObject(c2)
+
+ p1.setLayout(layout)
+
+ self.assertEqual(len(p2.children()), 0)
+ self.assertEqual(c1.parent(), p1)
+ self.assertEqual(c2.parent(), p1)
+ self.assertEqual(set(p1.children()), set([c1, c2, layout]))
+
+ p2.setLayout(layout)
+
+ self.assertEqual(len(p1.children()), 0)
+ self.assertEqual(c1.parent(), p2)
+ self.assertEqual(c2.parent(), p2)
+ self.assertEqual(set(p2.children()), set([c1, c2, layout]))
+
+ def testObjectTypeLayoutInsideAnotherLayout(self):
+ '''Adds one ObjectTypeLayout to another and sets the parent to an ObjectType.'''
+ p1 = ObjectType()
+
+ l1 = ObjectTypeLayout()
+ c1 = ObjectType()
+ l1.addObject(c1)
+ c2 = ObjectType()
+ l1.addObject(c2)
+
+ l2 = ObjectTypeLayout()
+ c3 = ObjectType()
+ l2.addObject(c3)
+ c4 = ObjectType()
+ l2.addObject(c4)
+
+ l1.addObject(l2)
+
+ p1.setLayout(l1)
+
+ self.assertEqual(c1.parent(), p1)
+ self.assertEqual(c2.parent(), p1)
+ self.assertEqual(c3.parent(), p1)
+ self.assertEqual(c4.parent(), p1)
+ self.assertEqual(l1.parent(), p1)
+ self.assertEqual(l2.parent(), l1)
+
+ del p1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ self.assertRaises(RuntimeError, c1.objectName)
+ self.assertRaises(RuntimeError, c2.objectName)
+ self.assertRaises(RuntimeError, c3.objectName)
+ self.assertRaises(RuntimeError, c4.objectName)
+ self.assertRaises(RuntimeError, l1.objectName)
+ self.assertRaises(RuntimeError, l2.objectName)
+
+ def testObjectTypeLayoutInsideAnotherLayoutAndEveryoneCreatedInCpp(self):
+ '''Adds one ObjectTypeLayout to another and sets the parent to an ObjectType.
+ All the objects are created in C++.'''
+ p1 = ObjectType.create()
+
+ l1 = ObjectTypeLayout.create()
+ c1 = ObjectType.create()
+ l1.addObject(c1)
+ c2 = ObjectType.create()
+ l1.addObject(c2)
+
+ l2 = ObjectTypeLayout.create()
+ c3 = ObjectType.create()
+ l2.addObject(c3)
+ c4 = ObjectType.create()
+ l2.addObject(c4)
+
+ l1.addObject(l2)
+
+ p1.setLayout(l1)
+
+ self.assertEqual(c1.parent(), p1)
+ self.assertEqual(c2.parent(), p1)
+ self.assertEqual(c3.parent(), p1)
+ self.assertEqual(c4.parent(), p1)
+ self.assertEqual(l1.parent(), p1)
+ self.assertEqual(l2.parent(), l1)
+
+ del p1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ self.assertRaises(RuntimeError, c1.objectName)
+ self.assertRaises(RuntimeError, c2.objectName)
+ self.assertRaises(RuntimeError, c3.objectName)
+ self.assertRaises(RuntimeError, c4.objectName)
+ self.assertRaises(RuntimeError, l1.objectName)
+ self.assertRaises(RuntimeError, l2.objectName)
+
+ def testTransferNestedLayoutsBetweenObjects(self):
+ '''Adds one ObjectTypeLayout to another, sets the parent to an ObjectType
+ and then transfer it to another object.'''
+ p1 = ObjectType()
+ p2 = ObjectType()
+
+ l1 = ObjectTypeLayout()
+ c1 = ObjectType()
+ l1.addObject(c1)
+ c2 = ObjectType()
+ l1.addObject(c2)
+
+ l2 = ObjectTypeLayout()
+ c3 = ObjectType()
+ l2.addObject(c3)
+ c4 = ObjectType()
+ l2.addObject(c4)
+
+ l1.addObject(l2)
+
+ p1.setLayout(l1)
+
+ self.assertEqual(c1.parent(), p1)
+ self.assertEqual(c2.parent(), p1)
+ self.assertEqual(c3.parent(), p1)
+ self.assertEqual(c4.parent(), p1)
+ self.assertEqual(l1.parent(), p1)
+ self.assertEqual(l2.parent(), l1)
+
+ p2.setLayout(l1)
+ del p1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ self.assertEqual(c1.parent(), p2)
+ self.assertEqual(c2.parent(), p2)
+ self.assertEqual(c3.parent(), p2)
+ self.assertEqual(c4.parent(), p2)
+ self.assertEqual(l1.parent(), p2)
+ self.assertEqual(l2.parent(), l1)
+
+ del p2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ self.assertRaises(RuntimeError, c1.objectName)
+ self.assertRaises(RuntimeError, c2.objectName)
+ self.assertRaises(RuntimeError, c3.objectName)
+ self.assertRaises(RuntimeError, c4.objectName)
+ self.assertRaises(RuntimeError, l1.objectName)
+ self.assertRaises(RuntimeError, l2.objectName)
+
+ def testTransferNestedLayoutsBetweenObjectsAndEveryoneCreatedInCpp(self):
+ '''Adds one ObjectTypeLayout to another, sets the parent to an ObjectType and then
+ transfer it to another object. All the objects are created in C++.'''
+ p1 = ObjectType.create()
+ p2 = ObjectType.create()
+
+ l1 = ObjectTypeLayout.create()
+ c1 = ObjectType.create()
+ l1.addObject(c1)
+ c2 = ObjectType.create()
+ l1.addObject(c2)
+
+ l2 = ObjectTypeLayout.create()
+ c3 = ObjectType.create()
+ l2.addObject(c3)
+ c4 = ObjectType.create()
+ l2.addObject(c4)
+
+ l1.addObject(l2)
+
+ p1.setLayout(l1)
+
+ self.assertEqual(c1.parent(), p1)
+ self.assertEqual(c2.parent(), p1)
+ self.assertEqual(c3.parent(), p1)
+ self.assertEqual(c4.parent(), p1)
+ self.assertEqual(l1.parent(), p1)
+ self.assertEqual(l2.parent(), l1)
+
+ p2.setLayout(l1)
+ del p1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ self.assertEqual(c1.parent(), p2)
+ self.assertEqual(c2.parent(), p2)
+ self.assertEqual(c3.parent(), p2)
+ self.assertEqual(c4.parent(), p2)
+ self.assertEqual(l1.parent(), p2)
+ self.assertEqual(l2.parent(), l1)
+
+ del p2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ self.assertRaises(RuntimeError, c1.objectName)
+ self.assertRaises(RuntimeError, c2.objectName)
+ self.assertRaises(RuntimeError, c3.objectName)
+ self.assertRaises(RuntimeError, c4.objectName)
+ self.assertRaises(RuntimeError, l1.objectName)
+ self.assertRaises(RuntimeError, l2.objectName)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py b/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py
new file mode 100644
index 000000000..ceeee6c8d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py
@@ -0,0 +1,42 @@
+#!/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 ObjectTypeOperators
+
+
+class ObjectTypeOperatorsTest(unittest.TestCase):
+
+ def testIt(self):
+ a = ObjectTypeOperators("a")
+ b = ObjectTypeOperators("b")
+ self.assertFalse(a == b)
+ self.assertEqual(a, a < b)
+
+ # this should change a.key() and return nothing.
+ self.assertEqual(None, a > b)
+ self.assertEqual(a.key(), "aoperator>")
+
+ def testPointerOpeators(self):
+ a = ObjectTypeOperators("a")
+ b = ObjectTypeOperators("b") # noqa: F841
+ self.assertEqual(a + "bc", "abc")
+ self.assertEqual("bc" + a, "bca")
+ self.assertEqual("a", a)
+ self.assertEqual(a, "a")
+
+ def testOperatorInjection(self):
+ a = ObjectTypeOperators("a")
+ self.assertNotEqual(a, "b")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py b/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py
new file mode 100644
index 000000000..5fa6f824e
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py
@@ -0,0 +1,31 @@
+#!/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 ObjectTypeHolder
+
+
+class TestObjectTypeReferenceAsVirtualMethodArgument(unittest.TestCase):
+
+ def testBasic(self):
+ holder = ObjectTypeHolder('TheObjectFromC++')
+ self.assertEqual(holder.callPassObjectTypeAsReference(), 'TheObjectFromC++')
+
+ def testExtended(self):
+ class Holder(ObjectTypeHolder):
+ def passObjectTypeAsReference(self, objectType):
+ return objectType.objectName().prepend(('ThisIs'))
+ holder = Holder('TheObjectFromC++')
+ self.assertEqual(holder.callPassObjectTypeAsReference(), 'ThisIsTheObjectFromC++')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/oddbool_test.py b/sources/shiboken6/tests/samplebinding/oddbool_test.py
new file mode 100644
index 000000000..87a8cdb1f
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/oddbool_test.py
@@ -0,0 +1,79 @@
+#!/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 OddBool user's primitive type conversion.'''
+
+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 OddBoolUser, ComparisonTester, SpaceshipComparisonTester
+
+
+class DerivedOddBoolUser (OddBoolUser):
+ def returnMyselfVirtual(self):
+ return OddBoolUser()
+ pass
+
+
+class OddBoolTest(unittest.TestCase):
+
+ def testOddBoolUser(self):
+ obuTrue = OddBoolUser()
+ obuFalse = OddBoolUser()
+ obuTrue.setOddBool(True)
+ self.assertEqual(obuFalse.oddBool(), False)
+ self.assertEqual(obuTrue.oddBool(), True)
+ self.assertEqual(obuTrue.callInvertedOddBool(), False)
+
+ self.assertTrue(obuTrue.oddBool())
+ self.assertFalse(obuFalse.oddBool())
+ self.assertTrue(obuTrue.oddBool() != obuFalse.oddBool())
+
+ self.assertFalse(obuFalse.oddBool())
+ self.assertFalse(obuFalse.oddBool())
+ self.assertTrue(obuTrue.oddBool() != obuFalse.oddBool())
+
+ def testVirtuals(self):
+ dobu = DerivedOddBoolUser()
+ self.assertEqual(dobu.invertedOddBool(), True)
+
+ def testImplicitConversionWithUsersPrimitiveType(self):
+ obu = OddBoolUser(True)
+ self.assertTrue(obu.oddBool())
+ obu = OddBoolUser(False)
+ self.assertFalse(obu.oddBool())
+ cpx = complex(1.0, 0.0)
+ obu = OddBoolUser(cpx)
+ self.assertTrue(obu.oddBool())
+ cpx = complex(0.0, 0.0)
+ obu = OddBoolUser(cpx)
+ self.assertFalse(obu.oddBool())
+
+ def testOddOperators(self):
+ t1 = ComparisonTester(42)
+ t2 = ComparisonTester(42)
+ self.assertEqual(t1, t2)
+
+ def testSpaceshipOperator(self):
+ if not SpaceshipComparisonTester.HasSpaceshipOperator:
+ print("Skipping Spaceship Operator test")
+ return
+ t1 = SpaceshipComparisonTester(42)
+ t2 = SpaceshipComparisonTester(42)
+ self.assertEqual(t1, t2)
+ self.assertTrue(t1 <= t2)
+ self.assertTrue(t1 >= t2)
+ t2 = SpaceshipComparisonTester(43)
+ self.assertTrue(t1 < t2)
+ self.assertFalse(t1 > t2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py b/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py
new file mode 100644
index 000000000..bcb154c52
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py
@@ -0,0 +1,40 @@
+#!/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 OnlyCopy, FriendOfOnlyCopy
+
+
+class ClassWithOnlyCopyCtorTest(unittest.TestCase):
+ def testGetOne(self):
+ obj = FriendOfOnlyCopy.createOnlyCopy(123)
+ self.assertEqual(type(obj), OnlyCopy)
+ self.assertEqual(obj.value(), 123)
+
+ def testGetMany(self):
+ objs = FriendOfOnlyCopy.createListOfOnlyCopy(3)
+ self.assertEqual(type(objs), list)
+ self.assertEqual(len(objs), 3)
+ for value, obj in enumerate(objs):
+ self.assertEqual(obj.value(), value)
+
+ def testPassAsValue(self):
+ obj = FriendOfOnlyCopy.createOnlyCopy(123)
+ self.assertEqual(obj.value(), OnlyCopy.getValue(obj))
+
+ def testPassAsReference(self):
+ obj = FriendOfOnlyCopy.createOnlyCopy(123)
+ self.assertEqual(obj.value(), OnlyCopy.getValueFromReference(obj))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/overflow_test.py b/sources/shiboken6/tests/samplebinding/overflow_test.py
new file mode 100644
index 000000000..84442306a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/overflow_test.py
@@ -0,0 +1,75 @@
+#!/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 overflowing C++ numeric types.'''
+
+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, doubleLongLong, doubleShort, doubleUnsignedInt,
+ doubleUnsignedLongLong)
+
+
+class OverflowTest(unittest.TestCase):
+ '''Test case for overflowing C++ numeric types.'''
+
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
+ def testUnsignedInt(self):
+ '''C++ function receives an unsigned int argument and raise OverflowError
+ if the value is negative.'''
+ val = 100
+ self.assertEqual(doubleUnsignedInt(val), 2 * val)
+ val *= -1
+ self.assertRaises(OverflowError, doubleUnsignedInt, val)
+
+ def testLongLong(self):
+ '''C++ function receives an long long argument and raise OverflowError
+ if the value is negative.'''
+ val = 100
+ self.assertEqual(doubleLongLong(val), 2 * val)
+ val = int(100)
+ self.assertEqual(doubleLongLong(val), 2 * val)
+ val = (2 << 64) + 1
+ self.assertRaises(OverflowError, doubleLongLong, val)
+
+ def testUnsignedLongLong(self):
+ '''C++ function receives an unsigned long long argument and raise OverflowError
+ if the value is negative.'''
+ val = 100
+ self.assertEqual(doubleUnsignedLongLong(val), 2 * val)
+ val = int(100)
+ self.assertEqual(doubleUnsignedLongLong(val), 2 * val)
+ val = -100
+ self.assertRaises(OverflowError, doubleUnsignedLongLong, val)
+ val = int(-200)
+ self.assertRaises(OverflowError, doubleUnsignedLongLong, val)
+
+ def testOverflow(self):
+ '''Calls function with unsigned int parameter using an overflowing value.'''
+ self.assertRaises(OverflowError, doubleUnsignedInt, 42415335332353253)
+ doubleUnsignedInt(0xdeadbeef)
+
+ def testShortOverflow(self):
+ '''Calls function with short parameter using an overflowing value.'''
+ doubleShort(-3)
+ self.assertRaises(OverflowError, doubleShort, 0xFFFF * -1)
+ self.assertRaises(OverflowError, doubleShort, 0xFFFF + 1)
+
+ def testOverflowOnCtor(self):
+ '''Calls object ctor with int parameter using overflowing values.'''
+ self.assertRaises(OverflowError, Point, 42415335332353253, 42415335332353253)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/overload_sorting_test.py b/sources/shiboken6/tests/samplebinding/overload_sorting_test.py
new file mode 100644
index 000000000..060d91510
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/overload_sorting_test.py
@@ -0,0 +1,85 @@
+#!/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 overload sorting'''
+
+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 (CustomOverloadSequence, ImplicitBase, ImplicitConv,
+ ImplicitTarget, SortedOverload)
+
+
+class Dummy(object):
+ pass
+
+
+class SimpleOverloadSorting(unittest.TestCase):
+
+ def setUp(self):
+ self.obj = SortedOverload()
+
+ def testIntDouble(self):
+ '''Overloads with int and double'''
+ self.assertEqual(self.obj.overload(3), "int")
+ self.assertEqual(self.obj.overload(3.14), "double")
+
+ def testImplicitConvert(self):
+ '''Overloads with implicit convertible types'''
+ self.assertEqual(self.obj.overload(ImplicitTarget()), "ImplicitTarget")
+ self.assertEqual(self.obj.overload(ImplicitBase()), "ImplicitBase")
+
+ def testContainer(self):
+ '''Overloads with containers arguments'''
+ self.assertEqual(self.obj.overload([ImplicitBase()]), "list(ImplicitBase)")
+
+ def testPyObject(self):
+ '''Overloads with PyObject args'''
+ self.assertEqual(self.obj.overload(Dummy()), "PyObject")
+
+ def testImplicitOnly(self):
+ '''Passing an implicit convertible object to an overload'''
+ self.assertTrue(self.obj.implicit_overload(ImplicitTarget()))
+
+ def testPyObjectSort(self):
+ self.assertEqual(self.obj.pyObjOverload(1, 2), "int,int")
+ self.assertEqual(self.obj.pyObjOverload(object(), 2), "PyObject,int")
+
+
+class DeepOverloadSorting(unittest.TestCase):
+
+ def setUp(self):
+ self.obj = SortedOverload()
+
+ def testPyObject(self):
+ '''Deep Overload - (int, PyObject *)'''
+ self.assertEqual(self.obj.overloadDeep(1, Dummy()), "PyObject")
+
+ def testImplicit(self):
+ '''Deep Overload - (int, ImplicitBase *)'''
+ self.assertEqual(self.obj.overloadDeep(1, ImplicitBase()), "ImplicitBase")
+
+
+class EnumOverIntSorting(unittest.TestCase):
+ def testEnumOverInt(self):
+ ic = ImplicitConv(ImplicitConv.CtorTwo)
+ self.assertEqual(ic.ctorEnum(), ImplicitConv.CtorTwo)
+
+
+class TestCustomOverloadSequence(unittest.TestCase):
+ '''Ensure the int-overload (returning v + sizeof(v)) is first as specified via
+ overload-number in XML.'''
+ def testCustomOverloadSequence(self):
+ s = CustomOverloadSequence()
+ self.assertEqual(s.overload(42), 46)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/overload_test.py b/sources/shiboken6/tests/samplebinding/overload_test.py
new file mode 100644
index 000000000..62fa8d8d2
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/overload_test.py
@@ -0,0 +1,189 @@
+#!/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 Overload 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 sample import Echo, Overload, Point, PointF, Polygon, Rect, RectF, Size, Str
+
+
+def raisesWithErrorMessage(func, arguments, errorType, errorMsg):
+ '''NOTE: Using 'try' because assertRaisesRegexp is not available
+ to check the error message.'''
+ try:
+ func(*arguments)
+ return False
+ except TypeError as err:
+ return errorMsg in str(err)
+ except Exception:
+ return False
+ return True
+
+
+class OverloadTest(unittest.TestCase):
+ '''Test case for Overload class'''
+
+ def testOverloadMethod0(self):
+ '''Check overloaded method call for signature "overloaded()".'''
+ overload = Overload()
+ self.assertEqual(overload.overloaded(), Overload.Function0)
+
+ def testOverloadMethod1(self):
+ '''Check overloaded method call for signature "overloaded(Size*)".'''
+ overload = Overload()
+ size = Size()
+ self.assertEqual(overload.overloaded(size), Overload.Function1)
+
+ def testOverloadMethod2(self):
+ '''Check overloaded method call for signature "overloaded(Point*, ParamEnum)".'''
+ overload = Overload()
+ point = Point()
+ self.assertEqual(overload.overloaded(point, Overload.Param1), Overload.Function2)
+
+ def testOverloadMethod3(self):
+ '''Check overloaded method call for signature "overloaded(const Point&)".'''
+ overload = Overload()
+ point = Point()
+ self.assertEqual(overload.overloaded(point), Overload.Function3)
+
+ def testDifferentReturnTypes(self):
+ '''Check method calls for overloads with different return types.'''
+ overload = Overload()
+ self.assertEqual(overload.differentReturnTypes(), None)
+ self.assertEqual(overload.differentReturnTypes(Overload.Param1), None)
+ self.assertEqual(overload.differentReturnTypes(Overload.Param0, 13), 13)
+
+ def testIntOverloads(self):
+ overload = Overload()
+ self.assertEqual(overload.intOverloads(2, 3), 2)
+ self.assertEqual(overload.intOverloads(2, 4.5), 3)
+ self.assertEqual(overload.intOverloads(Point(0, 0), 3), 1)
+
+ def testIntDoubleOverloads(self):
+ overload = Overload()
+ self.assertEqual(overload.intDoubleOverloads(1, 2), Overload.Function0)
+ self.assertEqual(overload.intDoubleOverloads(1, 2.0), Overload.Function0)
+ self.assertEqual(overload.intDoubleOverloads(1.0, 2), Overload.Function1)
+ self.assertEqual(overload.intDoubleOverloads(1.0, 2.0), Overload.Function1)
+
+ def testWrapperIntIntOverloads(self):
+ overload = Overload()
+ self.assertEqual(overload.wrapperIntIntOverloads(Point(), 1, 2), Overload.Function0)
+ self.assertEqual(overload.wrapperIntIntOverloads(Polygon(), 1, 2), Overload.Function1)
+
+ def testDrawTextPointAndStr(self):
+ overload = Overload()
+ self.assertEqual(overload.drawText(Point(), Str()), Overload.Function0)
+ self.assertEqual(overload.drawText(Point(), ''), Overload.Function0)
+ self.assertEqual(overload.drawText(PointF(), Str()), Overload.Function1)
+ self.assertEqual(overload.drawText(PointF(), ''), Overload.Function1)
+
+ def testDrawTextRectIntStr(self):
+ overload = Overload()
+ self.assertEqual(overload.drawText(Rect(), 1, Str()), Overload.Function2)
+ self.assertEqual(overload.drawText(Rect(), 1, ''), Overload.Function2)
+ self.assertEqual(overload.drawText(RectF(), 1, Str()), Overload.Function3)
+ self.assertEqual(overload.drawText(RectF(), 1, ''), Overload.Function3)
+
+ def testDrawTextRectFStrEcho(self):
+ overload = Overload()
+ self.assertEqual(overload.drawText(RectF(), Str()), Overload.Function4)
+ self.assertEqual(overload.drawText(RectF(), ''), Overload.Function4)
+ self.assertEqual(overload.drawText(RectF(), Str(), Echo()), Overload.Function4)
+ self.assertEqual(overload.drawText(RectF(), '', Echo()), Overload.Function4)
+ self.assertEqual(overload.drawText(Rect(), Str()), Overload.Function4)
+ self.assertEqual(overload.drawText(Rect(), ''), Overload.Function4)
+ self.assertEqual(overload.drawText(Rect(), Str(), Echo()), Overload.Function4)
+ self.assertEqual(overload.drawText(Rect(), '', Echo()), Overload.Function4)
+
+ def testDrawTextIntIntStr(self):
+ overload = Overload()
+ self.assertEqual(overload.drawText(1, 2, Str()), Overload.Function5)
+ self.assertEqual(overload.drawText(1, 2, ''), Overload.Function5)
+
+ def testDrawTextIntIntIntIntStr(self):
+ overload = Overload()
+ self.assertEqual(overload.drawText(1, 2, 3, 4, 5, Str()), Overload.Function6)
+ self.assertEqual(overload.drawText(1, 2, 3, 4, 5, ''), Overload.Function6)
+
+ def testDrawText2IntIntIntIntStr(self):
+ overload = Overload()
+ self.assertEqual(overload.drawText2(1, 2, 3, 4, 5, Str()), Overload.Function6)
+ self.assertEqual(overload.drawText2(1, 2, 3, 4, 5, ''), Overload.Function6)
+ self.assertEqual(overload.drawText2(1, 2, 3, 4, 5), Overload.Function6)
+ self.assertEqual(overload.drawText2(1, 2, 3, 4), Overload.Function6)
+ self.assertEqual(overload.drawText2(1, 2, 3), Overload.Function6)
+
+ def testDrawText3(self):
+ overload = Overload()
+ self.assertEqual(overload.drawText3(Str(), Str(), Str()), Overload.Function0)
+ self.assertEqual(overload.drawText3('', '', ''), Overload.Function0)
+ self.assertEqual(overload.drawText3(1, 2, 3, 4, 5), Overload.Function1)
+ self.assertEqual(overload.drawText3(1, 2, 3, 4, 5), Overload.Function1)
+
+ def testDrawText3Exception(self):
+ overload = Overload()
+ args = (Str(), Str(), Str(), 4, 5)
+ result = raisesWithErrorMessage(overload.drawText3, args,
+ TypeError, 'called with wrong argument types:')
+ self.assertTrue(result)
+
+ def testDrawText4(self):
+ overload = Overload()
+ self.assertEqual(overload.drawText4(1, 2, 3), Overload.Function0)
+ self.assertEqual(overload.drawText4(1, 2, 3, 4, 5), Overload.Function1)
+
+ def testAcceptSequence(self):
+ # Overload.acceptSequence()
+ overload = Overload()
+ self.assertEqual(overload.acceptSequence(), Overload.Function0)
+
+ def testAcceptSequenceIntInt(self):
+ # Overload.acceptSequence(int,int)
+ overload = Overload()
+ self.assertEqual(overload.acceptSequence(1, 2), Overload.Function1)
+
+ def testAcceptSequenceStrParamEnum(self):
+ # Overload.acceptSequence(Str,Overload::ParamEnum)
+ overload = Overload()
+ self.assertEqual(overload.acceptSequence(''), Overload.Function2)
+ self.assertEqual(overload.acceptSequence('', Overload.Param0), Overload.Function2)
+ self.assertEqual(overload.acceptSequence(Str('')), Overload.Function2)
+ self.assertEqual(overload.acceptSequence(Str(''), Overload.Param0), Overload.Function2)
+
+ def testAcceptSequenceSize(self):
+ # Overload.acceptSequence(Size)
+ overload = Overload()
+ self.assertEqual(overload.acceptSequence(Size()), Overload.Function3)
+
+ def testAcceptSequenceStringList(self):
+ # Overload.acceptSequence(const char**)
+ overload = Overload()
+ strings = ['line 1', 'line 2']
+ self.assertEqual(overload.acceptSequence(strings), Overload.Function4)
+ args = (['line 1', 2], )
+ result = raisesWithErrorMessage(overload.acceptSequence, args,
+ TypeError, 'The argument must be a sequence of strings.')
+ self.assertTrue(result)
+
+ def testAcceptSequencePyObject(self):
+ # Overload.acceptSequence(void*)
+ overload = Overload()
+
+ class Foo(object):
+ pass
+
+ foo = Foo()
+ self.assertEqual(overload.acceptSequence(foo), Overload.Function5)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py b/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py
new file mode 100644
index 000000000..269b97299
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py
@@ -0,0 +1,44 @@
+#!/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 Overload, Str
+
+
+class OverloadTest(unittest.TestCase):
+
+ def testNoArgument(self):
+ overload = Overload()
+ self.assertEqual(overload.strBufferOverloads(), Overload.Function2)
+
+ def testStrArgument(self):
+ overload = Overload()
+ self.assertEqual(overload.strBufferOverloads(Str('')), Overload.Function0)
+ self.assertEqual(overload.strBufferOverloads(Str(''), ''), Overload.Function0)
+ self.assertEqual(overload.strBufferOverloads(Str(''), '', False), Overload.Function0)
+
+ def testStringArgumentAsStr(self):
+ overload = Overload()
+ self.assertEqual(overload.strBufferOverloads('', ''), Overload.Function0)
+ self.assertEqual(overload.strBufferOverloads('', '', False), Overload.Function0)
+
+ def testStringArgumentAsBuffer(self):
+ overload = Overload()
+ self.assertEqual(overload.strBufferOverloads(bytes('', "UTF-8"), 0), Overload.Function1)
+
+ def testBufferArgument(self):
+ overload = Overload()
+ self.assertEqual(overload.strBufferOverloads(bytes('', "UTF-8"), 0), Overload.Function1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py b/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py
new file mode 100644
index 000000000..8a55d3ab8
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py
@@ -0,0 +1,44 @@
+#!/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
+
+'''Wrapper validity tests for arguments.'''
+
+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 Polygon, Point
+
+
+class WrapperValidityOfArgumentsTest(unittest.TestCase):
+ '''Wrapper validity tests for arguments.'''
+
+ def testInvalidArgumentToMethod(self):
+ '''Call to method using invalidated Python wrapper as argument should raise RuntimeError.'''
+ poly = Polygon()
+ Polygon.stealOwnershipFromPython(poly)
+ self.assertRaises(RuntimeError, Polygon.doublePolygonScale, poly)
+
+ def testInvalidArgumentToConstructor(self):
+ '''Call to constructor using invalidated Python wrapper as argument
+ should raise RuntimeError.'''
+ pt = Point(1, 2)
+ Polygon.stealOwnershipFromPython(pt)
+ self.assertRaises(RuntimeError, Polygon, pt)
+
+ def testInvalidArgumentWithImplicitConversion(self):
+ '''Call to method using invalidated Python wrapper to be implicitly converted
+ should raise RuntimeError.'''
+ pt = Point(1, 2)
+ Polygon.stealOwnershipFromPython(pt)
+ self.assertRaises(RuntimeError, Polygon.doublePolygonScale, pt)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py b/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py
new file mode 100644
index 000000000..25c6fea26
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_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
+
+'''Tests for destroy a child object in C++'''
+
+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 ObjectType
+
+
+class DeleteChildInCpp(unittest.TestCase):
+ '''Test case for destroying a child in c++'''
+
+ def testDeleteChild(self):
+ '''Delete child in C++ should invalidate child - using C++ wrapper'''
+ parent = ObjectType()
+ parent.setObjectName('parent')
+ child = ObjectType(parent)
+ child.setObjectName('child')
+
+ parent.killChild('child')
+ self.assertRaises(RuntimeError, child.objectName)
+ self.assertEqual(parent.objectName(), 'parent')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py b/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py
new file mode 100644
index 000000000..3ae186815
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py
@@ -0,0 +1,40 @@
+#!/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 for deleting a child object in python'''
+
+import gc
+import os
+import random
+import string
+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 ObjectType
+
+
+class DeleteChildInPython(unittest.TestCase):
+ '''Test case for deleting (unref) a child in python'''
+
+ def testDeleteChild(self):
+ '''Delete child in python should not invalidate child'''
+ parent = ObjectType()
+ child = ObjectType(parent)
+ name = ''.join(random.sample(string.ascii_letters, 5))
+ child.setObjectName(name)
+
+ del child
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ new_child = parent.children()[0]
+ self.assertEqual(new_child.objectName(), name)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py b/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py
new file mode 100644
index 000000000..8f654639c
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py
@@ -0,0 +1,71 @@
+#!/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 for destroying the parent'''
+
+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 ObjectType
+
+
+class DeleteParentTest(unittest.TestCase):
+ '''Test case for deleting a parent object'''
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testParentDestructor(self):
+ '''Delete parent object should invalidate child'''
+ parent = ObjectType()
+ child = ObjectType()
+ child.setParent(parent)
+
+ refcount_before = sys.getrefcount(child)
+
+ del parent
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertRaises(RuntimeError, child.objectName)
+ self.assertEqual(sys.getrefcount(child), refcount_before - 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testParentDestructorMultipleChildren(self):
+ '''Delete parent object should invalidate all children'''
+ parent = ObjectType()
+ children = [ObjectType() for _ in range(10)]
+
+ for child in children:
+ child.setParent(parent)
+
+ del parent
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ for i, child in enumerate(children):
+ self.assertRaises(RuntimeError, child.objectName)
+ self.assertEqual(sys.getrefcount(child), 4)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRecursiveParentDelete(self):
+ '''Delete parent should invalidate grandchildren'''
+ parent = ObjectType()
+ child = ObjectType(parent)
+ grandchild = ObjectType(child)
+
+ del parent
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertRaises(RuntimeError, child.objectName)
+ self.assertEqual(sys.getrefcount(child), 2)
+ self.assertRaises(RuntimeError, grandchild.objectName)
+ self.assertEqual(sys.getrefcount(grandchild), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py b/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py
new file mode 100644
index 000000000..37b7591e4
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py
@@ -0,0 +1,95 @@
+#!/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
+
+'''Ownership tests for cases of invalidation of Python wrapper after use.'''
+
+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 ObjectType, ObjectTypeDerived, Event
+
+
+class ExtObjectType(ObjectType):
+ def __init__(self):
+ ObjectType.__init__(self)
+ self.type_of_last_event = None
+ self.last_event = None
+
+ def event(self, event):
+ self.last_event = event
+ self.type_of_last_event = event.eventType()
+ return True
+
+
+class MyObjectType (ObjectType):
+ def __init__(self):
+ super(MyObjectType, self).__init__()
+ self.fail = False
+
+ def event(self, ev):
+ self.callInvalidateEvent(ev)
+ try:
+ ev.eventType()
+ except: # noqa: E722
+ self.fail = True
+ raise
+ return True
+
+ def invalidateEvent(self, ev):
+ pass
+
+
+class ExtObjectTypeDerived(ObjectTypeDerived):
+ def __init__(self):
+ ObjectTypeDerived.__init__(self)
+ self.type_of_last_event = None
+ self.last_event = None
+
+ def event(self, event):
+ self.last_event = event
+ self.type_of_last_event = event.eventType()
+ return True
+
+
+class OwnershipInvalidateAfterUseTest(unittest.TestCase):
+ '''Ownership tests for cases of invalidation of Python wrapper after use.'''
+
+ def testInvalidateAfterUse(self):
+ '''In ObjectType.event(Event*) the wrapper object created for Event
+ must me marked as invalid after the method is called.'''
+ eot = ExtObjectType()
+ eot.causeEvent(Event.SOME_EVENT)
+ self.assertEqual(eot.type_of_last_event, Event.SOME_EVENT)
+ self.assertRaises(RuntimeError, eot.last_event.eventType)
+
+ def testObjectInvalidatedAfterUseAsParameter(self):
+ '''Tries to use wrapper invalidated after use as a parameter to another method.'''
+ eot = ExtObjectType()
+ ot = ObjectType()
+ eot.causeEvent(Event.ANY_EVENT)
+ self.assertEqual(eot.type_of_last_event, Event.ANY_EVENT)
+ self.assertRaises(RuntimeError, ot.event, eot.last_event)
+
+ def testit(self):
+ obj = MyObjectType()
+ obj.causeEvent(Event.BASIC_EVENT)
+ self.assertFalse(obj.fail)
+
+ def testInvalidateAfterUseInDerived(self):
+ '''Invalidate was failing in a derived C++ class that also inherited
+ other base classes'''
+ eot = ExtObjectTypeDerived()
+ eot.causeEvent(Event.SOME_EVENT)
+ self.assertEqual(eot.type_of_last_event, Event.SOME_EVENT)
+ self.assertRaises(RuntimeError, eot.last_event.eventType)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py b/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py
new file mode 100644
index 000000000..77b7c576c
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py
@@ -0,0 +1,54 @@
+#!/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 for invalidating a C++ created child that was already on the care of a parent.'''
+
+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 ObjectType, BlackBox
+
+
+class InvalidateChildTest(unittest.TestCase):
+ '''Tests for invalidating a C++ created child that was already on the care of a parent.'''
+
+ def testInvalidateChild(self):
+ '''Invalidating method call should remove child from the care of a parent if it has one.'''
+ parent = ObjectType()
+ child1 = ObjectType(parent)
+ child1.setObjectName('child1')
+ child2 = ObjectType.create()
+ child2.setParent(parent)
+ child2.setObjectName('child2')
+
+ self.assertEqual(parent.children(), [child1, child2])
+
+ bbox = BlackBox()
+
+ # This method steals ownership from Python to C++.
+ bbox.keepObjectType(child1)
+ self.assertEqual(parent.children(), [child2])
+
+ bbox.keepObjectType(child2)
+ self.assertEqual(parent.children(), [])
+
+ del parent
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
+
+ self.assertEqual(child1.objectName(), 'child1')
+ self.assertRaises(RuntimeError, child2.objectName)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py b/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py
new file mode 100644
index 000000000..8cbefc30c
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_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
+
+'''The BlackBox class has cases of ownership transference between Python and C++.'''
+
+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, BlackBox
+
+
+class OwnershipInvalidateNonPolymorphicTest(unittest.TestCase):
+ '''The BlackBox class has cases of ownership transference between Python and C++.'''
+
+ def testOwnershipTransference(self):
+ '''Ownership transference from Python to C++ and back again.'''
+ p1 = Point(10, 20)
+ bb = BlackBox()
+ p1_ticket = bb.keepPoint(p1)
+ self.assertRaises(RuntimeError, p1.x)
+ p1_ret = bb.retrievePoint(p1_ticket)
+ self.assertEqual(p1_ret, Point(10, 20))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py b/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py
new file mode 100644
index 000000000..c721a212c
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py
@@ -0,0 +1,48 @@
+#!/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 for invalidating a parent of other objects.'''
+
+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 ObjectType, BlackBox
+
+
+class InvalidateParentTest(unittest.TestCase):
+ '''Tests for invalidating a parent of other objects.'''
+
+ def testInvalidateParent(self):
+ '''Invalidate parent should invalidate children'''
+ parent = ObjectType.create()
+ child1 = ObjectType(parent)
+ child1.setObjectName("child1")
+ child2 = ObjectType.create()
+ child2.setObjectName("child2")
+ child2.setParent(parent)
+ grandchild1 = ObjectType(child1)
+ grandchild1.setObjectName("grandchild1")
+ grandchild2 = ObjectType.create()
+ grandchild2.setObjectName("grandchild2")
+ grandchild2.setParent(child2)
+ bbox = BlackBox()
+
+ bbox.keepObjectType(parent) # Should invalidate the parent
+
+ self.assertRaises(RuntimeError, parent.objectName)
+ # some children still valid they are wrapper classes
+ self.assertEqual(child1.objectName(), "child1")
+ self.assertRaises(RuntimeError, child2.objectName)
+ self.assertEqual(grandchild1.objectName(), "grandchild1")
+ self.assertRaises(RuntimeError, grandchild2.objectName)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py b/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py
new file mode 100644
index 000000000..304223063
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py
@@ -0,0 +1,111 @@
+#!/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 for object reparenting.'''
+
+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()
+import sys
+
+from sample import ObjectType
+
+
+class ExtObjectType(ObjectType):
+ def __init__(self):
+ ObjectType.__init__(self)
+
+
+class ReparentingTest(unittest.TestCase):
+ '''Tests for object reparenting.'''
+
+ def testReparentedObjectTypeIdentity(self):
+ '''Reparent children from one parent to another.'''
+ object_list = []
+ old_parent = ObjectType()
+ new_parent = ObjectType()
+ for i in range(3):
+ obj = ObjectType()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for child in new_parent.children():
+ self.assertTrue(child in object_list)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReparentWithTheSameParent(self):
+ '''Set the same parent twice to check if the ref continue the same'''
+ obj = ObjectType()
+ parent = ObjectType()
+ self.assertEqual(sys.getrefcount(obj), 2)
+ obj.setParent(parent)
+ self.assertEqual(sys.getrefcount(obj), 3)
+ obj.setParent(parent)
+ self.assertEqual(sys.getrefcount(obj), 3)
+
+ def testReparentedExtObjectType(self):
+ '''Reparent children from one extended parent to another.'''
+ object_list = []
+ old_parent = ExtObjectType()
+ new_parent = ExtObjectType()
+ for i in range(3):
+ obj = ExtObjectType()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for orig, child in zip(object_list, new_parent.children()):
+ self.assertEqual(type(orig), type(child))
+
+ def testReparentedObjectTypeIdentityWithParentsCreatedInCpp(self):
+ '''Reparent children from one parent to another, both created in C++.'''
+ object_list = []
+ old_parent = ObjectType.create()
+ new_parent = ObjectType.create()
+ for i in range(3):
+ obj = ObjectType()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for child in new_parent.children():
+ self.assertTrue(child in object_list)
+
+ def testReparentedObjectTypeIdentityWithChildrenCreatedInCpp(self):
+ '''Reparent children created in C++ from one parent to another.'''
+ object_list = []
+ old_parent = ObjectType()
+ new_parent = ObjectType()
+ for i in range(3):
+ obj = ObjectType.create()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for child in new_parent.children():
+ self.assertTrue(child in object_list)
+
+ def testReparentedObjectTypeIdentityWithParentsAndChildrenCreatedInCpp(self):
+ '''Reparent children from one parent to another. Parents and children are created in C++.'''
+ object_list = []
+ old_parent = ObjectType.create()
+ new_parent = ObjectType.create()
+ for i in range(3):
+ obj = ObjectType.create()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for child in new_parent.children():
+ self.assertTrue(child in object_list)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_transference_test.py b/sources/shiboken6/tests/samplebinding/ownership_transference_test.py
new file mode 100644
index 000000000..0e9f08b72
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/ownership_transference_test.py
@@ -0,0 +1,71 @@
+#!/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
+
+'''The BlackBox class has cases of ownership transference between C++ and Python.'''
+
+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 ObjectType, BlackBox
+
+
+class BlackBoxTest(unittest.TestCase):
+ '''The BlackBox class has cases of ownership transference between C++ and Python.'''
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testOwnershipTransference(self):
+ '''Ownership transference from Python to C++ and back again.'''
+ o1 = ObjectType()
+ o1.setObjectName('object1')
+ o1_refcnt = sys.getrefcount(o1)
+ o2 = ObjectType()
+ o2.setObjectName('object2')
+ o2_refcnt = sys.getrefcount(o2)
+ bb = BlackBox()
+ o1_ticket = bb.keepObjectType(o1) # noqa: F841
+ o2_ticket = bb.keepObjectType(o2)
+ self.assertEqual(set(bb.objects()), set([o1, o2]))
+ self.assertEqual(str(o1.objectName()), 'object1')
+ self.assertEqual(str(o2.objectName()), 'object2')
+ # PySide give +1 ref to object with c++ ownership
+ self.assertEqual(sys.getrefcount(o1), o1_refcnt + 1)
+ self.assertEqual(sys.getrefcount(o2), o2_refcnt + 1)
+ o2 = bb.retrieveObjectType(o2_ticket)
+ self.assertEqual(sys.getrefcount(o2), o2_refcnt)
+ del bb
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertRaises(RuntimeError, o1.objectName)
+ self.assertEqual(str(o2.objectName()), 'object2')
+ self.assertEqual(sys.getrefcount(o2), o2_refcnt)
+
+ def testBlackBoxReleasingUnknownObjectType(self):
+ '''Asks BlackBox to release an unknown ObjectType.'''
+ o1 = ObjectType()
+ o2 = ObjectType() # noqa: F841
+ bb = BlackBox()
+ o1_ticket = bb.keepObjectType(o1) # noqa: F841
+ o3 = bb.retrieveObjectType(-5)
+ self.assertEqual(o3, None)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testOwnershipTransferenceCppCreated(self):
+ '''Ownership transference using a C++ created object.'''
+ o1 = ObjectType.create()
+ o1.setObjectName('object1')
+ o1_refcnt = sys.getrefcount(o1) # noqa: F841
+ bb = BlackBox()
+ o1_ticket = bb.keepObjectType(o1) # noqa: F841
+ self.assertRaises(RuntimeError, o1.objectName)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pair_test.py b/sources/shiboken6/tests/samplebinding/pair_test.py
new file mode 100644
index 000000000..4bd5c697c
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/pair_test.py
@@ -0,0 +1,89 @@
+#!/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 std::pair container 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 PairUser
+
+
+class ExtendedPairUser(PairUser):
+ def __init__(self):
+ PairUser.__init__(self)
+ self.create_pair_called = False
+
+ def createPair(self):
+ self.create_pair_called = True
+ return (7, 13)
+
+
+class PairConversionTest(unittest.TestCase):
+ '''Test case for std::pair container conversions'''
+
+ def testReimplementedVirtualMethodCall(self):
+ '''Test if a Python override of a virtual method is correctly called from C++.'''
+ pu = ExtendedPairUser()
+ pair = pu.callCreatePair()
+ self.assertTrue(pu.create_pair_called)
+ self.assertEqual(type(pair), tuple)
+ self.assertEqual(type(pair[0]), int)
+ self.assertEqual(type(pair[1]), int)
+ self.assertEqual(pair, (7, 13))
+
+ def testPrimitiveConversionInsideContainer(self):
+ '''Test primitive type conversion inside conversible std::pair container.'''
+ cpx0 = complex(1.2, 3.4)
+ cpx1 = complex(5.6, 7.8)
+ cp = PairUser.createComplexPair(cpx0, cpx1)
+ self.assertEqual(type(cp), tuple)
+ self.assertEqual(type(cp[0]), complex)
+ self.assertEqual(type(cp[1]), complex)
+ self.assertEqual(cp, (cpx0, cpx1))
+
+ def testSumPair(self):
+ '''Test method that sums the items of a pair using values of the types
+ expected by C++ (int and double)'''
+ pu = PairUser()
+ pair = (3, 7.13)
+ result = pu.sumPair(pair)
+ self.assertEqual(result, sum(pair))
+
+ def testSumPairDifferentTypes(self):
+ '''Test method that sums the items of a pair using values of types different
+ from the ones expected by C++ (int and double)'''
+ pu = PairUser()
+ pair = (3.3, 7)
+ result = pu.sumPair(pair)
+ self.assertNotEqual(result, sum(pair))
+ self.assertEqual(result, int(pair[0]) + pair[1])
+
+ def testConversionInBothDirections(self):
+ '''Test converting a pair from Python to C++ and the other way around.'''
+ pu = PairUser()
+ pair = (3, 5)
+ pu.setPair(pair)
+ result = pu.getPair()
+ self.assertEqual(result, pair)
+
+ def testConversionInBothDirectionsWithSimilarContainer(self):
+ '''Test converting a list, instead of the expected tuple, from Python to C++
+ and the other way around.'''
+ pu = PairUser()
+ pair = [3, 5]
+ pu.setPair(pair)
+ result = pu.getPair()
+ self.assertNotEqual(result, pair)
+ self.assertEqual(result, tuple(pair))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pen_test.py b/sources/shiboken6/tests/samplebinding/pen_test.py
new file mode 100644
index 000000000..106f3bd61
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/pen_test.py
@@ -0,0 +1,58 @@
+#!/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 <add-function> with const char* as argument'''
+
+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 Color, Pen, SampleNamespace
+
+
+class TestPen(unittest.TestCase):
+ '''Simple test case for Pen.'''
+
+ def testPenWithEmptyConstructor(self):
+ pen = Pen()
+ self.assertEqual(pen.ctorType(), Pen.EmptyCtor)
+
+ def testPenWithEnumConstructor(self):
+ pen = Pen(SampleNamespace.RandomNumber)
+ self.assertEqual(pen.ctorType(), Pen.EnumCtor)
+
+ def testPenWithColorConstructor(self):
+ pen = Pen(Color())
+ self.assertEqual(pen.ctorType(), Pen.ColorCtor)
+
+ def testPenWithCopyConstructor(self):
+ pen = Pen(Pen())
+ self.assertEqual(pen.ctorType(), Pen.CopyCtor)
+
+ def testPenWithIntConvertedToColor(self):
+ pen = Pen(1)
+ self.assertEqual(pen.ctorType(), Pen.ColorCtor)
+ pen.drawLine(0, 0, 5, 5)
+
+ def testPenRenderHintsProperty(self):
+ """Exercise the generated property setter and getters, checking
+ against the C++ getter/setter functions."""
+ pen = Pen(1)
+ self.assertEqual(pen.getRenderHints(), Pen.RenderHints.None_)
+ self.assertEqual(pen.renderHints, Pen.RenderHints.None_)
+ pen.renderHints = Pen.RenderHints.TextAntialiasing
+ self.assertEqual(pen.getRenderHints(), Pen.RenderHints.TextAntialiasing)
+ self.assertEqual(pen.renderHints, Pen.RenderHints.TextAntialiasing)
+ pen.setRenderHints(Pen.RenderHints.Antialiasing)
+ self.assertEqual(pen.getRenderHints(), Pen.RenderHints.Antialiasing)
+ self.assertEqual(pen.renderHints, Pen.RenderHints.Antialiasing)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/point_test.py b/sources/shiboken6/tests/samplebinding/point_test.py
new file mode 100644
index 000000000..f86c0f423
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/point_test.py
@@ -0,0 +1,98 @@
+#!/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 Point 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 sample import Point
+
+
+class PointTest(unittest.TestCase):
+ '''Test case for Point class, including operator overloads.'''
+
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
+ def testConstructor(self):
+ '''Test Point class constructor.'''
+ pt = Point(5.0, 2.3)
+ self.assertEqual(pt.x(), 5.0)
+ self.assertEqual(pt.y(), 2.3)
+
+ def testPlusOperator(self):
+ '''Test Point class + operator.'''
+ pt1 = Point(5.0, 2.3)
+ pt2 = Point(0.5, 3.2)
+ self.assertEqual(pt1 + pt2, Point(5.0 + 0.5, 2.3 + 3.2))
+
+ def testEqualOperator(self):
+ '''Test Point class == operator.'''
+ pt1 = Point(5.0, 2.3)
+ pt2 = Point(5.0, 2.3)
+ pt3 = Point(0.5, 3.2)
+ self.assertTrue(pt1 == pt1)
+ self.assertTrue(pt1 == pt2)
+ self.assertFalse(pt1 == pt3)
+ self.assertFalse(pt1 == object())
+
+ def testNotEqualOperator(self):
+ '''Test Point class != operator.'''
+ pt1 = Point(5.0, 2.3)
+ pt2 = Point(5.0, 2.3)
+ # This test no longer makes sense because we always supply default `==`, `!=`.
+ #self.assertRaises(NotImplementedError, pt1.__ne__, pt2)
+ # Since we use the default identity comparison, this results in `!=` .
+ self.assertTrue(pt1 != pt2)
+
+ def testReturnNewCopy(self):
+ '''Point returns a copy of itself.'''
+ pt1 = Point(1.1, 2.3)
+ pt2 = pt1.copy()
+ self.assertEqual(pt1, pt2)
+ pt2 += pt1
+ self.assertFalse(pt1 == pt2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReturnConstPointer(self):
+ '''Point returns a const pointer for itself.'''
+ pt1 = Point(5.0, 2.3)
+ refcount1 = sys.getrefcount(pt1)
+ pt2 = pt1.getSelf()
+ self.assertEqual(pt1, pt2)
+ self.assertEqual(sys.getrefcount(pt1), refcount1 + 1)
+ self.assertEqual(sys.getrefcount(pt1), sys.getrefcount(pt2))
+
+ def testUintOverflow(self):
+ pt1 = Point(0.0, 0.0)
+ self.assertRaises(OverflowError, pt1.setXAsUint, 840835495615213080)
+ self.assertEqual(pt1.x(), 0.0)
+
+ def testAddedOperator(self):
+ p = Point(0.0, 0.0)
+ r = p - 'Hi'
+ self.assertEqual(r, 'Hi')
+
+ # now the reverse op.
+ r = 'Hi' - p
+ self.assertEqual(r, 'Hi')
+
+ def testModifiedMethod(self):
+ pt1 = Point(0.0, 0.0)
+ pt2 = Point(10.0, 10.0)
+ expected = Point((pt1.x() + pt2.x()) / 2.0, (pt1.y() + pt2.y()) / 2.0)
+ self.assertEqual(pt1.midpoint(pt2), expected)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pointerholder_test.py b/sources/shiboken6/tests/samplebinding/pointerholder_test.py
new file mode 100644
index 000000000..633525a9c
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/pointerholder_test.py
@@ -0,0 +1,41 @@
+#!/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 a class that holds an arbitraty pointer and is modified to hold an PyObject.'''
+
+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 PointerHolder
+
+
+class TestPointerHolder(unittest.TestCase):
+ '''Test cases for a class that holds an arbitraty pointer and
+ is modified to hold an PyObject.'''
+
+ def testStoringAndRetrievingPointer(self):
+ ph = PointerHolder('Hello')
+ self.assertEqual(ph.pointer(), 'Hello')
+ a = (1, 2, 3)
+ ph = PointerHolder(a)
+ self.assertEqual(ph.pointer(), a)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReferenceCounting(self):
+ '''Test reference counting when retrieving data with PointerHolder.pointer().'''
+ a = (1, 2, 3)
+ refcnt = sys.getrefcount(a)
+ ph = PointerHolder(a)
+ ptr = ph.pointer() # noqa: F841
+ self.assertEqual(sys.getrefcount(a), refcnt + 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py b/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py
new file mode 100644
index 000000000..4da1a89c6
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py
@@ -0,0 +1,56 @@
+#!/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
+
+"""
+pointerprimitivetype_test.py
+
+check that the primitive types are correctly mapped by the signature module.
+
+Mapping
+-------
+IntArray2(const int*) -- <Signature (self, data: typing.Sequence)>
+getMargins(int*,int*,int*,int*)const -- <Signature (self) -> typing.Tuple[int, int, int, int]>
+
+We explicitly check only against typing.Iterable in the first test,
+because typing.Sequence is a subclass, but we will generalize this
+to typing.Iterable in the future.
+"""
+
+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 IntArray2, VirtualMethods
+
+from shibokensupport.signature import get_signature
+
+import typing
+
+
+class PointerPrimitiveTypeTest(unittest.TestCase):
+
+ def testArraySignature(self):
+ # signature="IntArray2(const int*)"
+ found = False
+ for sig in get_signature(IntArray2):
+ if "data" in sig.parameters:
+ found = True
+ break
+ self.assertTrue(found)
+ ann = sig.parameters["data"].annotation
+ self.assertEqual(ann.__args__, (int,))
+ self.assertTrue(issubclass(ann.__origin__, typing.Iterable))
+
+ def testReturnVarSignature(self):
+ # signature="getMargins(int*,int*,int*,int*)const">
+ ann = get_signature(VirtualMethods.getMargins).return_annotation
+ self.assertEqual(ann, typing.Tuple[int, int, int, int])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pointf_test.py b/sources/shiboken6/tests/samplebinding/pointf_test.py
new file mode 100644
index 000000000..91c58eb1d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/pointf_test.py
@@ -0,0 +1,51 @@
+#!/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 PointF 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 sample import PointF
+
+
+class PointFTest(unittest.TestCase):
+ '''Test case for PointF class, including operator overloads.'''
+
+ def testConstructor(self):
+ '''Test PointF class constructor.'''
+ pt = PointF(5.0, 2.3)
+ self.assertEqual(pt.x(), 5.0)
+ self.assertEqual(pt.y(), 2.3)
+
+ def testPlusOperator(self):
+ '''Test PointF class + operator.'''
+ pt1 = PointF(5.0, 2.3)
+ pt2 = PointF(0.5, 3.2)
+ self.assertEqual(pt1 + pt2, PointF(5.0 + 0.5, 2.3 + 3.2))
+
+ def testEqualOperator(self):
+ '''Test PointF class == operator.'''
+ pt1 = PointF(5.0, 2.3)
+ pt2 = PointF(5.0, 2.3)
+ pt3 = PointF(0.5, 3.2)
+ self.assertTrue(pt1 == pt1)
+ self.assertTrue(pt1 == pt2)
+ self.assertFalse(pt1 == pt3)
+
+ def testModifiedMethod(self):
+ pt1 = PointF(0.0, 0.0)
+ pt2 = PointF(10.0, 10.0)
+ expected = PointF((pt1.x() + pt2.x()) / 2.0, (pt1.y() + pt2.y()) / 2.0)
+ self.assertEqual(pt1.midpoint(pt2), expected)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py b/sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py
new file mode 100644
index 000000000..0b9fe2249
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/primitivereferenceargument_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()
+import sample
+
+
+class PrimitiveReferenceArgumentTest(unittest.TestCase):
+
+ def testIntReferenceArgument(self):
+ '''C++ signature: int acceptIntReference(int&)'''
+ self.assertEqual(sample.acceptIntReference(123), 123)
+
+ def testIntReturnPtr(self):
+ '''C++ signature: const int *acceptIntReturnPtr(int x)'''
+ self.assertEqual(sample.acceptIntReturnPtr(123), 123)
+
+ def testOddBoolReferenceArgument(self):
+ '''C++ signature: OddBool acceptOddBoolReference(OddBool&)'''
+ self.assertEqual(sample.acceptOddBoolReference(True), True)
+ self.assertEqual(sample.acceptOddBoolReference(False), False)
+ self.assertNotEqual(sample.acceptOddBoolReference(True), False)
+ self.assertNotEqual(sample.acceptOddBoolReference(False), True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/privatector_test.py b/sources/shiboken6/tests/samplebinding/privatector_test.py
new file mode 100644
index 000000000..63040388d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/privatector_test.py
@@ -0,0 +1,69 @@
+#!/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 a class with only a private constructor.'''
+
+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 PrivateCtor
+
+
+class PrivateCtorTest(unittest.TestCase):
+ '''Test case for PrivateCtor class'''
+
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
+ def testPrivateCtorInstanciation(self):
+ '''Test if instanciation of class with a private constructor raises an exception.'''
+ self.assertRaises(TypeError, PrivateCtor)
+
+ def testPrivateCtorInheritance(self):
+ '''Test if inheriting from PrivateCtor raises an exception.'''
+ def inherit():
+ class Foo(PrivateCtor):
+ pass
+ self.assertRaises(TypeError, inherit)
+
+ def testPrivateCtorInstanceMethod(self):
+ '''Test if PrivateCtor.instance() method return the proper singleton.'''
+ pd1 = PrivateCtor.instance()
+ calls = pd1.instanceCalls()
+ self.assertEqual(type(pd1), PrivateCtor)
+ pd2 = PrivateCtor.instance()
+ self.assertEqual(pd2, pd1)
+ self.assertEqual(pd2.instanceCalls(), calls + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testPrivateCtorRefCounting(self):
+ '''Test refcounting of the singleton returned by PrivateCtor.instance().'''
+ pd1 = PrivateCtor.instance()
+ calls = pd1.instanceCalls()
+ refcnt = sys.getrefcount(pd1)
+ pd2 = PrivateCtor.instance()
+ self.assertEqual(pd2.instanceCalls(), calls + 1)
+ self.assertEqual(sys.getrefcount(pd2), sys.getrefcount(pd1))
+ self.assertEqual(sys.getrefcount(pd2), refcnt + 1)
+ del pd1
+ self.assertEqual(sys.getrefcount(pd2), refcnt)
+ del pd2
+ gc.collect()
+ pd3 = PrivateCtor.instance()
+ self.assertEqual(type(pd3), PrivateCtor)
+ self.assertEqual(pd3.instanceCalls(), calls + 2)
+ self.assertEqual(sys.getrefcount(pd3), refcnt)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/privatedtor_test.py b/sources/shiboken6/tests/samplebinding/privatedtor_test.py
new file mode 100644
index 000000000..651f63b15
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/privatedtor_test.py
@@ -0,0 +1,85 @@
+#!/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 a class with a private destructor.'''
+
+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 shiboken6 import Shiboken
+from sample import PrivateDtor
+
+
+class PrivateDtorTest(unittest.TestCase):
+ '''Test case for PrivateDtor class'''
+
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
+ def testPrivateDtorInstanciation(self):
+ '''Test if instanciation of class with a private destructor raises an exception.'''
+ self.assertRaises(TypeError, PrivateDtor)
+
+ def testPrivateDtorInheritance(self):
+ '''Test if inheriting from PrivateDtor raises an exception.'''
+ def inherit():
+ class Foo(PrivateDtor):
+ pass
+ self.assertRaises(TypeError, inherit)
+
+ def testPrivateDtorInstanceMethod(self):
+ '''Test if PrivateDtor.instance() method return the proper singleton.'''
+ pd1 = PrivateDtor.instance()
+ calls = pd1.instanceCalls()
+ self.assertEqual(type(pd1), PrivateDtor)
+ pd2 = PrivateDtor.instance()
+ self.assertEqual(pd2, pd1)
+ self.assertEqual(pd2.instanceCalls(), calls + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testPrivateDtorRefCounting(self):
+ '''Test refcounting of the singleton returned by PrivateDtor.instance().'''
+ pd1 = PrivateDtor.instance()
+ calls = pd1.instanceCalls()
+ refcnt = sys.getrefcount(pd1)
+ pd2 = PrivateDtor.instance()
+ self.assertEqual(pd2.instanceCalls(), calls + 1)
+ self.assertEqual(sys.getrefcount(pd2), sys.getrefcount(pd1))
+ self.assertEqual(sys.getrefcount(pd2), refcnt + 1)
+ del pd1
+ self.assertEqual(sys.getrefcount(pd2), refcnt)
+ del pd2
+ gc.collect()
+ pd3 = PrivateDtor.instance()
+ self.assertEqual(type(pd3), PrivateDtor)
+ self.assertEqual(pd3.instanceCalls(), calls + 2)
+ self.assertEqual(sys.getrefcount(pd3), refcnt)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testClassDecref(self):
+ # Bug was that class PyTypeObject wasn't decrefed when instance
+ # was invalidated
+
+ before = sys.getrefcount(PrivateDtor)
+
+ for i in range(1000):
+ obj = PrivateDtor.instance()
+ Shiboken.invalidate(obj)
+
+ after = sys.getrefcount(PrivateDtor)
+
+ self.assertLess(abs(before - after), 5)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/protected_test.py b/sources/shiboken6/tests/samplebinding/protected_test.py
new file mode 100644
index 000000000..e4ccf721d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/protected_test.py
@@ -0,0 +1,401 @@
+#!/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 protected methods.'''
+
+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 cacheSize
+from sample import ProtectedNonPolymorphic, ProtectedVirtualDestructor
+from sample import (ProtectedPolymorphic, ProtectedPolymorphicDaughter,
+ ProtectedPolymorphicGrandDaughter)
+from sample import createProtectedProperty, ProtectedProperty, ProtectedEnumClass
+from sample import PrivateDtor
+from sample import Event, ObjectType, Point
+
+
+class ExtendedProtectedPolymorphic(ProtectedPolymorphic):
+ def __init__(self, name):
+ ProtectedPolymorphic.__init__(self, name)
+ self.protectedName_called = False
+
+ def protectedName(self):
+ self.protectedName_called = True
+ self._name = 'Extended' + ProtectedPolymorphic.protectedName(self)
+ return self._name
+
+
+class ExtendedProtectedPolymorphicDaughter(ProtectedPolymorphicDaughter):
+ def __init__(self, name):
+ self.protectedName_called = False
+ ProtectedPolymorphicDaughter.__init__(self, name)
+
+ def protectedName(self):
+ self.protectedName_called = True
+ self._name = 'ExtendedDaughter' + ProtectedPolymorphicDaughter.protectedName(self)
+ return self._name
+
+
+class ExtendedProtectedPolymorphicGrandDaughter(ProtectedPolymorphicGrandDaughter):
+ def __init__(self, name):
+ self.protectedName_called = False
+ ProtectedPolymorphicGrandDaughter.__init__(self, name)
+
+ def protectedName(self):
+ self.protectedName_called = True
+ self._name = 'ExtendedGrandDaughter' + ProtectedPolymorphicGrandDaughter.protectedName(self)
+ return self._name
+
+
+class ExtendedProtectedVirtualDestructor(ProtectedVirtualDestructor):
+ def __init__(self):
+ ProtectedVirtualDestructor.__init__(self)
+
+
+class ProtectedNonPolymorphicTest(unittest.TestCase):
+ '''Test cases for protected method in a class without virtual methods.'''
+
+ def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(cacheSize(), 0)
+
+ def testProtectedCall(self):
+ '''Calls a non-virtual protected method.'''
+ p = ProtectedNonPolymorphic('NonPoly')
+ self.assertEqual(p.publicName(), p.protectedName())
+ a0, a1 = 1, 2
+ self.assertEqual(p.protectedSum(a0, a1), a0 + a1)
+
+ def testProtectedCallWithInstanceCreatedOnCpp(self):
+ '''Calls a non-virtual protected method on an instance created in C++.'''
+ p = ProtectedNonPolymorphic.create()
+ self.assertEqual(p.publicName(), p.protectedName())
+ a0, a1 = 1, 2
+ self.assertEqual(p.protectedSum(a0, a1), a0 + a1)
+
+ def testModifiedProtectedCall(self):
+ '''Calls a non-virtual protected method modified with code injection.'''
+ p = ProtectedNonPolymorphic('NonPoly')
+ self.assertEqual(p.dataTypeName(), 'integer')
+ self.assertEqual(p.dataTypeName(1), 'integer')
+ self.assertEqual(p.dataTypeName(Point(1, 2)), 'pointer')
+
+
+class ProtectedPolymorphicTest(unittest.TestCase):
+ '''Test cases for protected method in a class with virtual methods.'''
+
+ def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(cacheSize(), 0)
+
+ def testProtectedCall(self):
+ '''Calls a virtual protected method.'''
+ p = ProtectedNonPolymorphic('Poly')
+ self.assertEqual(p.publicName(), p.protectedName())
+ a0, a1 = 1, 2
+ self.assertEqual(p.protectedSum(a0, a1), a0 + a1)
+
+ def testProtectedCallWithInstanceCreatedOnCpp(self):
+ '''Calls a virtual protected method on an instance created in C++.'''
+ p = ProtectedPolymorphic.create()
+ self.assertEqual(p.publicName(), p.protectedName())
+ self.assertEqual(p.callProtectedName(), p.protectedName())
+
+ def testReimplementedProtectedCall(self):
+ '''Calls a reimplemented virtual protected method.'''
+ original_name = 'Poly'
+ p = ExtendedProtectedPolymorphic(original_name)
+ name = p.callProtectedName()
+ self.assertTrue(p.protectedName_called)
+ self.assertEqual(p.protectedName(), name)
+ self.assertEqual(ProtectedPolymorphic.protectedName(p), original_name)
+
+
+class ProtectedPolymorphicDaugherTest(unittest.TestCase):
+ '''Test cases for protected method in a class inheriting for a class with virtual methods.'''
+
+ def testProtectedCallWithInstanceCreatedOnCpp(self):
+ '''Calls a virtual protected method from parent class on an instance created in C++.'''
+ p = ProtectedPolymorphicDaughter.create()
+ self.assertEqual(p.publicName(), p.protectedName())
+ self.assertEqual(p.callProtectedName(), p.protectedName())
+
+ def testReimplementedProtectedCall(self):
+ '''Calls a reimplemented virtual protected method from parent class.'''
+ original_name = 'Poly'
+ p = ExtendedProtectedPolymorphicDaughter(original_name)
+ name = p.callProtectedName()
+ self.assertTrue(p.protectedName_called)
+ self.assertEqual(p.protectedName(), name)
+ self.assertEqual(ProtectedPolymorphicDaughter.protectedName(p), original_name)
+
+
+class ProtectedPolymorphicGrandDaugherTest(unittest.TestCase):
+ '''Test cases for protected method in a class inheriting for a class that inherits from
+ another with protected virtual methods.'''
+
+ def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(cacheSize(), 0)
+
+ def testProtectedCallWithInstanceCreatedOnCpp(self):
+ '''Calls a virtual protected method from parent class on an instance created in C++.'''
+ p = ProtectedPolymorphicGrandDaughter.create()
+ self.assertEqual(p.publicName(), p.protectedName())
+ self.assertEqual(p.callProtectedName(), p.protectedName())
+
+ def testReimplementedProtectedCall(self):
+ '''Calls a reimplemented virtual protected method from parent class.'''
+ original_name = 'Poly'
+ p = ExtendedProtectedPolymorphicGrandDaughter(original_name)
+ name = p.callProtectedName()
+ self.assertTrue(p.protectedName_called)
+ self.assertEqual(p.protectedName(), name)
+ self.assertEqual(ProtectedPolymorphicGrandDaughter.protectedName(p), original_name)
+
+
+class ProtectedVirtualDtorTest(unittest.TestCase):
+ '''Test cases for protected virtual destructor.'''
+
+ def setUp(self):
+ ProtectedVirtualDestructor.resetDtorCounter()
+
+ def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(cacheSize(), 0)
+
+ def testVirtualProtectedDtor(self):
+ '''Original protected virtual destructor is being called.'''
+ dtor_called = ProtectedVirtualDestructor.dtorCalled()
+ for i in range(1, 10):
+ pvd = ProtectedVirtualDestructor()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ del pvd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(ProtectedVirtualDestructor.dtorCalled(), dtor_called + i)
+
+ def testVirtualProtectedDtorOnCppCreatedObject(self):
+ '''Original protected virtual destructor is being called for a C++ created object.'''
+ dtor_called = ProtectedVirtualDestructor.dtorCalled()
+ for i in range(1, 10):
+ pvd = ProtectedVirtualDestructor.create()
+ del pvd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(ProtectedVirtualDestructor.dtorCalled(), dtor_called + i)
+
+ def testProtectedDtorOnDerivedClass(self):
+ '''Original protected virtual destructor is being called for a derived class.'''
+ dtor_called = ExtendedProtectedVirtualDestructor.dtorCalled()
+ for i in range(1, 10):
+ pvd = ExtendedProtectedVirtualDestructor()
+ del pvd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(ExtendedProtectedVirtualDestructor.dtorCalled(), dtor_called + i)
+
+
+class ExtendedProtectedEnumClass(ProtectedEnumClass):
+ def __init__(self):
+ ProtectedEnumClass.__init__(self)
+
+ def protectedEnumMethod(self, value):
+ if value == ProtectedEnumClass.ProtectedItem0:
+ return ProtectedEnumClass.ProtectedItem1
+ return ProtectedEnumClass.ProtectedItem0
+
+ def publicEnumMethod(self, value):
+ if value == ProtectedEnumClass.PublicItem0:
+ return ProtectedEnumClass.PublicItem1
+ return ProtectedEnumClass.PublicItem0
+
+
+class ProtectedEnumTest(unittest.TestCase):
+ '''Test cases for protected enum.'''
+
+ def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(cacheSize(), 0)
+
+ def testProtectedMethodWithProtectedEnumArgument(self):
+ '''Calls protected method with protected enum argument.'''
+ obj = ProtectedEnumClass()
+
+ self.assertEqual(type(ProtectedEnumClass.ProtectedItem0), ProtectedEnumClass.ProtectedEnum)
+
+ self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem0),
+ ProtectedEnumClass.ProtectedItem0)
+ self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem1),
+ ProtectedEnumClass.ProtectedItem1)
+ self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem0),
+ ProtectedEnumClass.ProtectedItem0)
+ self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem1),
+ ProtectedEnumClass.ProtectedItem1)
+
+ def testProtectedMethodWithPublicEnumArgument(self):
+ '''Calls protected method with public enum argument.'''
+ obj = ProtectedEnumClass()
+
+ self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem0)
+ self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem1)
+
+ self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem0)
+ self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem1)
+
+ def testOverriddenProtectedMethodWithProtectedEnumArgument(self):
+ '''Calls overridden protected method with protected enum argument.'''
+ obj = ExtendedProtectedEnumClass()
+
+ self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem0),
+ ProtectedEnumClass.ProtectedItem1)
+ self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem1),
+ ProtectedEnumClass.ProtectedItem0)
+
+ self.assertEqual(ProtectedEnumClass.protectedEnumMethod(obj, ProtectedEnumClass.ProtectedItem0), # noqa: E501
+ ProtectedEnumClass.ProtectedItem0)
+ self.assertEqual(ProtectedEnumClass.protectedEnumMethod(obj,
+ ProtectedEnumClass.ProtectedItem1), ProtectedEnumClass.ProtectedItem1)
+
+ self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem0),
+ ProtectedEnumClass.ProtectedItem1)
+ self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem1),
+ ProtectedEnumClass.ProtectedItem0)
+
+ def testOverriddenProtectedMethodWithPublicEnumArgument(self):
+ '''Calls overridden protected method with public enum argument.'''
+ obj = ExtendedProtectedEnumClass()
+
+ self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem1)
+ self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem0)
+
+ self.assertEqual(ProtectedEnumClass.publicEnumMethod(obj, ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem0)
+ self.assertEqual(ProtectedEnumClass.publicEnumMethod(obj, ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem1)
+
+ self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem1)
+ self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem0)
+
+
+class ProtectedPropertyTest(unittest.TestCase):
+ '''Test cases for a class with a protected property (or field in C++).'''
+
+ def setUp(self):
+ self.obj = ProtectedProperty()
+
+ def tearDown(self):
+ del self.obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(cacheSize(), 0)
+
+ def testProtectedProperty(self):
+ '''Writes and reads a protected integer property.'''
+ self.obj.protectedProperty = 3
+ self.assertEqual(self.obj.protectedProperty, 3)
+
+ def testProtectedContainerProperty(self):
+ '''Writes and reads a protected list of integers property.'''
+ lst = [1, 2, 3, 4]
+ self.obj.protectedContainerProperty = lst
+ self.assertEqual(self.obj.protectedContainerProperty, lst)
+
+ def testProtectedEnumProperty(self):
+ '''Writes and reads a protected enum property.'''
+ self.obj.protectedEnumProperty = Event.SOME_EVENT
+ self.assertEqual(self.obj.protectedEnumProperty, Event.SOME_EVENT)
+
+ def testProtectedValueTypeProperty(self):
+ '''Writes and reads a protected value type property.'''
+ point = Point(12, 34)
+ self.obj.protectedValueTypeProperty = point
+ self.assertEqual(self.obj.protectedValueTypeProperty, point)
+ self.assertFalse(self.obj.protectedValueTypeProperty is point)
+ pointProperty = self.obj.protectedValueTypeProperty
+ self.assertTrue(self.obj.protectedValueTypeProperty is pointProperty)
+
+ def testProtectedValueTypePropertyWrapperRegistration(self):
+ '''Access colocated protected value type property.'''
+ cache_size = cacheSize()
+ point = Point(12, 34)
+ obj = createProtectedProperty()
+ obj.protectedValueTypeProperty
+ self.assertEqual(obj.protectedValueTypeProperty.copy(),
+ obj.protectedValueTypeProperty)
+ obj.protectedValueTypeProperty = point
+ self.assertEqual(obj.protectedValueTypeProperty, point)
+ self.assertFalse(obj.protectedValueTypeProperty is point)
+ pointProperty = obj.protectedValueTypeProperty
+ self.assertTrue(obj.protectedValueTypeProperty is pointProperty)
+ del obj, point, pointProperty
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(cacheSize(), cache_size)
+
+ def testProtectedValueTypePointerProperty(self):
+ '''Writes and reads a protected value type pointer property.'''
+ pt1 = Point(12, 34)
+ pt2 = Point(12, 34)
+ self.obj.protectedValueTypePointerProperty = pt1
+ self.assertEqual(self.obj.protectedValueTypePointerProperty, pt1)
+ self.assertEqual(self.obj.protectedValueTypePointerProperty, pt2)
+ self.assertTrue(self.obj.protectedValueTypePointerProperty is pt1)
+ self.assertFalse(self.obj.protectedValueTypePointerProperty is pt2)
+ # PYSIDE-535: Need to assign None to break the cycle
+ self.obj.protectedValueTypePointerProperty = None
+
+ def testProtectedObjectTypeProperty(self):
+ '''Writes and reads a protected object type property.'''
+ obj = ObjectType()
+ self.obj.protectedObjectTypeProperty = obj
+ self.assertEqual(self.obj.protectedObjectTypeProperty, obj)
+ # PYSIDE-535: Need to assign None to break the cycle
+ self.obj.protectedObjectTypeProperty = None
+
+
+class PrivateDtorProtectedMethodTest(unittest.TestCase):
+ '''Test cases for classes with private destructors and protected methods.'''
+
+ def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(cacheSize(), 0)
+
+ def testProtectedMethod(self):
+ '''Calls protected method of a class with a private destructor.'''
+ obj = PrivateDtor.instance()
+
+ self.assertEqual(type(obj), PrivateDtor)
+ self.assertEqual(obj.instanceCalls(), 1)
+ self.assertEqual(obj.instanceCalls(), obj.protectedInstanceCalls())
+ obj = PrivateDtor.instance()
+ self.assertEqual(obj.instanceCalls(), 2)
+ self.assertEqual(obj.instanceCalls(), obj.protectedInstanceCalls())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pstrlist_test.py b/sources/shiboken6/tests/samplebinding/pstrlist_test.py
new file mode 100644
index 000000000..d60f9cf35
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/pstrlist_test.py
@@ -0,0 +1,32 @@
+#!/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()
+import sample
+
+
+class PStrListTest(unittest.TestCase):
+
+ def testPStrList(self):
+ a = 'str0'
+ b = 'str1'
+ lst = sample.createPStrList(a, b)
+ self.assertEqual(lst, [a, b])
+
+ def testListOfPStr(self):
+ a = 'str0'
+ b = 'str1'
+ lst = sample.createListOfPStr(a, b)
+ self.assertEqual(lst, [a, b])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pystr_test.py b/sources/shiboken6/tests/samplebinding/pystr_test.py
new file mode 100644
index 000000000..ec64c1e31
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/pystr_test.py
@@ -0,0 +1,29 @@
+#!/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 definition of __str__ method.'''
+
+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
+
+
+class PyStrTest(unittest.TestCase):
+ '''Test case for definition of __str__ method.'''
+
+ def testPyStr(self):
+ '''Test case for defined __str__ method.'''
+ pt = Point(5, 2)
+ self.assertEqual(str(pt), 'Point(5.0, 2.0)')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/python_thread_test.py b/sources/shiboken6/tests/samplebinding/python_thread_test.py
new file mode 100644
index 000000000..65398b5c6
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/python_thread_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
+
+#!/usr/bin/env python
+
+'''Tests for using Shiboken-based bindings with python threads'''
+
+import logging
+import os
+from random import random
+import sys
+import threading
+import time
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from shiboken_paths import init_paths
+init_paths()
+
+import sample
+
+#logging.basicConfig(level=logging.DEBUG)
+
+
+class Producer(threading.Thread):
+ '''Producer thread'''
+
+ def __init__(self, bucket, max_runs, *args):
+ #Constructor. Receives the bucket
+ super(Producer, self).__init__(*args)
+ self.runs = 0
+ self.bucket = bucket
+ self.max_runs = max_runs
+ self.production_list = []
+
+ def run(self):
+ while self.runs < self.max_runs:
+ value = int(random() * 10) % 10
+ self.bucket.push(value)
+ self.production_list.append(value)
+ logging.debug(f'PRODUCER - pushed {value}')
+ self.runs += 1
+ #self.msleep(5)
+ time.sleep(0.01)
+
+
+class Consumer(threading.Thread):
+ '''Consumer thread'''
+ def __init__(self, bucket, max_runs, *args):
+ #Constructor. Receives the bucket
+ super(Consumer, self).__init__(*args)
+ self.runs = 0
+ self.bucket = bucket
+ self.max_runs = max_runs
+ self.consumption_list = []
+
+ def run(self):
+ while self.runs < self.max_runs:
+ if not self.bucket.empty():
+ value = self.bucket.pop()
+ self.consumption_list.append(value)
+ logging.debug(f'CONSUMER - got {value}')
+ self.runs += 1
+ else:
+ logging.debug('CONSUMER - empty bucket')
+ time.sleep(0.01)
+
+
+class ProducerConsumer(unittest.TestCase):
+ '''Basic test case for producer-consumer QThread'''
+
+ def finishCb(self):
+ #Quits the application
+ self.app.exit(0)
+
+ def testProdCon(self):
+ #QThread producer-consumer example
+ bucket = sample.Bucket()
+ prod = Producer(bucket, 10)
+ cons = Consumer(bucket, 10)
+
+ prod.start()
+ cons.start()
+
+ #QObject.connect(prod, SIGNAL('finished()'), self.finishCb)
+ #QObject.connect(cons, SIGNAL('finished()'), self.finishCb)
+
+ prod.join()
+ cons.join()
+
+ self.assertEqual(prod.production_list, cons.consumption_list)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py b/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py
new file mode 100644
index 000000000..1d19de941
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py
@@ -0,0 +1,36 @@
+#!/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 function that could receive a NULL pointer in a '[const] char*' parameter.'''
+
+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 countCharacters
+
+
+class ReceiveNullCStringTest(unittest.TestCase):
+ '''Test case for a function that could receive a NULL pointer in a '[const] char*'
+ parameter.'''
+
+ def testBasic(self):
+ '''The test function should be working for the basic cases.'''
+ a = ''
+ b = 'abc'
+ self.assertEqual(countCharacters(a), len(a))
+ self.assertEqual(countCharacters(b), len(b))
+
+ def testReceiveNull(self):
+ '''The test function returns '-1' when receives a None value instead of a string.'''
+ self.assertEqual(countCharacters(None), -1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/reference_test.py b/sources/shiboken6/tests/samplebinding/reference_test.py
new file mode 100644
index 000000000..1b6dd3a7a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/reference_test.py
@@ -0,0 +1,107 @@
+#!/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 methods that receive references to objects.'''
+
+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 Reference, Str
+
+
+class ExtendedReference(Reference):
+ def __init__(self):
+ Reference.__init__(self)
+ self.uses_reference_virtual_called = False
+ self.uses_const_reference_virtual_called = False
+ self.reference_inc = 1
+ self.const_reference_inc = 2
+ self.multiplier = 333
+
+ def usesReferenceVirtual(self, ref, inc):
+ self.uses_reference_virtual_called = True
+ return ref.objId() + inc + self.reference_inc
+
+ def usesConstReferenceVirtual(self, ref, inc):
+ self.uses_const_reference_virtual_called = True
+ return ref.objId() + inc + self.const_reference_inc
+
+ def alterReferenceIdVirtual(self, ref):
+ ref.setObjId(ref.objId() * self.multiplier)
+
+
+class ReferenceTest(unittest.TestCase):
+ '''Test case for methods that receive references to objects.'''
+
+ def testMethodThatReceivesReference(self):
+ '''Test a method that receives a reference to an object as argument.'''
+ objId = 123
+ r = Reference(objId)
+ self.assertEqual(Reference.usesReference(r), objId)
+
+ def testCantSegFaultWhenReceiveNone(self):
+ '''do not segfault when receiving None as argument.'''
+ s = Str()
+ self.assertFalse(bool(s))
+
+ def testMethodThatReceivesConstReference(self):
+ '''Test a method that receives a const reference to an object as argument.'''
+ objId = 123
+ r = Reference(objId)
+ self.assertEqual(Reference.usesConstReference(r), objId)
+
+ def testModificationOfReference(self):
+ '''Tests if the identity of a reference argument is preserved when passing
+ it to be altered in C++.'''
+ objId = 123
+ r1 = Reference(objId)
+ r1.alterReferenceIdVirtual(r1)
+ self.assertEqual(r1.objId(), objId * Reference.multiplier())
+
+ def testModificationOfReferenceCallingAVirtualIndirectly(self):
+ '''Tests if the identity of a reference argument is preserved when passing it
+ to be altered in C++ through a method that calls a virtual method.'''
+ objId = 123
+ r1 = Reference(objId)
+ r1.callAlterReferenceIdVirtual(r1)
+ self.assertEqual(r1.objId(), objId * Reference.multiplier())
+
+ def testModificationOfReferenceCallingAReimplementedVirtualIndirectly(self):
+ '''Test if a Python override of a virtual method with a reference parameter
+ called from C++ alters the argument properly.'''
+ objId = 123
+ r = Reference(objId)
+ er = ExtendedReference()
+ result = er.callAlterReferenceIdVirtual(r) # noqa: F841
+ self.assertEqual(r.objId(), objId * er.multiplier)
+
+ def testReimplementedVirtualMethodCallWithReferenceParameter(self):
+ '''Test if a Python override of a virtual method with a reference parameter
+ is correctly called from C++.'''
+ inc = 9
+ objId = 123
+ r = Reference(objId)
+ er = ExtendedReference()
+ result = er.callUsesReferenceVirtual(r, inc)
+ self.assertEqual(result, objId + inc + er.reference_inc)
+
+ def testReimplementedVirtualMethodCallWithConstReferenceParameter(self):
+ '''Test if a Python override of a virtual method with a const reference
+ parameter is correctly called from C++.'''
+ inc = 9
+ objId = 123
+ r = Reference(objId)
+ er = ExtendedReference()
+ result = er.callUsesConstReferenceVirtual(r, inc)
+ self.assertEqual(result, objId + inc + er.const_reference_inc)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/referencetopointer_test.py b/sources/shiboken6/tests/samplebinding/referencetopointer_test.py
new file mode 100644
index 000000000..942c7ea29
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/referencetopointer_test.py
@@ -0,0 +1,78 @@
+#!/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 a reference to pointer argument type.'''
+
+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 VirtualMethods, Str
+
+
+class ExtendedVirtualMethods(VirtualMethods):
+ def __init__(self):
+ VirtualMethods.__init__(self)
+ self.prefix = 'Ext'
+
+ def createStr(self, text):
+ ext_text = text
+ if text is not None:
+ ext_text = self.prefix + text
+ return VirtualMethods.createStr(self, ext_text)
+
+
+class ReferenceToPointerTest(unittest.TestCase):
+ '''Test cases for a reference to pointer argument type.'''
+
+ def testSimpleCallWithNone(self):
+ '''Simple call to createStr method with a None argument.'''
+ obj = VirtualMethods()
+ ok, string = obj.createStr(None)
+ self.assertFalse(ok)
+ self.assertEqual(string, None)
+
+ def testSimpleCallWithString(self):
+ '''Simple call to createStr method with a Python string argument.'''
+ obj = VirtualMethods()
+ ok, string = obj.createStr('foo')
+ self.assertTrue(ok)
+ self.assertEqual(string, Str('foo'))
+
+ def testCallNonReimplementedMethodWithNone(self):
+ '''Calls createStr method from C++ with a None argument.'''
+ obj = VirtualMethods()
+ ok, string = obj.callCreateStr(None)
+ self.assertFalse(ok)
+ self.assertEqual(string, None)
+
+ def testCallNonReimplementedMethodWithString(self):
+ '''Calls createStr method from C++ with a Python string argument.'''
+ obj = VirtualMethods()
+ ok, string = obj.callCreateStr('foo')
+ self.assertTrue(ok)
+ self.assertEqual(string, Str('foo'))
+
+ def testCallReimplementedMethodWithNone(self):
+ '''Calls reimplemented createStr method from C++ with a None argument.'''
+ obj = ExtendedVirtualMethods()
+ ok, string = obj.callCreateStr(None)
+ self.assertFalse(ok)
+ self.assertEqual(string, None)
+
+ def testCallReimplementedMethodWithString(self):
+ '''Calls reimplemented createStr method from C++ with a Python string argument.'''
+ obj = ExtendedVirtualMethods()
+ ok, string = obj.callCreateStr('foo')
+ self.assertTrue(ok)
+ self.assertEqual(string, Str(obj.prefix + 'foo'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/renaming_test.py b/sources/shiboken6/tests/samplebinding/renaming_test.py
new file mode 100644
index 000000000..b08438ef3
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/renaming_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 renaming using target-lang-name attribute.'''
+
+import os
+import re
+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 RenamedValue, RenamedUser
+
+from shibokensupport.signature import get_signature
+
+
+class RenamingTest(unittest.TestCase):
+ def test(self):
+ '''Tests whether the C++ class ToBeRenamedValue renamed via attribute
+ target-lang-name to RenamedValue shows up in consuming function
+ signature strings correctly.
+ '''
+ renamed_value = RenamedValue()
+ self.assertEqual(str(type(renamed_value)),
+ "<class 'sample.RenamedValue'>")
+ rename_user = RenamedUser()
+ rename_user.useRenamedValue(renamed_value)
+ actual_signature = str(get_signature(rename_user.useRenamedValue))
+ self.assertTrue(re.match(r"^\(self,\s*?v:\s*?sample.RenamedValue\)\s*?->\s*?None$",
+ actual_signature))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/return_null_test.py b/sources/shiboken6/tests/samplebinding/return_null_test.py
new file mode 100644
index 000000000..2c4f07c65
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/return_null_test.py
@@ -0,0 +1,40 @@
+#!/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 functions that could return a NULL 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 sample import (returnNullPrimitivePointer, returnNullValueTypePointer,
+ returnNullObjectTypePointer)
+
+
+class ReturnNullTest(unittest.TestCase):
+ '''Test case for functions that could return a NULL pointer.'''
+
+ def testReturnNull(self):
+ '''Function returns a NULL pointer to a primitive type.'''
+ o = returnNullPrimitivePointer()
+ self.assertEqual(o, None)
+
+ def testReturnNullObjectType(self):
+ '''Function returns a NULL pointer to an object-type.'''
+ o = returnNullObjectTypePointer()
+ self.assertEqual(o, None)
+
+ def testReturnNullValueType(self):
+ '''Function returns a NULL pointer to a value-type.'''
+ o = returnNullValueTypePointer()
+ self.assertEqual(o, None)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/richcompare_test.py b/sources/shiboken6/tests/samplebinding/richcompare_test.py
new file mode 100644
index 000000000..3146d0faf
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/richcompare_test.py
@@ -0,0 +1,28 @@
+#!/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 Expression
+
+
+class TestRichCompare(unittest.TestCase):
+
+ def testIt(self):
+ a = Expression(2)
+ b = Expression(3)
+ c = a + b
+ d = a + c < b + a
+ self.assertEqual(d.toString(), "((2+(2+3))<(3+2))")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/sample-binding.txt.in b/sources/shiboken6/tests/samplebinding/sample-binding.txt.in
new file mode 100644
index 000000000..bcf9de90f
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/sample-binding.txt.in
@@ -0,0 +1,16 @@
+[generator-project]
+
+generator-set = shiboken
+
+header-file = @CMAKE_CURRENT_SOURCE_DIR@/global.h
+typesystem-file = @sample_TYPESYSTEM@
+
+output-directory = @CMAKE_CURRENT_BINARY_DIR@
+
+include-path = @libsample_SOURCE_DIR@
+
+typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@
+
+enable-parent-ctor-heuristic
+use-isnull-as-nb_nonzero
+lean-headers
diff --git a/sources/shiboken6/tests/samplebinding/sample_test.py b/sources/shiboken6/tests/samplebinding/sample_test.py
new file mode 100644
index 000000000..19b2f708d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/sample_test.py
@@ -0,0 +1,76 @@
+#!/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 bindings 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()
+
+import sample
+
+
+class ModuleTest(unittest.TestCase):
+ '''Test case for module and global functions'''
+
+ def testAddedFunctionAtModuleLevel(self):
+ '''Calls function added to module from type system description.'''
+ str1 = 'Foo'
+ self.assertEqual(sample.multiplyString(str1, 3), str1 * 3)
+ self.assertEqual(sample.multiplyString(str1, 0), str1 * 0)
+
+ def testAddedFunctionWithVarargs(self):
+ '''Calls function that receives varargs added to module from type system description.'''
+ self.assertEqual(sample.countVarargs(1), 0)
+ self.assertEqual(sample.countVarargs(1, 2), 1)
+ self.assertEqual(sample.countVarargs(1, 2, 3, 'a', 'b', 4, (5, 6)), 6)
+
+ def testSampleComparisonOpInNamespace(self):
+ s1 = sample.sample.sample(10)
+ s2 = sample.sample.sample(10)
+ self.assertEqual(s1, s2)
+
+ def testConstant(self):
+ self.assertEqual(sample.sample.INT_CONSTANT, 42)
+
+ def testStringFunctions(self):
+ # Test plain ASCII, UCS1 and UCS4 encoding which have different
+ # representations in the PyUnicode objects.
+ for t1 in ["ascii", "Ümläut", "😀"]:
+ expected = t1 + t1
+ self.assertEqual(sample.addStdStrings(t1, t1), expected)
+ self.assertEqual(sample.addStdWStrings(t1, t1), expected)
+
+ def testNullPtrT(self):
+ sample.testNullPtrT(None)
+ self.assertRaises(TypeError, sample.testNullPtrT, 42)
+
+ def testRValueRefsWithValueTypes(self):
+ """Passing value types by rvalue refs: For value types, nothing should
+ happen since the argument is copied in the call and the copy is
+ moved from."""
+ polygon = sample.Polygon()
+ polygon.addPoint(sample.Point(1, 2))
+ polygon.addPoint(sample.Point(3, 4))
+ point_count = len(polygon.points())
+ self.assertEqual(point_count, sample.takePolygon(polygon))
+
+ def testRValueRefsWithObjectTypes(self):
+ """Passing object types by rvalue refs: The underlying object should
+ be moved from."""
+ o = sample.ObjectType()
+ object_name = "Name"
+ o.setObjectName(object_name)
+ self.assertEqual(len(object_name), sample.takeObjectType(o))
+ # o should be moved from, name is now empty
+ self.assertEqual(len(o.objectName()), 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/samplebinding.pyproject b/sources/shiboken6/tests/samplebinding/samplebinding.pyproject
new file mode 100644
index 000000000..ba6ba6f8f
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/samplebinding.pyproject
@@ -0,0 +1,131 @@
+{
+ "files": ["__del___test.py",
+ "abstract_test.py",
+ "addedfunction_test.py",
+ "addedfunction_with_container_args_test.py",
+ "argumentmodifications_test.py",
+ "array_numpy_test.py",
+ "array_sequence_test.py",
+ "bug_554_test.py",
+ "bug_704_test.py",
+ "bytearray_test.py",
+ "child_return_test.py",
+ "class_fields_test.py",
+ "collector_test.py",
+ "complex_test.py",
+ "conversion_operator_test.py",
+ "copy_test.py",
+ "ctorconvrule_test.py",
+ "cyclic_test.py",
+ "date_test.py",
+ "decisor_test.py",
+ "delete_test.py",
+ "deprecated_test.py",
+ "derived_test.py",
+ "duck_punching_test.py",
+ "echo_test.py",
+ "enum_test.py",
+ "enumfromremovednamespace_test.py",
+ "event_loop_call_virtual_test.py",
+ "event_loop_thread_test.py",
+ "exception_test.py",
+ "filter_test.py",
+ "handleholder_test.py",
+ "hashabletype_test.py",
+ "ignorederefop_test.py",
+ "implicitconv_numerical_test.py",
+ "implicitconv_test.py",
+ "inheritanceandscope_test.py",
+ "injectcode_test.py",
+ "innerclass_test.py",
+ "intlist_test.py",
+ "intwrapper_test.py",
+ "invalid_virtual_return_test.py",
+ "keep_reference_test.py",
+ "list_test.py",
+ "lock_test.py",
+ "map_test.py",
+ "metaclass_test.py",
+ "mi_virtual_methods_test.py",
+ "mixed_mi_test.py",
+ "modelindex_test.py",
+ "modelview_test.py",
+ "modifications_test.py",
+ "modified_constructor_test.py",
+ "modifiedvirtualmethods_test.py",
+ "multi_cpp_inheritance_test.py",
+ "multiple_derived_test.py",
+ "namespace_test.py",
+ "newdivision_test.py",
+ "nondefaultctor_test.py",
+ "nontypetemplate_test.py",
+ "nonzero_test.py",
+ "numericaltypedef_test.py",
+ "numpy_test.py",
+ "objecttype_test.py",
+ "objecttype_with_named_args_test.py",
+ "objecttypebyvalue_test.py",
+ "objecttypelayout_test.py",
+ "objecttypeoperators_test.py",
+ "objecttypereferenceasvirtualmethodargument_test.py",
+ "oddbool_test.py",
+ "onlycopyclass_test.py",
+ "overflow_test.py",
+ "overload_sorting_test.py",
+ "overload_test.py",
+ "overloadwithdefault_test.py",
+ "ownership_argument_invalidation_test.py",
+ "ownership_delete_child_in_cpp_test.py",
+ "ownership_delete_child_in_python_test.py",
+ "ownership_delete_parent_test.py",
+ "ownership_invalidate_after_use_test.py",
+ "ownership_invalidate_child_test.py",
+ "ownership_invalidate_nonpolymorphic_test.py",
+ "ownership_invalidate_parent_test.py",
+ "ownership_reparenting_test.py",
+ "ownership_transference_test.py",
+ "pair_test.py",
+ "pen_test.py",
+ "point_test.py",
+ "pointerholder_test.py",
+ "pointerprimitivetype_test.py",
+ "pointf_test.py",
+ "primitivereferenceargument_test.py",
+ "privatector_test.py",
+ "privatedtor_test.py",
+ "protected_test.py",
+ "pstrlist_test.py",
+ "pystr_test.py",
+ "python_thread_test.py",
+ "receive_null_cstring_test.py",
+ "reference_test.py",
+ "referencetopointer_test.py",
+ "renaming_test.py",
+ "return_null_test.py",
+ "richcompare_test.py",
+ "sample_test.py",
+ "samplesnippets.cpp",
+ "simplefile_glue.cpp",
+ "simplefile_test.py",
+ "size_test.py",
+ "snakecase_test.py",
+ "static_nonstatic_methods_test.py",
+ "str_test.py",
+ "strlist_test.py",
+ "templateinheritingclass_test.py",
+ "time_test.py",
+ "transform_test.py",
+ "typeconverters_test.py",
+ "typedealloc_test.py",
+ "typedtordoublefree_test.py",
+ "typesystypedef_test.py",
+ "unsafe_parent_test.py",
+ "useraddedctor_test.py",
+ "virtualdtor_test.py",
+ "virtualmethods_test.py",
+ "visibilitychange_test.py",
+ "voidholder_test.py",
+ "weakref_test.py",
+ "writableclassdict_test.py",
+ "typesystem_sample.xml"]
+}
diff --git a/sources/shiboken6/tests/samplebinding/samplesnippets.cpp b/sources/shiboken6/tests/samplebinding/samplesnippets.cpp
new file mode 100644
index 000000000..43e6b08de
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/samplesnippets.cpp
@@ -0,0 +1,54 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+// @snippet intwrapper_add_ints
+extern "C" {
+static PyObject *Sbk_IntWrapper_add_ints(PyObject * /* self */, PyObject *args)
+{
+ PyObject *result = nullptr;
+ if (PyTuple_Check(args) != 0 && PyTuple_Size(args) == 2) {
+ PyObject *arg1 = PyTuple_GetItem(args, 0);
+ PyObject *arg2 = PyTuple_GetItem(args, 1);
+ if (PyLong_Check(arg1) != 0 && PyLong_Check(arg2) != 0)
+ result = PyLong_FromLong(PyLong_AsLong(arg1) + PyLong_AsLong(arg2));
+ }
+ if (result == nullptr)
+ PyErr_SetString(PyExc_TypeError, "expecting 2 ints");
+ return result;
+}
+}
+// @snippet intwrapper_add_ints
+
+// @snippet stdcomplex_floor
+%PYARG_0 = PyFloat_FromDouble(std::floor(%CPPSELF.abs_value()));
+// @snippet stdcomplex_floor
+
+// @snippet stdcomplex_ceil
+%PYARG_0 = PyFloat_FromDouble(std::ceil(%CPPSELF.abs_value()));
+// @snippet stdcomplex_ceil
+
+// @snippet stdcomplex_abs
+%PYARG_0 = PyFloat_FromDouble(%CPPSELF.abs_value());
+// @snippet stdcomplex_abs
+
+// @snippet stdcomplex_pow
+%RETURN_TYPE %0 = %CPPSELF.pow(%1);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet stdcomplex_pow
+
+// @snippet size_char_ct
+// Convert a string "{width}x{height}" specification
+{
+ double width = -1;
+ double height = -1;
+ const std::string s = %1;
+ const auto pos = s.find('x');
+ if (pos != std::string::npos) {
+ std::istringstream wstr(s.substr(0, pos));
+ wstr >> width;
+ std::istringstream hstr(s.substr(pos + 1, s.size() - pos - 1));
+ hstr >> height;
+ }
+ %0 = new %TYPE(width, height);
+}
+// @snippet size_char_ct
diff --git a/sources/shiboken6/tests/samplebinding/simplefile_glue.cpp b/sources/shiboken6/tests/samplebinding/simplefile_glue.cpp
new file mode 100644
index 000000000..76c0cfaf2
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/simplefile_glue.cpp
@@ -0,0 +1,9 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+if (!%CPPSELF.%FUNCTION_NAME()) {
+ PyObject* error_msg = PyBytes_FromFormat(
+ "Could not open file: \"%s\"", %CPPSELF->filename());
+ PyErr_SetObject(PyExc_IOError, error_msg);
+ return 0;
+}
diff --git a/sources/shiboken6/tests/samplebinding/simplefile_test.py b/sources/shiboken6/tests/samplebinding/simplefile_test.py
new file mode 100644
index 000000000..55c894a35
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/simplefile_test.py
@@ -0,0 +1,60 @@
+#!/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 SimpleFile 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 sample import SimpleFile
+
+
+class SimpleFileTest(unittest.TestCase):
+ '''Test cases for SimpleFile class.'''
+
+ def setUp(self):
+ filename = f'simplefile{os.getpid()}.txt'
+ self.existing_filename = Path(os.curdir) / filename
+ self.delete_file = False
+ if not self.existing_filename.exists():
+ with self.existing_filename.open('w') as f:
+ for line in range(10):
+ f.write('sbrubbles\n')
+ self.delete_file = True
+
+ self.non_existing_filename = Path(os.curdir) / 'inexistingfile.txt'
+ i = 0
+ while self.non_existing_filename.exists():
+ i += 1
+ filename = f'inexistingfile-{i}.txt'
+ self.non_existing_filename = Path(os.curdir) / filename
+
+ def tearDown(self):
+ if self.delete_file:
+ os.remove(self.existing_filename)
+
+ def testExistingFile(self):
+ '''Test SimpleFile class with existing file.'''
+ f = SimpleFile(os.fspath(self.existing_filename))
+ self.assertEqual(f.filename(), os.fspath(self.existing_filename))
+ f.open()
+ self.assertNotEqual(f.size(), 0)
+ f.close()
+
+ def testNonExistingFile(self):
+ '''Test SimpleFile class with non-existing file.'''
+ f = SimpleFile(os.fspath(self.non_existing_filename))
+ self.assertEqual(f.filename(), os.fspath(self.non_existing_filename))
+ self.assertRaises(IOError, f.open)
+ self.assertEqual(f.size(), 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/size_test.py b/sources/shiboken6/tests/samplebinding/size_test.py
new file mode 100644
index 000000000..069ce59b3
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/size_test.py
@@ -0,0 +1,100 @@
+#!/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 operator overloads on Size 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 sample import Size
+
+
+class PointTest(unittest.TestCase):
+ '''Test case for Size class, including operator overloads.'''
+
+ def testConstructor(self):
+ '''Test Size class constructor.'''
+ width, height = (5.0, 2.3)
+ size = Size(width, height)
+ self.assertEqual(size.width(), width)
+ self.assertEqual(size.height(), height)
+ self.assertEqual(size.calculateArea(), width * height)
+
+ def testCopyConstructor(self):
+ '''Test Size class copy constructor.'''
+ width, height = (5.0, 2.3)
+ s1 = Size(width, height)
+ s2 = Size(s1)
+ self.assertFalse(s1 is s2)
+ self.assertEqual(s1, s2)
+
+ def testPlusOperator(self):
+ '''Test Size class + operator.'''
+ s1 = Size(5.0, 2.3)
+ s2 = Size(0.5, 3.2)
+ self.assertEqual(s1 + s2, Size(5.0 + 0.5, 2.3 + 3.2))
+
+ def testEqualOperator(self):
+ '''Test Size class == operator.'''
+ s1 = Size(5.0, 2.3)
+ s2 = Size(5.0, 2.3)
+ s3 = Size(0.5, 3.2)
+ self.assertTrue(s1 == s1)
+ self.assertTrue(s1 == s2)
+ self.assertFalse(s1 == s3)
+
+ def testNotEqualOperator(self):
+ '''Test Size class != operator.'''
+ s1 = Size(5.0, 2.3)
+ s2 = Size(5.0, 2.3)
+ s3 = Size(0.5, 3.2)
+ self.assertFalse(s1 != s1)
+ self.assertFalse(s1 != s2)
+ self.assertTrue(s1 != s3)
+
+ def testMinorEqualOperator(self):
+ '''Test Size class <= operator.'''
+ s1 = Size(5.0, 2.3)
+ s2 = Size(5.0, 2.3)
+ s3 = Size(0.5, 3.2)
+ self.assertTrue(s1 <= s1)
+ self.assertTrue(s1 <= s2)
+ self.assertTrue(s3 <= s1)
+ self.assertFalse(s1 <= s3)
+
+ def testMinorOperator(self):
+ '''Test Size class < operator.'''
+ s1 = Size(5.0, 2.3)
+ s2 = Size(0.5, 3.2)
+ self.assertFalse(s1 < s1)
+ self.assertFalse(s1 < s2)
+ self.assertTrue(s2 < s1)
+
+ def testMajorEqualOperator(self):
+ '''Test Size class >= operator.'''
+ s1 = Size(5.0, 2.3)
+ s2 = Size(5.0, 2.3)
+ s3 = Size(0.5, 3.2)
+ self.assertTrue(s1 >= s1)
+ self.assertTrue(s1 >= s2)
+ self.assertTrue(s1 >= s3)
+ self.assertFalse(s3 >= s1)
+
+ def testMajorOperator(self):
+ '''Test Size class > operator.'''
+ s1 = Size(5.0, 2.3)
+ s2 = Size(0.5, 3.2)
+ self.assertFalse(s1 > s1)
+ self.assertTrue(s1 > s2)
+ self.assertFalse(s2 > s1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/snakecase_test.py b/sources/shiboken6/tests/samplebinding/snakecase_test.py
new file mode 100644
index 000000000..a1538796a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/snakecase_test.py
@@ -0,0 +1,60 @@
+#!/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 snake case generation'''
+
+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 (SnakeCaseTest, SnakeCaseDerivedTest,
+ snake_case_global_function)
+
+
+class OverrideTest(SnakeCaseDerivedTest):
+ def virtual_func(self):
+ return 4711
+
+
+class SnakeCaseTestCase(unittest.TestCase):
+ '''Test for SnakeCaseTest'''
+ def testMemberFunctions(self):
+ s = SnakeCaseTest()
+ self.assertEqual(s.test_function1(), 42)
+
+ self.assertEqual(s.testFunctionDisabled(), 42)
+
+ self.assertEqual(s.testFunctionBoth(), 42)
+ self.assertEqual(s.test_function_both(), 42)
+
+ def virtualFunctions(self):
+ s = OverrideTest()
+ self.assertEqual(s.call_virtual_func(), 4711)
+
+ def testMemberFields(self):
+ s = SnakeCaseTest()
+ old_value = s.test_field
+ s.test_field = old_value + 1
+ self.assertEqual(s.test_field, old_value + 1)
+
+ old_value = s.testFieldDisabled
+ s.testFieldDisabled = old_value + 1
+ self.assertEqual(s.testFieldDisabled, old_value + 1)
+
+ old_value = s.test_field_both
+ s.test_field_both = old_value + 1
+ self.assertEqual(s.test_field_both, old_value + 1)
+ self.assertEqual(s.testFieldBoth, old_value + 1)
+
+ def testGlobalFunction(self):
+ self.assertEqual(snake_case_global_function(), 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py b/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py
new file mode 100644
index 000000000..cf0889299
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py
@@ -0,0 +1,91 @@
+#!/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 overloads involving static and non-static versions of a method.'''
+
+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 SimpleFile
+
+
+class SimpleFile2 (SimpleFile):
+ def exists(self):
+ return "Mooo"
+
+
+class SimpleFile3 (SimpleFile):
+ pass
+
+
+class SimpleFile4 (SimpleFile):
+ exists = 5
+
+
+class StaticNonStaticMethodsTest(unittest.TestCase):
+ '''Test cases for overloads involving static and non-static versions of a method.'''
+
+ def setUp(self):
+ filename = f'simplefile{os.getpid()}.txt'
+ self.existing_filename = Path(filename)
+ self.delete_file = False
+ if not self.existing_filename.exists():
+ with self.existing_filename.open('w') as f:
+ for line in range(10):
+ f.write('sbrubbles\n')
+ self.delete_file = True
+
+ self.non_existing_filename = Path('inexistingfile.txt')
+ i = 0
+ while self.non_existing_filename.exists():
+ i += 1
+ filename = 'inexistingfile-{i}.txt'
+ self.non_existing_filename = Path(filename)
+
+ def tearDown(self):
+ if self.delete_file:
+ os.remove(self.existing_filename)
+
+ def testCallingStaticMethodWithClass(self):
+ '''Call static method using class.'''
+ self.assertTrue(SimpleFile.exists(os.fspath(self.existing_filename)))
+ self.assertFalse(SimpleFile.exists(os.fspath(self.non_existing_filename)))
+
+ def testCallingStaticMethodWithInstance(self):
+ '''Call static method using instance of class.'''
+ f = SimpleFile(os.fspath(self.non_existing_filename))
+ self.assertTrue(f.exists(os.fspath(self.existing_filename)))
+ self.assertFalse(f.exists(os.fspath(self.non_existing_filename)))
+
+ def testCallingInstanceMethod(self):
+ '''Call instance method.'''
+ f1 = SimpleFile(os.fspath(self.non_existing_filename))
+ self.assertFalse(f1.exists())
+ f2 = SimpleFile(os.fspath(self.existing_filename))
+ self.assertTrue(f2.exists())
+
+ def testOverridingStaticNonStaticMethod(self):
+ f = SimpleFile2(os.fspath(self.existing_filename))
+ self.assertEqual(f.exists(), "Mooo")
+
+ f = SimpleFile3(os.fspath(self.existing_filename))
+ self.assertTrue(f.exists())
+
+ f = SimpleFile4(os.fspath(self.existing_filename))
+ self.assertEqual(f.exists, 5)
+
+ def testDuckPunchingStaticNonStaticMethod(self):
+ f = SimpleFile(os.fspath(self.existing_filename))
+ f.exists = lambda: "Meee"
+ self.assertEqual(f.exists(), "Meee")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/stdcomplex_test.py b/sources/shiboken6/tests/samplebinding/stdcomplex_test.py
new file mode 100644
index 000000000..0caa9764d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/stdcomplex_test.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for StdComplex class'''
+
+import os
+import math
+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 StdComplex
+
+
+REAL = 5.0
+IMAG = 2.3
+
+
+class StdComplexTest(unittest.TestCase):
+ '''Test case for StdComplex class, exercising esoteric number
+ protocols (Py_nb_). For standard number protocols, see Point.'''
+
+ def testConversion(self):
+ pt = StdComplex(REAL, IMAG)
+ self.assertEqual(int(pt), int(round(pt.abs_value())))
+ self.assertEqual(float(pt), pt.abs_value())
+
+ def testAbs(self):
+ pt = StdComplex(REAL, IMAG)
+ self.assertEqual(abs(pt), pt.abs_value())
+
+ def testPow(self):
+ '''Compare pow() function to builtin Python type.'''
+ pt = StdComplex(REAL, IMAG)
+ result = pow(pt, StdComplex(2.0, 0))
+ py_pt = complex(REAL, IMAG)
+ py_result = pow(py_pt, complex(2.0, 0))
+ self.assertAlmostEqual(result.real(), py_result.real)
+ self.assertAlmostEqual(result.imag(), py_result.imag)
+
+ def testFloor(self):
+ pt = StdComplex(REAL, IMAG)
+ self.assertEqual(math.floor(pt), math.floor(pt.abs_value()))
+
+ def testCeil(self):
+ pt = StdComplex(REAL, IMAG)
+ self.assertEqual(math.ceil(pt), math.ceil(pt.abs_value()))
+
+ def testPlusOperator(self):
+ '''Test StdComplex class + operator.'''
+ pt1 = StdComplex(REAL, IMAG)
+ pt2 = StdComplex(0.5, 3.2)
+ self.assertEqual(pt1 + pt2, StdComplex(REAL + 0.5, IMAG + 3.2))
+
+ def testEqualOperator(self):
+ '''Test StdComplex class == operator.'''
+ pt1 = StdComplex(REAL, IMAG)
+ pt2 = StdComplex(REAL, IMAG)
+ pt3 = StdComplex(0.5, 3.2)
+ self.assertTrue(pt1 == pt1)
+ self.assertTrue(pt1 == pt2)
+ self.assertFalse(pt1 == pt3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/str_test.py b/sources/shiboken6/tests/samplebinding/str_test.py
new file mode 100644
index 000000000..c06fd6428
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/str_test.py
@@ -0,0 +1,97 @@
+#!/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 a method that receives a reference to class that is implicitly
+ convertible from a Python native type.'''
+
+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
+
+
+class StrTest(unittest.TestCase):
+ '''Test cases for thr Str class.'''
+
+ def test__str__Method(self):
+ '''Test if the binding correcly implements the Python __str__ method.'''
+ s1 = 'original string'
+ s2 = Str(s1)
+ self.assertEqual(s1, s2)
+ self.assertEqual(s1, str(s2))
+
+ def testPassExactClassAsReferenceToArgument(self):
+ '''Test passing the expected class as an argument to a method that expects a reference.'''
+ s1 = Str('This is %VAR!').arg(Str('Sparta'))
+ self.assertEqual(str(s1), 'This is Sparta!')
+
+ def testPassPythonTypeImplictlyConvertibleToAClassUsedAsReference(self):
+ '''Test passing a Python class implicitly convertible to a wrapped class
+ that is expected to be passed as reference.'''
+ s1 = Str('This is %VAR!').arg('Athens')
+ self.assertEqual(str(s1), 'This is Athens!')
+
+ def testSequenceOperators(self):
+ s1 = Str("abcdef")
+ self.assertEqual(len(s1), 6)
+ self.assertEqual(len(Str()), 0)
+
+ # getitem
+ self.assertEqual(s1[0], "a")
+ self.assertEqual(s1[1], "b")
+ self.assertEqual(s1[2], "c")
+ self.assertEqual(s1[3], "d")
+ self.assertEqual(s1[4], "e")
+ self.assertEqual(s1[5], "f")
+ self.assertEqual(s1[-1], "f")
+ self.assertEqual(s1[-2], "e")
+
+ self.assertRaises(TypeError, s1.__getitem__, 6)
+
+ # setitem
+ s1[0] = 'A'
+ s1[1] = 'B'
+ self.assertEqual(s1[0], 'A')
+ self.assertEqual(s1[1], 'B')
+ self.assertRaises(TypeError, s1.__setitem__(6, 67))
+
+ def testReverseOperator(self):
+ s1 = Str("hello")
+ self.assertEqual(s1 + 2, "hello2")
+ self.assertEqual(2 + s1, "2hello")
+
+ def testToIntError(self):
+ self.assertEqual(Str('Z').toInt(), (0, False))
+
+ def testToIntWithDecimal(self):
+ decimal = Str('37')
+ val, ok = decimal.toInt()
+ self.assertEqual(type(val), int)
+ self.assertEqual(type(ok), bool)
+ self.assertEqual(val, int(str(decimal)))
+
+ def testToIntWithOctal(self):
+ octal = Str('52')
+ val, ok = octal.toInt(8)
+ self.assertEqual(type(val), int)
+ self.assertEqual(type(ok), bool)
+ self.assertEqual(val, int(str(octal), 8))
+
+ def testToIntWithHexadecimal(self):
+ hexa = Str('2A')
+ val, ok = hexa.toInt(16)
+ self.assertEqual(type(val), int)
+ self.assertEqual(type(ok), bool)
+ self.assertEqual(val, int(str(hexa), 16))
+ self.assertEqual(hexa.toInt(), (0, False))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/strlist_test.py b/sources/shiboken6/tests/samplebinding/strlist_test.py
new file mode 100644
index 000000000..2bfb80b67
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/strlist_test.py
@@ -0,0 +1,94 @@
+#!/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 StrList class that inherits from std::list<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, StrList
+
+
+class StrListTest(unittest.TestCase):
+ '''Test cases for StrList class that inherits from std::list<Str>.'''
+
+ def testStrListCtor_NoParams(self):
+ '''StrList constructor receives no parameter.'''
+ sl = StrList()
+ self.assertEqual(len(sl), 0)
+ self.assertEqual(sl.constructorUsed(), StrList.NoParamsCtor)
+
+ def testStrListCtor_Str(self):
+ '''StrList constructor receives a Str object.'''
+ s = Str('Foo')
+ sl = StrList(s)
+ self.assertEqual(len(sl), 1)
+ self.assertEqual(sl[0], s)
+ self.assertEqual(sl.constructorUsed(), StrList.StrCtor)
+
+ def testStrListCtor_PythonString(self):
+ '''StrList constructor receives a Python string.'''
+ s = 'Foo'
+ sl = StrList(s)
+ self.assertEqual(len(sl), 1)
+ self.assertEqual(sl[0], s)
+ self.assertEqual(sl.constructorUsed(), StrList.StrCtor)
+
+ def testStrListCtor_StrList(self):
+ '''StrList constructor receives a StrList object.'''
+ sl1 = StrList(Str('Foo'))
+ sl2 = StrList(sl1)
+ #self.assertEqual(len(sl1), len(sl2))
+ #self.assertEqual(sl1, sl2)
+ self.assertEqual(sl2.constructorUsed(), StrList.CopyCtor)
+
+ def testStrListCtor_ListOfStrs(self):
+ '''StrList constructor receives a Python list of Str objects.'''
+ strs = [Str('Foo'), Str('Bar')]
+ sl = StrList(strs)
+ self.assertEqual(len(sl), len(strs))
+ self.assertEqual(sl, strs)
+ self.assertEqual(sl.constructorUsed(), StrList.ListOfStrCtor)
+
+ def testStrListCtor_MixedListOfStrsAndPythonStrings(self):
+ '''StrList constructor receives a Python list of mixed Str objects and Python strings.'''
+ strs = [Str('Foo'), 'Bar']
+ sl = StrList(strs)
+ self.assertEqual(len(sl), len(strs))
+ self.assertEqual(sl, strs)
+ self.assertEqual(sl.constructorUsed(), StrList.ListOfStrCtor)
+
+ def testCompareStrListWithTupleOfStrs(self):
+ '''Compares StrList with a Python tuple of Str objects.'''
+ sl = StrList()
+ sl.append(Str('Foo'))
+ sl.append(Str('Bar'))
+ self.assertEqual(len(sl), 2)
+ self.assertEqual(sl, (Str('Foo'), Str('Bar')))
+
+ def testCompareStrListWithTupleOfPythonStrings(self):
+ '''Compares StrList with a Python tuple of Python strings.'''
+ sl = StrList()
+ sl.append(Str('Foo'))
+ sl.append(Str('Bar'))
+ self.assertEqual(len(sl), 2)
+ self.assertEqual(sl, ('Foo', 'Bar'))
+
+ def testCompareStrListWithTupleOfStrAndPythonString(self):
+ '''Compares StrList with a Python tuple of mixed Str objects and Python strings.'''
+ sl = StrList()
+ sl.append(Str('Foo'))
+ sl.append(Str('Bar'))
+ self.assertEqual(len(sl), 2)
+ self.assertEqual(sl, (Str('Foo'), 'Bar'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py b/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py
new file mode 100644
index 000000000..11279c7ec
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py
@@ -0,0 +1,63 @@
+#!/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 Photon
+
+'''This tests classes that inherit from template classes,
+ simulating a situation found in Qt's phonon module.'''
+
+
+class TemplateInheritingClassTest(unittest.TestCase):
+ def testClassBasics(self):
+ self.assertEqual(Photon.ValueIdentity.classType(), Photon.IdentityType)
+ self.assertEqual(Photon.ValueDuplicator.classType(), Photon.DuplicatorType)
+
+ def testInstanceBasics(self):
+ value = 123
+ samer = Photon.ValueIdentity(value)
+ self.assertEqual(samer.multiplicator(), 1)
+ doubler = Photon.ValueDuplicator(value)
+ self.assertEqual(doubler.multiplicator(), 2)
+ self.assertEqual(samer.value(), doubler.value())
+ self.assertEqual(samer.calculate() * 2, doubler.calculate())
+
+ def testPassToFunctionAsPointer(self):
+ obj = Photon.ValueDuplicator(123)
+ self.assertEqual(Photon.callCalculateForValueDuplicatorPointer(obj), obj.calculate())
+
+ def testPassToFunctionAsReference(self):
+ obj = Photon.ValueDuplicator(321)
+ self.assertEqual(Photon.callCalculateForValueDuplicatorReference(obj), obj.calculate())
+
+ def testPassToMethodAsValue(self):
+ value1, value2 = 123, 321
+ one = Photon.ValueIdentity(value1)
+ other = Photon.ValueIdentity(value2)
+ self.assertEqual(one.sumValueUsingPointer(other), value1 + value2)
+
+ def testPassToMethodAsReference(self):
+ value1, value2 = 123, 321
+ one = Photon.ValueDuplicator(value1)
+ other = Photon.ValueDuplicator(value2)
+ self.assertEqual(one.sumValueUsingReference(other), value1 + value2)
+
+ def testPassPointerThrough(self):
+ obj1 = Photon.ValueIdentity(123)
+ self.assertEqual(obj1, obj1.passPointerThrough(obj1))
+ obj2 = Photon.ValueDuplicator(321)
+ self.assertEqual(obj2, obj2.passPointerThrough(obj2))
+ self.assertRaises(TypeError, obj1.passPointerThrough, obj2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/time_test.py b/sources/shiboken6/tests/samplebinding/time_test.py
new file mode 100644
index 000000000..6283a6744
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/time_test.py
@@ -0,0 +1,120 @@
+#!/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 constructor and method signature decisor on Time 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()
+import datetime
+
+from sample import Time, ImplicitConv, ObjectType
+
+
+class TimeTest(unittest.TestCase):
+ '''Test cases for constructor and method signature decisor on Time class.
+ The constructor and one method have these signatures: CTORMETHOD() and
+ CTORMETHOD(int h, int m, int s = 0, int ms = 0); there another method
+ with a more complex signature METH(int, int, ImplicitConv=DEFVALUE, ObjectType=0),
+ to produce an even worse scenario.
+ '''
+
+ def testConstructorWithoutParamers(self):
+ '''Constructor without parameters: Time()'''
+ time = Time()
+ self.assertTrue(time.isNull())
+
+ def testConstructorWithAllParamers(self):
+ '''Constructor with all parameters: Time(int h, int m, int s = 0, int ms = 0)'''
+ time = Time(1, 2, 3, 4)
+ self.assertTrue(time.toString(), '01:02:03.004')
+
+ def testConstructorWithThreeParamers(self):
+ '''Constructor with 3 parameters: Time(int h, int m, int s = 0, int ms = 0)'''
+ time = Time(1, 2, 3)
+ self.assertTrue(time.toString(), '01:02:03.000')
+
+ def testConstructorWithTwoParamers(self):
+ '''Constructor with 2 parameters: Time(int h, int m, int s = 0, int ms = 0)'''
+ time = Time(1, 2)
+ self.assertTrue(time.toString(), '01:02:00.000')
+
+ def testSimpleMethodWithoutParamers(self):
+ '''Constructor without parameters: Time.setTime()'''
+ time = Time(1, 2, 3, 4)
+ time.setTime()
+ self.assertTrue(time.isNull())
+
+ def testSimpleMethodWithAllParamers(self):
+ '''Simple method with all parameters: Time.setTime(int h, int m, int s = 0, int ms = 0)'''
+ time = Time()
+ time.setTime(1, 2, 3, 4)
+ self.assertTrue(time.toString(), '01:02:03.004')
+
+ def testSimpleMethodWithThreeParamers(self):
+ '''Simple method with 3 parameters: Time.setTime(int h, int m, int s = 0, int ms = 0)'''
+ time = Time()
+ time.setTime(1, 2, 3)
+ self.assertTrue(time.toString(), '01:02:03.000')
+
+ def testSimpleMethodWithTwoParamers(self):
+ '''Simple method with 2 parameters: Time.setTime(int h, int m, int s = 0, int ms = 0)'''
+ time = Time()
+ time.setTime(1, 2)
+ self.assertTrue(time.toString(), '01:02:00.000')
+
+ def testMethodWithoutParamers(self):
+ '''Method without parameters: Time.somethingCompletelyDifferent()'''
+ time = Time()
+ result = time.somethingCompletelyDifferent()
+ self.assertEqual(result, Time.ZeroArgs)
+
+ def testMethodWithAllParamers(self):
+ '''Method with all parameters:
+ Time.somethingCompletelyDifferent(
+ int h, int m, ImplicitConv ic = ImplicitConv::CtorThree, ObjectType* type = 0
+ );
+ '''
+ time = Time()
+ obj = ObjectType()
+ result = time.somethingCompletelyDifferent(1, 2, ImplicitConv(2), obj)
+ self.assertEqual(result, Time.FourArgs)
+
+ def testMethodWithThreeParamers(self):
+ '''Method with 3 parameters: Time.somethingCompletelyDifferent(...)'''
+ time = Time()
+ result = time.somethingCompletelyDifferent(1, 2, ImplicitConv(ImplicitConv.CtorOne))
+ self.assertEqual(result, Time.ThreeArgs)
+
+ def testMethodWithTwoParamers(self):
+ '''Method with 2 parameters: Time.somethingCompletelyDifferent(...)'''
+ time = Time()
+ result = time.somethingCompletelyDifferent(1, 2)
+ self.assertEqual(result, Time.TwoArgs)
+
+ def testMethodWithThreeParamersAndImplicitConversion(self):
+ '''Method with 3 parameters, the last one triggers an implicit conversion.'''
+ time = Time()
+ result = time.somethingCompletelyDifferent(1, 2, ImplicitConv.CtorOne)
+ self.assertEqual(result, Time.ThreeArgs)
+
+ # PYSIDE-1436: These tests crash at shutdown due to `assert(Not)?Equal`.
+ def testCompareWithPythonTime(self):
+ time = Time(12, 32, 5)
+ py = datetime.time(12, 32, 5)
+ self.assertEqual(time, py)
+
+ def testNotEqual(self):
+ time = Time(12, 32, 6)
+ py = datetime.time(12, 32, 5)
+ self.assertNotEqual(time, py)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/transform_test.py b/sources/shiboken6/tests/samplebinding/transform_test.py
new file mode 100644
index 000000000..7dfd18a4a
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/transform_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
+
+'''Test cases for argument modification with more than nine arguments.'''
+
+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, applyHomogeneousTransform
+
+
+class TransformTest(unittest.TestCase):
+ '''Test cases for modifying a function with > 9 arguments.'''
+
+ def testTransform_ValidMatrix(self):
+ '''Transform applies successfully.'''
+ p = Point(3, 4)
+ r = applyHomogeneousTransform(p, 0, 1, 0, -1, 0, 0, 0, 0, 1)
+ self.assertTrue(type(r) is Point)
+ self.assertEqual(r.x(), 4)
+ self.assertEqual(r.y(), -3)
+
+ def testTransform_InvalidMatrix(self):
+ '''Transform does not apply successfully.'''
+ p = Point(3, 4)
+ r = applyHomogeneousTransform(p, 1, 0, 0, 0, 1, 0, 0, 0, 0)
+ self.assertTrue(r is None)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/typeconverters_test.py b/sources/shiboken6/tests/samplebinding/typeconverters_test.py
new file mode 100644
index 000000000..987ba6dfd
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/typeconverters_test.py
@@ -0,0 +1,190 @@
+#!/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 various usages of the type converters.'''
+
+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()
+
+import sample
+
+
+class GetPythonTypeByNameTest(unittest.TestCase):
+
+ '''Uses an added function with inject code that uses the libshiboken
+ function "Shiboken::Conversions::getPythonTypeObject(typeName)".'''
+
+ def testGetObjectType(self):
+ pyType1 = sample.getPythonType('ObjectType')
+ self.assertEqual(pyType1, sample.ObjectType)
+ pyType2 = sample.getPythonType('ObjectType*')
+ self.assertEqual(pyType2, sample.ObjectType)
+ self.assertEqual(pyType1, pyType2)
+
+ def testGetValueType(self):
+ pyType1 = sample.getPythonType('Point')
+ self.assertEqual(pyType1, sample.Point)
+ pyType2 = sample.getPythonType('Point*')
+ self.assertEqual(pyType2, sample.Point)
+ self.assertEqual(pyType1, pyType2)
+
+ def testGetUsersPrimitiveType(self):
+ pyType = sample.getPythonType('OddBool')
+ self.assertEqual(pyType, bool)
+
+ def testGetUsersPrimitiveTypeWithoutTargetLangApiName(self):
+ '''If the primitive type attribute "target-lang-api-name" is not set
+ there'll be no Python type associated with the C++ type.'''
+ pyType = sample.getPythonType('PStr')
+ self.assertEqual(pyType, None)
+
+ def testPrimitiveTypeAndTypedef(self):
+ pyType = sample.getPythonType('double')
+ self.assertEqual(pyType, float)
+ pyTypedef = sample.getPythonType('real')
+ self.assertEqual(pyType, pyTypedef)
+
+ def testPairContainerType(self):
+ pyType = sample.getPythonType('std::pair<Complex,int>')
+ self.assertEqual(pyType, list)
+
+ def testListContainerType(self):
+ pyType = sample.getPythonType('std::list<int>')
+ self.assertEqual(pyType, list)
+
+ def testMapContainerType(self):
+ pyType = sample.getPythonType('std::map<std::string,int>')
+ self.assertEqual(pyType, dict)
+
+ def testGlobalEnumType(self):
+ pyType = sample.getPythonType('GlobalEnum')
+ self.assertEqual(pyType, sample.GlobalEnum)
+
+ def testScopedEnumType(self):
+ pyType = sample.getPythonType('Abstract::Type')
+ self.assertEqual(pyType, sample.Abstract.Type)
+
+
+class CheckValueAndObjectTypeByNameTest(unittest.TestCase):
+
+ '''Uses an added function with inject code that uses the libshiboken
+ functions that check if a type is Object or Value, based on its converter.'''
+
+ def testErrors(self):
+ '''not existent type'''
+ self.assertRaises(ValueError, sample.cppTypeIsValueType, 'NotExistentType')
+ self.assertRaises(ValueError, sample.cppTypeIsObjectType, 'NotExistentType')
+
+ def testObjectType1(self):
+ self.assertTrue(sample.cppTypeIsObjectType('ObjectType'))
+ self.assertFalse(sample.cppTypeIsValueType('ObjectType'))
+
+ def testObjectType2(self):
+ self.assertTrue(sample.cppTypeIsObjectType('ObjectType*'))
+ self.assertFalse(sample.cppTypeIsValueType('ObjectType*'))
+
+ def testValueType1(self):
+ self.assertTrue(sample.cppTypeIsValueType('Point'))
+ self.assertFalse(sample.cppTypeIsObjectType('Point'))
+
+ def testValueType2(self):
+ self.assertTrue(sample.cppTypeIsValueType('Point*'))
+ self.assertFalse(sample.cppTypeIsObjectType('Point*'))
+
+ def testUsersPrimitiveType(self):
+ self.assertFalse(sample.cppTypeIsValueType('Complex'))
+ self.assertFalse(sample.cppTypeIsObjectType('Complex'))
+
+ def testContainerType(self):
+ self.assertFalse(sample.cppTypeIsValueType('std::list<int>'))
+ self.assertFalse(sample.cppTypeIsObjectType('std::list<int>'))
+
+
+class SpecificConverterTest(unittest.TestCase):
+
+ '''Uses an added function with inject code that uses the libshiboken
+ adapter class "Shiboken::Conversions::SpecificConverter".'''
+
+ def testNotExistentType(self):
+ conversion = sample.getConversionTypeString('NotExistentType')
+ self.assertEqual(conversion, 'Invalid conversion')
+
+ def testObjectType(self):
+ conversion = sample.getConversionTypeString('ObjectType')
+ self.assertEqual(conversion, 'Pointer conversion')
+ conversion = sample.getConversionTypeString('ObjectType*')
+ self.assertEqual(conversion, 'Pointer conversion')
+ conversion = sample.getConversionTypeString('ObjectType&')
+ self.assertEqual(conversion, 'Reference conversion')
+
+ def testValueType(self):
+ conversion = sample.getConversionTypeString('Point')
+ self.assertEqual(conversion, 'Copy conversion')
+ conversion = sample.getConversionTypeString('Point*')
+ self.assertEqual(conversion, 'Pointer conversion')
+ conversion = sample.getConversionTypeString('Point&')
+ self.assertEqual(conversion, 'Reference conversion')
+
+
+class StringBasedConversionTest(unittest.TestCase):
+
+ def testValueType(self):
+ pts = (sample.Point(1, 1), sample.Point(2, 2), sample.Point(3, 3))
+ result = sample.convertValueTypeToCppAndThenToPython(pts[0], pts[1], pts[2])
+ for orig, new in zip(pts, result):
+ self.assertEqual(orig, new)
+ self.assertFalse(pts[0] is result[0])
+ self.assertTrue(pts[1] is result[1])
+ self.assertTrue(pts[2] is result[2])
+
+ def testObjectType(self):
+ objs = (sample.ObjectType(), sample.ObjectType())
+ objs[0].setObjectName('obj0')
+ objs[1].setObjectName('obj1')
+ result = sample.convertObjectTypeToCppAndThenToPython(objs[0], objs[1])
+ for orig, new in zip(objs, result):
+ self.assertEqual(orig, new)
+ self.assertEqual(orig.objectName(), new.objectName())
+ self.assertTrue(orig is new)
+
+ def testContainerType(self):
+ lst = range(4)
+ result = sample.convertListOfIntegersToCppAndThenToPython(lst)
+ self.assertTrue(len(result), 1)
+ self.assertTrue(lst, result[0])
+
+
+class PrimitiveConversionTest(unittest.TestCase):
+
+ def testCppPrimitiveType(self):
+ integers = (12, 34)
+ result = sample.convertIntegersToCppAndThenToPython(integers[0], integers[1])
+ for orig, new in zip(integers, result):
+ self.assertEqual(orig, new)
+
+ def testLargeIntAsFloat(self):
+ """PYSIDE-2417: When passing an int to a function taking float,
+ a 64bit conversion should be done."""
+ point = sample.PointF(1, 2)
+ large_int = 2**31 + 2
+ point.setX(large_int)
+ self.assertEqual(round(point.x()), large_int)
+
+ def testUnsignedLongLongAsFloat(self):
+ """PYSIDE-2652: When passing an unsigned long long to a function taking float,
+ an unsigned 64bit conversion should be done."""
+ point = sample.PointF(1, 2)
+ large_int = 2**63
+ point.setX(large_int)
+ self.assertEqual(round(point.x()), large_int)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/typedealloc_test.py b/sources/shiboken6/tests/samplebinding/typedealloc_test.py
new file mode 100644
index 000000000..ce881e802
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/typedealloc_test.py
@@ -0,0 +1,60 @@
+#!/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 deallocation of type extended in Python.'''
+
+import gc
+import os
+import sys
+import unittest
+import weakref
+
+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
+
+
+class TypeDeallocTest(unittest.TestCase):
+
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ del self.called
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def callback(self, *args):
+ self.called = True
+
+ def testScopeEnd(self):
+ ref = None
+
+ def scope():
+
+ class Ext(Point):
+ pass
+
+ o = Ext() # noqa: F841
+ global ref
+ ref = weakref.ref(Ext, self.callback)
+
+ scope()
+ gc.collect()
+ self.assertTrue(self.called)
+
+ def testDeleteType(self):
+ class Ext(Point):
+ pass
+ ref = weakref.ref(Ext, self.callback) # noqa: F841
+ del Ext
+ gc.collect()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py b/sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py
new file mode 100644
index 000000000..ab8e535b5
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/typedtordoublefree_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
+
+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 ObjectType
+
+
+class TestTypeDestructorDoubleFree(unittest.TestCase):
+ def testTypeDestructorDoubleFree(self):
+ '''Causes the type destructors of two derived classes to be called.'''
+ def scope():
+ class ExtObj1(ObjectType):
+ def __init__(self):
+ ObjectType.__init__(self)
+ obj = ExtObj1()
+ child = ObjectType(parent=obj)
+ self.assertEqual(obj.takeChild(child), child)
+
+ class ExtObj2(ObjectType):
+ def __init__(self):
+ ObjectType.__init__(self)
+
+ obj = ExtObj2()
+ child = ObjectType(parent=obj)
+ self.assertEqual(obj.takeChild(child), child)
+ scope()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
new file mode 100644
index 000000000..e315e599e
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
@@ -0,0 +1,2457 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<typesystem package="sample">
+ <primitive-type name="ObjectType::Identifier"/>
+ <primitive-type name="std::nullptr_t"/>
+
+ <primitive-type name="Foo::SAMPLE_HANDLE" target-lang-api-name="PyLong"/>
+
+ <primitive-type name="std::size_t" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target>
+ return PyLong_FromSize_t(%in);
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyLong">
+ %out = %OUTTYPE(PyLong_AsSsize_t(%in));
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <inject-code class="native" position="beginning">
+ static bool Check2TupleOfNumbers(PyObject* pyIn) {
+ if (!PySequence_Check(pyIn) || !(PySequence_Size(pyIn) == 2))
+ return false;
+ Shiboken::AutoDecRef pyReal(PySequence_GetItem(pyIn, 0));
+ if (!PyNumber_Check(pyReal))
+ return false;
+ Shiboken::AutoDecRef pyImag(PySequence_GetItem(pyIn, 1));
+ if (!PyNumber_Check(pyImag))
+ return false;
+ return true;
+ }
+ </inject-code>
+ <primitive-type name="Complex" target-lang-api-name="PyComplex">
+ <include file-name="complex.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ return PyComplex_FromDoubles(%in.real(), %in.imag());
+ </native-to-target>
+ <target-to-native>
+ <!-- The 'check' attribute can be derived from the 'type' attribute,
+ it is defined here to test the CHECKTYPE type system variable. -->
+ <add-conversion type="PyComplex" check="%CHECKTYPE[Complex](%in)">
+ double real = PyComplex_RealAsDouble(%in);
+ double imag = PyComplex_ImagAsDouble(%in);
+ %out = %OUTTYPE(real, imag);
+ </add-conversion>
+ <add-conversion type="PySequence" check="Check2TupleOfNumbers(%in)">
+ Shiboken::AutoDecRef pyReal(PySequence_GetItem(%in, 0));
+ Shiboken::AutoDecRef pyImag(PySequence_GetItem(%in, 1));
+ double real = %CONVERTTOCPP[double](pyReal);
+ double imag = %CONVERTTOCPP[double](pyImag);
+ %out = %OUTTYPE(real, imag);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <primitive-type name="Null">
+ <include file-name="null.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ SBK_UNUSED(%in);
+ Py_RETURN_NONE;
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyObject" check="%in == 0 || %in == Py_None">
+ %out = %OUTTYPE(%in == 0);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <primitive-type name="SAMPLE_HANDLE" target-lang-api-name="PyComplex">
+ <include file-name="handle.h" location="local"/>
+ <conversion-rule>
+ <native-to-target>
+ if (!%in)
+ Py_RETURN_NONE;
+ return PyCapsule_New(%in, nullptr, nullptr);
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyNone">
+ SBK_UNUSED(%in)
+ %out = 0;
+ </add-conversion>
+ <add-conversion check="checkPyCapsuleOrPyCObject(%in)" type="PyObject">
+ void *ptr = PyCapsule_GetPointer(%in, nullptr);
+ %out = (%OUTTYPE)ptr;
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <inject-code class="native" position="beginning">
+ static bool checkPyCapsuleOrPyCObject(PyObject* pyObj)
+ {
+ return PyCapsule_CheckExact(pyObj);
+ }
+ </inject-code>
+
+ <primitive-type name="PrimitiveStructPtr">
+ <include file-name="handle.h" location="local"/>
+ <conversion-rule>
+ <native-to-target>
+ return PyCapsule_New(&amp;%in, nullptr, nullptr);
+ </native-to-target>
+ <target-to-native>
+ <add-conversion check="checkPyCapsuleOrPyCObject(%in)" type="PyObject">
+ void *ptr = PyCapsule_GetPointer(%in, nullptr);
+ %out = *reinterpret_cast&lt;%OUTTYPE*&gt;(ptr);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <primitive-type name="OddBool" target-lang-api-name="PyBool" default-constructor="OddBool(false)">
+ <include file-name="oddbool.h" location="global"/>
+ <include file-name="complex.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ return PyBool_FromLong(%in.value());
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyBool">
+ // Tests CONVERTTOCPP macro with C++ primitive type.
+ bool b = %CONVERTTOCPP[bool](%in);
+ %out = %OUTTYPE(b);
+ </add-conversion>
+ <add-conversion type="PyComplex">
+ // Tests CONVERTTOCPP macro with user's primitive type.
+ Complex cpx = %CONVERTTOCPP[Complex](%in);
+ %out = %OUTTYPE(cpx.real() != 0.0 || cpx.imag() != 0.0);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <!-- As of Qt 6, there is a trend of hiding bool returns of comparison
+ operators of container classes behind some template expression using
+ SFINAE depending on their value's traits, like:
+ template <typename U = T>
+ friend QTypeTraits::compare_eq_result<U> operator==(const QList &l, const QList &r)
+ which the clang parser cannot identify. Rich comparison of classes
+ inheriting QList (QPolygon, QItemSelection) will then not be generated.
+ To work around, the operators should be added manually without
+ injecting code. The code should just use the standard implementation. -->
+ <value-type name="ComparisonTester">
+ <include file-name="oddbool.h" location="global"/>
+ <add-function signature="operator==(const ComparisonTester&amp;)" return-type="bool"/>
+ <add-function signature="operator!=(const ComparisonTester&amp;)" return-type="bool"/>
+ </value-type>
+ <value-type name="SpaceshipComparisonTester">
+ <enum-type name="Enabled"/>
+ </value-type>
+
+ <primitive-type name="PStr">
+ <include file-name="str.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ return Shiboken::String::fromCString(%in.cstring(), %in.size());
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyUnicode" check="Shiboken::String::check(%in)">
+ const char* str = %CONVERTTOCPP[const char*](%in);
+ %out = %OUTTYPE(str);
+ </add-conversion>
+ <add-conversion type="Py_None">
+ SBK_UNUSED(%in)
+ %out = %OUTTYPE();
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <function signature="changePStr(PStr*, const char*)">
+ <!--
+ Comment out these modifications and the Shiboken generator
+ will issue a fatal error, because it can't handle a pointer
+ to a primitive type (PStr*) without help from the binding
+ developer.
+ -->
+ <modify-function>
+ <modify-argument index="1">
+ <replace-type modified-type="PStr"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ %FUNCTION_NAME(&amp;%1, %2);
+ %PYARG_0 = %CONVERTTOPYTHON[PStr](%1);
+ </inject-code>
+ </modify-function>
+ </function>
+
+ <function signature="duplicatePStr(PStr*)">
+ <modify-function>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <replace-type modified-type="PStr"/>
+ <replace-default-expression with="PStr()"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ %FUNCTION_NAME(&amp;%1);
+ %PYARG_0 = %CONVERTTOPYTHON[PStr](%1);
+ </inject-code>
+ </modify-function>
+ </function>
+
+ <primitive-type name="PStrList">
+ <include file-name="strlist.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ PyObject *%out = PyList_New(Py_ssize_t(%in.size()));
+ Py_ssize_t idx = 0;
+ for (const auto &amp;s : %in) {
+ PStr cppItem(s);
+ PyList_SET_ITEM(%out, idx++, %CONVERTTOPYTHON[PStr](cppItem));
+ }
+ return %out;
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ %OUTTYPE&amp; list = %out;
+ Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
+ for (int i = 0; i &lt; PySequence_Fast_GET_SIZE(seq.object()); i++) {
+ PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), i);
+ PStr cppItem = %CONVERTTOCPP[PStr](pyItem);
+ list.push_back(cppItem);
+ }
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <add-function signature="createPStrList(PStr, PStr)" return-type="PyObject">
+ <inject-code class="target">
+ PStrList %0;
+ %0.push_back(%1);
+ %0.push_back(%2);
+ %PYARG_0 = %CONVERTTOPYTHON[PStrList](%0);
+ </inject-code>
+ </add-function>
+ <add-function signature="createListOfPStr(PStr, PStr)" return-type="PyObject">
+ <inject-code class="target">
+ std::list&lt;PStr&gt; %0;
+ %0.push_back(%1);
+ %0.push_back(%2);
+ %PYARG_0 = %CONVERTTOPYTHON[std::list&lt;PStr&gt;](%0);
+ </inject-code>
+ </add-function>
+
+ <add-function signature="getPythonType(const char*)" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ SBK_UNUSED(self)
+ %PYARG_0 = (PyObject*) Shiboken::Conversions::getPythonTypeObject(%1);
+ if (!%PYARG_0)
+ %PYARG_0 = Py_None;
+ Py_INCREF(%PYARG_0);
+ </inject-code>
+ </add-function>
+
+ <template name="cpp_type_is_object_or_value_type">
+ SbkConverter* converter = Shiboken::Conversions::getConverter(%1);
+ if (converter) {
+ if (Shiboken::Conversions::pythonTypeIs$TYPEType(converter))
+ %PYARG_0 = Py_True;
+ else
+ %PYARG_0 = Py_False;
+ Py_INCREF(%PYARG_0);
+ } else {
+ PyErr_Format(PyExc_ValueError, "Type '%s' has no converter associated to it", %1);
+ }
+ </template>
+ <add-function signature="cppTypeIsObjectType(const char*)" return-type="bool">
+ <inject-code class="target" position="beginning">
+ <insert-template name="cpp_type_is_object_or_value_type">
+ <replace from="$TYPE" to="Object" />
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="cppTypeIsValueType(const char*)" return-type="bool">
+ <inject-code class="target" position="beginning">
+ <insert-template name="cpp_type_is_object_or_value_type">
+ <replace from="$TYPE" to="Value" />
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="getConversionTypeString(const char*)" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ Shiboken::Conversions::SpecificConverter converter(%1);
+ const char* %0 = 0;
+ switch (converter.conversionType()) {
+ case Shiboken::Conversions::SpecificConverter::CopyConversion:
+ %0 = "Copy conversion";
+ break;
+ case Shiboken::Conversions::SpecificConverter::PointerConversion:
+ %0 = "Pointer conversion";
+ break;
+ case Shiboken::Conversions::SpecificConverter::ReferenceConversion:
+ %0 = "Reference conversion";
+ break;
+ default:
+ %0 = "Invalid conversion";
+ }
+ %PYARG_0 = %CONVERTTOPYTHON[const char*](%0);
+ </inject-code>
+ </add-function>
+
+ <inject-code class="native" position="beginning">
+ static PyObject* __convertCppValuesToPython(const char** typeName, void** values, int size)
+ {
+ PyObject* result = PyTuple_New(size);
+ for (int i = 0; i &lt; size; ++i) {
+ Shiboken::Conversions::SpecificConverter converter(typeName[i]);
+ PyTuple_SET_ITEM(result, i, converter.toPython(values[i]));
+ }
+ return result;
+ }
+ </inject-code>
+ <add-function signature="convertValueTypeToCppAndThenToPython(Point,Point*,Point&amp;)" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ const char* typeNames[] = { "Point", "Point*", "Point&amp;" };
+ void* values[] = { &amp;%1, &amp;%2, &amp;(%3) };
+ %PYARG_0 = __convertCppValuesToPython(typeNames, values, 3);
+ </inject-code>
+ </add-function>
+ <add-function signature="convertObjectTypeToCppAndThenToPython(ObjectType*,ObjectType&amp;)" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ const char* typeNames[] = { "ObjectType*", "ObjectType&amp;" };
+ void* values[] = { &amp;%1, &amp;(%2) };
+ %PYARG_0 = __convertCppValuesToPython(typeNames, values, 2);
+ </inject-code>
+ </add-function>
+ <add-function signature="convertListOfIntegersToCppAndThenToPython(std::list&lt;int&gt;)" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ const char* typeNames[] = { "std::list&lt;int&gt;" };
+ void* values[] = { &amp;%1 };
+ %PYARG_0 = __convertCppValuesToPython(typeNames, values, 1);
+ </inject-code>
+ </add-function>
+ <add-function signature="convertIntegersToCppAndThenToPython(int,int)" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ const char* typeNames[] = { "int", "int" };
+ void* values[] = { &amp;%1, &amp;%2 };
+ %PYARG_0 = __convertCppValuesToPython(typeNames, values, 2);
+ </inject-code>
+ </add-function>
+
+ <template name="cpp_indexed_list_to_pylist_conversion">
+ PyObject *%out = PyList_New(Py_ssize_t(%in.size()));
+ Py_ssize_t idx = 0;
+ for (auto it = %in.cbegin(), end = %in.cend(); it != end; ++it, ++idx) {
+ %INTYPE_0 cppItem(*it);
+ PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
+ }
+ return %out;
+ </template>
+ <container-type name="List" type="list">
+ <include file-name="list" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="cpp_indexed_list_to_pylist_conversion"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="shiboken_conversion_pyiterable_to_cppsequentialcontainer"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+ <add-function signature="cacheSize()" return-type="int">
+ <inject-code class="target">
+ %RETURN_TYPE %0 = Shiboken::BindingManager::instance().getAllPyObjects().size();
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+
+ <namespace-type name="sample">
+ <value-type name="sample" />
+ </namespace-type>
+
+ <function signature="sumComplexPair(std::pair&lt;Complex, Complex>)" />
+ <function signature="gimmeComplexList()" />
+ <function signature="transmuteComplexIntoPoint(const Complex&amp;)" />
+ <function signature="transmutePointIntoComplex(const Point&amp;)" />
+ <function signature="sumComplexPair(std::pair&lt;Complex, Complex>)" />
+ <function signature="doubleUnsignedInt(unsigned int)" />
+ <function signature="doubleLongLong(long long)" />
+ <function signature="doubleUnsignedLongLong(unsigned long long)" />
+ <function signature="doubleShort(short)" />
+ <function signature="returnNullPrimitivePointer()" />
+ <function signature="returnNullValueTypePointer()" />
+ <function signature="returnNullObjectTypePointer()" />
+ <function signature="acceptInt(int)" />
+ <function signature="acceptIntReturnPtr(int)"/>
+ <function signature="acceptUInt(unsigned int)" />
+ <function signature="acceptLong(long)" />
+ <function signature="acceptULong(unsigned long)" />
+ <function signature="acceptDouble(double)" />
+ <function signature="acceptIntReference(int&amp;)" />
+ <function signature="acceptOddBoolReference(OddBool&amp;)" />
+ <function signature="countCharacters(const char*)" />
+ <function signature="gimmeInt()" />
+ <function signature="gimmeDouble()" />
+ <function signature="makeCString()" />
+ <function signature="sumIntArray(int[4])"/>
+ <function signature="sumDoubleArray(double[4])"/>
+ <function signature="sumIntMatrix(int[2][3])"/>
+ <function signature="sumDoubleMatrix(double[2][3])"/>
+ <function signature="multiplyPair(std::pair&lt;double, double>)" />
+ <function signature="returnCString()" />
+ <function signature="overloadedFunc(double)" />
+ <function signature="overloadedFunc(int)" />
+ <function signature="addStdStrings(const std::string&amp;, const std::string&amp;)"/>
+ <function signature="addStdWStrings(const std::wstring&amp;, const std::wstring&amp;)"/>
+ <function signature="testNullPtrT(std::nullptr_t)"/>
+ <function signature="takePolygon(Polygon&amp;&amp;)"/>
+ <function signature="takeObjectType(ObjectType&amp;&amp;)"/>
+
+ <value-type name="ArrayModifyTest">
+ <modify-function signature="sumIntArray(int, int*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="ClassWithFunctionPointer">
+ <suppress-warning text="^skipping public function 'void ClassWithFunctionPointer::callFunctionPointer.*$" />
+ </value-type>
+
+ <value-type name="IntArray" generate="no"/>
+ <value-type name="IntArray2">
+ <modify-function signature="IntArray2(const int*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="IntArray3">
+ <modify-function signature="IntArray3(const int*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ </value-type>
+
+ <enum-type name="OverloadedFuncEnum"/>
+ <!-- BUG:
+ renaming the ICOverloadedFuncEnum to the same name
+ of a global enum causes the generator to confuse the
+ two types.
+ -->
+ <enum-type name="GlobalEnum"/>
+ <enum-type name="GlobalOverloadFuncEnum"/>
+
+ <enum-type identified-by-value="AnonymousGlobalEnum_Value0"/>
+
+ <namespace-type name="SampleNamespace">
+ <namespace-type name="InlineNamespace">
+ <value-type name="ClassWithinInlineNamespace"/>
+ <enum-type name="EnumWithinInlineNamespace"/>
+ </namespace-type>
+ <enum-type name="Option"/>
+ <enum-type name="InValue"/>
+ <enum-type name="OutValue"/>
+ <enum-type identified-by-value="AnonymousClassEnum_Value1"/>
+
+ <object-type name="DerivedFromNamespace">
+ <enum-type name="SampleNamespace"/>
+ </object-type>
+ <value-type name="SomeClass">
+ <enum-type name="PublicScopedEnum"/>
+ <value-type name="SomeInnerClass">
+ <object-type name="OkThisIsRecursiveEnough">
+ <enum-type name="NiceEnum" />
+ <enum-type name="NiceEnumClass" />
+ </object-type>
+ <enum-type name="ProtectedEnum"/>
+ </value-type>
+ <value-type name="SomeOtherInnerClass"/>
+ <enum-type name="ProtectedEnum"/>
+ </value-type>
+
+ <modify-function signature="doSomethingWithArray(const unsigned char*, unsigned int, const char*)">
+ <modify-argument index="1">
+ <replace-type modified-type="const char*"/>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion>
+ const unsigned char* %out = reinterpret_cast&lt;const unsigned char*>(Shiboken::String::toCString(%PYARG_1));
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ <conversion-rule class="native">
+ unsigned int %out = static_cast&lt;unsigned int>(Shiboken::String::len(%PYARG_1));
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="ImInsideANamespace(int, int)" return-type="int">
+ <inject-code class="target">
+ %RETURN_TYPE %0 = %1 + %2;
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+ <add-function signature="passReferenceToValueType(Point&amp;)" return-type="double">
+ <inject-code>
+ %RETURN_TYPE %0 = %1.x() + %1.y();
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+
+ <!-- Do change the argument from pointer to reference to comply with the C++ overload
+ of this function. The generator must be able to deal with this for Object Types. -->
+ <add-function signature="passReferenceToObjectType(ObjectType*)" return-type="int">
+ <inject-code>
+ // The dot in "%1." must be replaced with a "->" by the generator.
+ %RETURN_TYPE %0 = %1.objectName().size();
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+
+ <object-type name="CtParam"/>
+ </namespace-type>
+
+ <namespace-type name="RemovedNamespace1" visible='false'>
+ <enum-type name="RemovedNamespace1_Enum" />
+ <function signature="mathSum(int,int)"/>
+ <value-type name="ObjectOnInvisibleNamespace" />
+ <namespace-type name="RemovedNamespace2" visible='false'>
+ <enum-type name="RemovedNamespace2_Enum" />
+ </namespace-type>
+ <enum-type identified-by-value="RemovedNamespace1_AnonymousEnum_Value0" />
+ </namespace-type>
+
+ <namespace-type name="UnremovedNamespace">
+ <namespace-type name="RemovedNamespace3" visible='false'>
+ <enum-type name="RemovedNamespace3_Enum" />
+ <enum-type identified-by-value="RemovedNamespace3_AnonymousEnum_Value0" />
+ </namespace-type>
+ </namespace-type>
+
+ <namespace-type name="Photon">
+ <enum-type name="ClassType"/>
+ <value-type name="Base"/>
+ <value-type name="TemplateBase" generate="no"/>
+ <value-type name="ValueIdentity"/>
+ <value-type name="ValueDuplicator"/>
+ </namespace-type>
+
+ <value-type name="CVValueType"/>
+ <value-type name="CVListUser"/>
+
+ <value-type name="IntList">
+ <enum-type name="CtorEnum"/>
+ </value-type>
+ <value-type name="PointValueList">
+ <enum-type name="CtorEnum"/>
+ </value-type>
+ <value-type name="ObjectTypePtrList">
+ <enum-type name="CtorEnum"/>
+ </value-type>
+
+ <object-type name="Abstract">
+ <enum-type name="Type"/>
+ <enum-type name="PrintFormat"/>
+ <modify-function signature="id()" rename="id_"/>
+ <modify-function signature="hideFunction(HideType*)" remove="all"/>
+ <modify-field name="toBeRenamedField" rename="renamedField"/>
+ <modify-field name="readOnlyField" write="false"/>
+ <modify-function signature="virtualWithOutParameter(int&amp;)const">
+ <inject-code class="shell" position="override">
+ x = virtualWithOutParameterPyOverride(gil, pyOverride.object());
+ return;
+ </inject-code>
+ </modify-function>
+ <add-function signature="virtualWithOutParameterPyOverride()"
+ return-type="int" python-override="true"/>
+ </object-type>
+
+ <object-type name="Derived" polymorphic-id-expression="%1->type() == Derived::TpDerived">
+ <enum-type name="OtherOverloadedFuncEnum"/>
+ <value-type name="SomeInnerClass" />
+ </object-type>
+
+ <object-type name="DerivedUsingCt"/>
+
+ <object-type name="ModifiedConstructor">
+ <modify-function signature="ModifiedConstructor(int)">
+ <modify-argument index="1">
+ <replace-type modified-type="str"/>
+ </modify-argument>
+ <inject-code class='target' position='beginning'>
+ const char* tmpArg = %CONVERTTOCPP[const char*](%PYARG_1);
+ %0 = new %FUNCTION_NAME(atoi(tmpArg));
+ </inject-code>
+ </modify-function>
+ </object-type>
+
+ <object-type name="ObjectType" hash-function="objectTypeHash" parent-management="yes">
+ <modify-function signature="deprecatedFunction()" deprecated="yes" />
+ <!-- rename function to avoid Python signature conflit -->
+ <modify-function signature="setObject(const Null&amp;)" rename="setNullObject" />
+
+ <modify-function signature="getCppParent()">
+ <modify-argument index="this">
+ <parent index="return" action="add" />
+ </modify-argument>
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="event(Event*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="invalidateEvent(Event*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="create()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="createWithChild()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setParent(ObjectType*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <inject-code class="native" position="beginning">
+ static void reparent_layout_items(PyObject* parent, PyObject* layout)
+ {
+ // CHECKTYPE and ISCONVERTIBLE are used here for test purposes, don't change them.
+ if (!%CHECKTYPE[ObjectTypeLayout*](layout) &amp;&amp; !%ISCONVERTIBLE[ObjectTypeLayout*](layout))
+ return;
+ /* %CHECKTYPE[ObjectTypeLayout*](layout) */
+ /* %ISCONVERTIBLE[ObjectTypeLayout*](layout) */
+ ObjectTypeLayout* var;
+ var = %CONVERTTOCPP[ObjectTypeLayout*](layout);
+ // TODO-CONVERTER: erase this
+ /*
+ ObjectTypeLayout* var2 = %CONVERTTOCPP[ObjectTypeLayout*](layout);
+ */
+ const ObjectTypeList&amp; objChildren = var->objects();
+ ObjectTypeList::const_iterator it = objChildren.begin();
+ for (; it != objChildren.end(); ++it) {
+ if ((*it)->isLayoutType()) {
+ ObjectTypeLayout* l = reinterpret_cast&lt;ObjectTypeLayout*>(*it);
+ reparent_layout_items(parent, %CONVERTTOPYTHON[ObjectTypeLayout*](l));
+ Shiboken::Object::setParent(layout, %CONVERTTOPYTHON[ObjectTypeLayout*](l));
+ } else {
+ Shiboken::Object::setParent(parent, %CONVERTTOPYTHON[ObjectType*](*it));
+ }
+ }
+ }
+ </inject-code>
+ <modify-function signature="setLayout(ObjectTypeLayout*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ if (%PYARG_1 != Py_None)
+ reparent_layout_items(%PYSELF, %PYARG_1);
+ </inject-code>
+ </modify-function>
+ <modify-function signature="takeChild(ObjectType*)">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeChild(const Str&amp;)">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="findChild(const Str&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="children()const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="createChild(ObjectType*)">
+ <modify-argument index="return">
+ <define-ownership owner="c++" />
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="nextInFocusChain()">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="OtherBase" />
+ <object-type name="ObjectTypeDerived" />
+
+ <object-type name="ObjectTypeLayout">
+ <modify-function signature="create()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="ObjectView">
+ <modify-function signature="ObjectView(ObjectModel*, ObjectType*)">
+ <modify-argument index="1">
+ <reference-count action="set" variable-name="setModel(ObjectModel*)1"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setModel(ObjectModel*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="ObjectTypeHolder"/>
+ <value-type name="OnlyCopy"/>
+ <value-type name="FriendOfOnlyCopy"/>
+
+ <object-type name="ObjectModel">
+ <enum-type name="MethodCalled" />
+ <modify-function signature="data() const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <value-type name="Event">
+ <enum-type name="EventType"/>
+ <enum-type name="EventTypeClass"/>
+ </value-type>
+
+ <value-type name="BlackBox">
+ <modify-function signature="keepObjectType(ObjectType*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="retrieveObjectType(int)">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="keepPoint(Point*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="retrievePoint(int)">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="ProtectedNonPolymorphic">
+ <modify-function signature="create()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="modifiedProtectedSum(int, int)">
+ <inject-code class="target" position="beginning">
+ %RETURN_TYPE %0 = %CPPSELF.%TYPE::%FUNCTION_NAME(%1, %2) * 10;
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </modify-function>
+ <modify-function signature="dataTypeName(void*) const" remove="all"/>
+ <modify-function signature="dataTypeName(int) const">
+ <modify-argument index="1">
+ <replace-default-expression with="0"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="dataTypeName(PyObject*)const" return-type="const char*">
+ <inject-code class="target" position="beginning">
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%PYARG_1);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="ProtectedPolymorphic">
+ <modify-function signature="create()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="ProtectedPolymorphicDaughter">
+ <modify-function signature="create()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="ProtectedPolymorphicGrandDaughter">
+ <modify-function signature="create()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <object-type name="ProtectedVirtualDestructor">
+ <modify-function signature="create()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+
+ <object-type name="ProtectedEnumClass">
+ <enum-type name="ProtectedEnum" />
+ <enum-type name="PublicEnum" />
+ </object-type>
+
+ <value-type name="ProtectedProperty" />
+
+ <function signature="createProtectedProperty()" />
+
+ <template name="boolptr_at_end_fix_beginning">
+ bool __ok__;
+ %RETURN_TYPE %0 = %CPPSELF.%TYPE::%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;__ok__);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </template>
+
+ <template name="boolptr_at_start_fix_beginning">
+ bool __ok__;
+ %RETURN_TYPE %0 = %CPPSELF.%TYPE::%FUNCTION_NAME(&amp;__ok__, %ARGUMENT_NAMES);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </template>
+
+ <template name="boolptr_at_start_and_one_arg_fix_beginning">
+ bool __ok__;
+ %RETURN_TYPE %0 = %CPPSELF.%TYPE::%FUNCTION_NAME(&amp;__ok__, %2);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </template>
+
+ <template name="boolptr_fix_end">
+ PyObject* _tuple_ = PyTuple_New(2);
+ PyTuple_SET_ITEM(_tuple_, 0, %PYARG_0);
+ PyObject* _item_ = %CONVERTTOPYTHON[bool](__ok__);
+ PyTuple_SET_ITEM(_tuple_, 1, _item_);
+ %PYARG_0 = _tuple_;
+ </template>
+
+ <template name="return_4_arguments_as_tuple">
+ %PYARG_0 = PyTuple_New(4);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG2_TYPE](%2));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[%ARG3_TYPE](%3));
+ PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[%ARG4_TYPE](%4));
+ </template>
+
+ <template name="return_5_arguments_as_tuple">
+ %PYARG_0 = PyTuple_New(5);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG2_TYPE](%2));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[%ARG3_TYPE](%3));
+ PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[%ARG4_TYPE](%4));
+ PyTuple_SET_ITEM(%PYARG_0, 4, %CONVERTTOPYTHON[%ARG5_TYPE](%5));
+ </template>
+
+ <template name="return_none">
+ %PYARG_0 = Py_None;
+ Py_INCREF(Py_None);
+ </template>
+
+ <object-type name="Modifications">
+ <enum-type name="OverloadedModFunc"/>
+ <enum-type name="TestEnum"/>
+
+ <modify-function signature="overloaded(int, bool, int, double)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ %RETURN_TYPE %0 = %CPPSELF.%TYPE::%FUNCTION_NAME(%1, true, %3, %4);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="overloaded(int, bool, int, int)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <replace-default-expression with="321"/>
+ </modify-argument>
+ <!--
+ <modify-argument index="4">
+ <remove-default-expression/>
+ </modify-argument>
+ -->
+ </modify-function>
+
+ <modify-function signature="argRemoval0(int, bool, int, int)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <replace-default-expression with="321"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_4_arguments_as_tuple"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="argRemoval1(int, bool, Point, Point, int)">
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_5_arguments_as_tuple"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="argRemoval1(int, bool, int, bool)">
+ <inject-code class="target" position="end">
+ <insert-template name="return_none"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="argRemoval2(int, bool, Point, Point, int)">
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_5_arguments_as_tuple"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="argRemoval3(int, Point, bool, Point, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_5_arguments_as_tuple"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="argRemoval4(int, Point, bool, Point, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <replace-default-expression with="Point(6, 9)"/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_5_arguments_as_tuple"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="argRemoval5(int, bool, Point, Point, int)">
+ <modify-argument index="1">
+ <remove-argument/>
+ <replace-default-expression with="100"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_5_arguments_as_tuple"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="argRemoval5(int, bool, int, bool)">
+ <modify-argument index="1">
+ <remove-argument/>
+ <replace-default-expression with="200"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_4_arguments_as_tuple"/>
+ </inject-code>
+ </modify-function>
+
+ <!--
+ this alteration will trigger an interesting
+ compile time error on the binding
+ -->
+ <!--
+ <modify-function signature="overloaded(int, bool, Point, Point)">
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ </modify-function>
+ -->
+
+ <!--
+ renaming this signature should remove it from the other
+ overloaded methods decision tree
+ -->
+ <modify-function signature="overloaded(int, bool, Point, Point)" rename="over"/>
+
+ <!--
+ 'ok' must be removed and the return value will be changed
+ to a tuple (PyObject*) containing the expected result plus
+ the 'ok' value as a Python boolean
+ -->
+ <modify-function signature="pointToPair(Point, bool*)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="boolptr_at_end_fix_beginning"/>
+ </inject-code>
+ <inject-code class="target" position="end">
+ <insert-template name="boolptr_fix_end"/>
+ </inject-code>
+ </modify-function>
+
+ <!-- same as 'pointToPair' except that this time 'ok' is the first argument -->
+ <modify-function signature="multiplyPointCoordsPlusValue(bool*, Point, double)">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="boolptr_at_start_fix_beginning"/>
+ </inject-code>
+ <inject-code class="target" position="end">
+ <insert-template name="boolptr_fix_end"/>
+ </inject-code>
+ </modify-function>
+
+ <!-- completely remove 'plus' from the Python side -->
+ <modify-function signature="doublePlus(int, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ </modify-function>
+
+ <!-- the default value for both arguments must be changed in Python -->
+ <modify-function signature="power(int, int)">
+ <modify-argument index="1">
+ <replace-default-expression with="2"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <replace-default-expression with="1"/>
+ </modify-argument>
+ </modify-function>
+
+ <!-- in Python set argument default value to 10 -->
+ <modify-function signature="timesTen(int)">
+ <modify-argument index="1">
+ <replace-default-expression with="10"/>
+ </modify-argument>
+ </modify-function>
+
+ <!-- in Python remove the argument default value -->
+ <modify-function signature="increment(int)">
+ <modify-argument index="1">
+ <remove-default-expression/>
+ </modify-argument>
+ </modify-function>
+
+ <!-- don't export this method to Python -->
+ <modify-function signature="exclusiveCppStuff()" remove="all"/>
+
+ <!-- change the name of this regular method -->
+ <modify-function signature="cppMultiply(int, int)" rename="calculateArea"/>
+
+ <!-- change the name of this virtual method -->
+ <modify-function signature="className()" rename="name"/>
+
+ <modify-function signature="sumPointArray(int, const Point[])">
+ <modify-argument index="1">
+ <remove-argument/>
+ <conversion-rule class="native">
+ const auto %out = PySequence_Size(%PYARG_1);
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="2">
+ <replace-type modified-type="PySequence" />
+ <conversion-rule class="native">
+ Shiboken::AutoArrayPointer&lt;Point&gt; %out(%1);
+ for (Py_ssize_t i = 0; i &lt; %1; ++i)
+ %out[i] = %CONVERTTOCPP[Point](PySequence_Fast_GET_ITEM(%PYARG_1, i));
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="getSize(const void*,int)">
+ <modify-argument index="1">
+ <replace-type modified-type="ByteArray&amp;"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <replace-default-expression with="-1"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ int size = (%2 &lt; 0) ? %1.size() : %2;
+ %BEGIN_ALLOW_THREADS
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME((const void*) %1.data(), size);
+ %END_ALLOW_THREADS
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </modify-function>
+ <modify-function signature="sumPointCoordinates(const Point*)">
+ <modify-argument index="1">
+ <no-null-pointer/>
+ </modify-argument>
+ </modify-function>
+ <template name="differenceOfPointCoordinates_arg2">
+ bool _status;
+ bool* %2 = &amp;_status;
+ </template>
+ <template name="differenceOfPointCoordinates_returnTarget">
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](*%2));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
+ </template>
+ <modify-function signature="differenceOfPointCoordinates(const Point*, bool*)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="differenceOfPointCoordinates_arg2"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PySequence"/>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion>
+ Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0));
+ Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1));
+ *%2 = %CONVERTTOCPP[bool](_py_ok_);
+ %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ret_);
+ </add-conversion>
+ </target-to-native>
+ <native-to-target>
+ <insert-template name="differenceOfPointCoordinates_returnTarget"/>
+ </native-to-target>
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="callDifferenceOfPointCoordinates(const Point*, bool*)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="differenceOfPointCoordinates_arg2"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PySequence"/>
+ <conversion-rule class="target">
+ <insert-template name="differenceOfPointCoordinates_returnTarget"/>
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="nonConversionRuleForArgumentWithDefaultValue(ObjectType**)">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="(status, object)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ ObjectType* tmpObject = 0;
+ %BEGIN_ALLOW_THREADS
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(&amp;tmpObject);
+ %END_ALLOW_THREADS
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[ObjectType*](tmpObject));
+ </inject-code>
+ </modify-function>
+ <modify-function signature="passOddBool(OddBool)" rename="invertBoolean">
+ <inject-code class="target" position="beginning">
+ %RETURN_TYPE %0 = !%CPPSELF.%FUNCTION_NAME(%1);
+ %PYARG_0 = %CONVERTTOPYTHON[OddBool](%0);
+ </inject-code>
+ </modify-function>
+ <modify-function signature="setEnumValue(Modifications::TestEnum)">
+ <modify-argument index="1">
+ <replace-default-expression with="cppSelf->defaultEnumValue()"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="__getattro__" return-type="PyObject *">
+ <inject-code class="target" position="beginning">
+ cppSelf->notifyGetAttroCalled();
+ </inject-code>
+ </add-function>
+ <add-function signature="__setattro__" return-type="int">
+ <inject-code class="target" position="beginning">
+ cppSelf->notifySetAttroCalled();
+ </inject-code>
+ </add-function>
+ </object-type>
+
+ <object-type name="AbstractModifications">
+ <!--
+ completely removing the pure virtual method from this
+ class will generate an #error directive.
+ -->
+ <!--
+ <modify-function signature="pointlessPureVirtualMethod()" remove="all"/>
+ -->
+ </object-type>
+
+ <value-type name="Reference">
+ <modify-function signature="returnMyFirstArg(Reference&amp;)">
+ <modify-argument index="return">
+ <replace-default-expression with="%1"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="returnMySecondArg(int, Reference&amp;)">
+ <modify-argument index="return">
+ <replace-default-expression with="%2"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <object-type name="ObjTypeReference">
+ <modify-function signature="returnMyFirstArg(ObjTypeReference&amp;)">
+ <modify-argument index="return">
+ <replace-default-expression with="%1"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="returnMySecondArg(int, ObjTypeReference&amp;)">
+ <modify-argument index="return">
+ <replace-default-expression with="%2"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="justAPureVirtualFunc(ObjTypeReference&amp;)">
+ <modify-argument index="return">
+ <replace-default-expression with="%1"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="ImplicitConv">
+ <enum-type name="CtorEnum"/>
+ <enum-type name="ICOverloadedFuncEnum"/>
+ </value-type>
+
+ <value-type name="VirtualMethods">
+ <modify-function signature="sum0(int, int, int)" rename="sumThree"/>
+ <modify-function signature="sum1(int, int, int)">
+ <modify-argument index="3">
+ <replace-default-expression with="1000"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="sum2(int, int, int)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <replace-default-expression with="2000"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="sum3(int, int, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ %RETURN_TYPE %0 = %CPPSELF.%TYPE::%FUNCTION_NAME(%1, %1+%3, %3);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </modify-function>
+ <modify-function signature="sum4(int, int, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <replace-default-expression with="3000"/>
+ </modify-argument>
+ <inject-code class="native" position="beginning">
+ PyObject* new_arg0 = PyLong_FromLong(PyLong_AS_LONG(%PYARG_1) - %2);
+ Py_DECREF(%PYARG_1);
+ %PYARG_1 = new_arg0;
+ </inject-code>
+ </modify-function>
+ <modify-function signature="name()">
+ <inject-code class="native" position="end">
+ %0.prepend(Str("Pimped"));
+ </inject-code>
+ </modify-function>
+ <modify-function signature="callMe()">
+ <inject-code class="native" position="end">
+ PyObject_Call(%PYTHON_METHOD_OVERRIDE, %PYTHON_ARGUMENTS, NULL);
+ </inject-code>
+ </modify-function>
+ <modify-function signature="createStr(const char*, Str*&amp;)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PySequence"/>
+ <conversion-rule class="native">
+ Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0));
+ Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1));
+ %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ok_);
+ %2 = %CONVERTTOCPP[Str*](_py_ret_);
+ </conversion-rule>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ Str* _str_arg_ = 0;
+ %RETURN_TYPE %0 = %CPPSELF.%TYPE::%FUNCTION_NAME(%1, _str_arg_);
+ </inject-code>
+ <inject-code class="target" position="end">
+ %PYARG_0 = PyTuple_New(2);
+ PyObject* _item_ = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ PyTuple_SET_ITEM(%PYARG_0, 0, _item_);
+ _item_ = %CONVERTTOPYTHON[Str*](_str_arg_);
+ PyTuple_SET_ITEM(%PYARG_0, 1, _item_);
+ </inject-code>
+ </modify-function>
+ <modify-function signature="callCreateStr(const char*, Str*&amp;)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PySequence"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ Str* _str_arg_ = 0;
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, _str_arg_);
+ </inject-code>
+ <inject-code class="target" position="end">
+ %PYARG_0 = PyTuple_New(2);
+ PyObject* _item_ = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ PyTuple_SET_ITEM(%PYARG_0, 0, _item_);
+ _item_ = %CONVERTTOPYTHON[Str*](_str_arg_);
+ PyTuple_SET_ITEM(%PYARG_0, 1, _item_);
+ </inject-code>
+ </modify-function>
+ <template name="fix_int*,int*,int*,int*">
+ int a0, a1, a2, a3;
+ %BEGIN_ALLOW_THREADS
+ %CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;a0, &amp;a1, &amp;a2, &amp;a3);
+ %END_ALLOW_THREADS
+ %PYARG_0 = PyTuple_New(4);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](a0));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](a1));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](a2));
+ PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](a3));
+ </template>
+ <template name="fix_native_return_int*,int*,int*,int*">
+ PyObject* _obj = %PYARG_0;
+ if (!PySequence_Check(_obj)
+ || PySequence_Fast_GET_SIZE(_obj) != 4
+ || !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 0))
+ || !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 1))
+ || !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 2))
+ || !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 3))) {
+ PyErr_SetString(PyExc_TypeError, "Sequence of 4 numbers expected");
+ } else {
+ *%1 = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(_obj, 0));
+ *%2 = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(_obj, 1));
+ *%3 = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(_obj, 2));
+ *%4 = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(_obj, 3));
+ }
+ </template>
+ <modify-function signature="getMargins(int*,int*,int*,int*)const">
+ <modify-argument index="return" pyi-type="Tuple[int, int, int, int]">
+ <replace-type modified-type="PyObject" />
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_int*,int*,int*,int*"/>
+ </inject-code>
+ <inject-code class="native" position="end">
+ <insert-template name="fix_native_return_int*,int*,int*,int*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="callGetMargins(int*,int*,int*,int*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject" />
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_int*,int*,int*,int*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="recursionOnModifiedVirtual(Str)const">
+ <inject-code class="target" position="beginning">
+ %BEGIN_ALLOW_THREADS
+ // It's important for test purposes to use a constructor with parenthesis as argument.
+ %RETURN_TYPE %0 = %RETURN_TYPE(%CPPSELF.%FUNCTION_NAME(Str(%1)));
+ %END_ALLOW_THREADS
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </modify-function>
+ </value-type>
+ <value-type name="VirtualDaughter" />
+ <object-type name="VirtualDaughter2" />
+ <object-type name="VirtualFinalDaughter" />
+
+ <value-type name="VirtualDtor">
+ <modify-function signature="create()">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="PointerHolder">
+ <modify-function signature="PointerHolder(void*)" remove="all"/>
+ <add-function signature="PointerHolder(PyObject*)">
+ <inject-code class="target" position="beginning">
+ %0 = new %TYPE(%PYARG_1);
+ </inject-code>
+ </add-function>
+ <modify-function signature="pointer() const">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = reinterpret_cast&lt;PyObject*>(%CPPSELF.%FUNCTION_NAME());
+ if (!%PYARG_0)
+ %PYARG_0 = Py_None;
+ Py_INCREF(%PYARG_0);
+ </inject-code>
+ </modify-function>
+ </value-type>
+
+ <function signature="applyHomogeneousTransform(Point,double,double,double,double,double,double,double,double,double,bool*)">
+ <!--
+ Tests handling of the '%#' substitution for # > 9.
+ -->
+ <modify-function signature="applyHomogeneousTransform(Point,double,double,double,double,double,double,double,double,double,bool*)">
+ <modify-argument index="11">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ bool ok_;
+ %RETURN_TYPE retval_ =
+ %FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, &amp;ok_);
+ if (!ok_)
+ %PYARG_0 = Py_None;
+ else
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval_);
+ </inject-code>
+ </modify-function>
+ </function>
+
+ <!-- Tests add-function for nested template types -->
+ <add-function signature="sum2d(std::list&lt;std::list&lt;int&gt; &gt;)" return-type="int">
+ <inject-code class="target" position="beginning">
+ typedef std::list&lt;int&gt; Inner;
+ typedef std::list&lt;Inner&gt; Outer;
+
+ int result = 0;
+
+ Outer::const_iterator oiter, oend = %1.end();
+ for (oiter = %1.begin(); oiter != oend; ++oiter) {
+ const Inner&amp; inner = *oiter;
+ Inner::const_iterator iiter, iend = inner.end();
+ for (iiter = inner.begin(); iiter != iend; ++iiter)
+ result += *iiter;
+ }
+
+ %PYARG_0 = %CONVERTTOPYTHON[int](result);
+ </inject-code>
+ </add-function>
+
+ <!-- Tests add-function for nested template types -->
+ <add-function signature="sumproduct(std::list&lt;std::pair&lt;int, int&gt; &gt;)" return-type="int">
+ <inject-code class="target" position="beginning">
+ typedef std::pair&lt;int, int&gt; Pair;
+ typedef std::list&lt;Pair&gt; List;
+
+ int result = 0;
+
+ List::const_iterator iter, end = %1.end();
+ for (iter = %1.begin(); iter != end; ++iter)
+ result += iter->first * iter->second;
+
+ %PYARG_0 = %CONVERTTOPYTHON[int](result);
+ </inject-code>
+ </add-function>
+
+
+ <value-type name="InjectCode">
+ <!--
+ Various tests for inject codes.
+ Note: Some uses of inject code here are used just for testing purposes, consider using the add-function tag.
+ -->
+
+ <modify-function signature="sumArrayAndLength(int *) const">
+ <modify-argument index="1">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ int* array = NULL;
+ bool errorOccurred = false;
+
+ if (PySequence_Check(%PYARG_1)) {
+ if((array = Shiboken::sequenceToIntArray(%PYARG_1, true)) == NULL &amp;&amp; PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "Should be a sequence of ints");
+ errorOccurred = true;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "Should be a sequence of ints");
+ errorOccurred = true;
+ }
+
+ if (!errorOccurred) {
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(array);
+ if (array)
+ delete[] array;
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ }
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="arrayMethod(int, int*) const">
+ <modify-argument index="1">
+ <remove-argument/>
+ <conversion-rule class="native">
+ const auto %out = PySequence_Size(%PYARG_1);
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="2">
+ <replace-type modified-type="PySequence"/>
+ <conversion-rule class="native">
+ const auto numItems = PySequence_Size(%PYARG_1);
+ Shiboken::AutoArrayPointer&lt;int&gt; %out(numItems);
+ for (Py_ssize_t i = 0; i &lt; numItems; ++i) {
+ if (%CHECKTYPE[int](PySequence_Fast_GET_ITEM(%PYARG_1, i)))
+ %out[i] = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(%PYARG_1, i));
+ else if (%ISCONVERTIBLE[int](PySequence_Fast_GET_ITEM(%PYARG_1, i)))
+ %out[i] = -1;
+ else
+ %out[i] = -2;
+ }
+ </conversion-rule>
+ <conversion-rule class="target">
+ PyObject* %out = PyList_New(count);
+ for (int i = 0; i &lt; count; ++i)
+ PyList_SET_ITEM(%out, i, %CONVERTTOPYTHON[int](%in[i]));
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="callArrayMethod(int, int*) const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <replace-type modified-type="PySequence"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ int numItems = PySequence_Size(%PYARG_1);
+ int *cppItems = new int[numItems];
+ for (int i = 0; i &lt; numItems; i++)
+ cppItems[i] = %CONVERTTOCPP[int](PySequence_GetItem(%PYARG_1, i));
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(numItems, cppItems);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ delete[] cppItems;
+ </inject-code>
+ </modify-function>
+
+ <!--
+ Inject the tp_str method using this alternative way
+ Tested in InjectCodeTest.testTypeNativeBeginning_TypeTargetBeginning:
+ -->
+ <inject-code class="native" position="beginning">
+ PyObject* InjectCode_tpstr(PyObject*) { return Shiboken::String::fromCString("Hi! I'm the inject code dummy class."); }
+ </inject-code>
+ <!--
+ Register our tp_str class using another inject code
+ Tested in InjectCodeTest.testTypeNativeBeginning_TypeTargetBeginning:
+ -->
+ <inject-code class="target" position="beginning">
+ %PYTHONTYPEOBJECT.tp_str = InjectCode_tpstr;
+ </inject-code>
+
+ <!-- Tested in InjectCodeTest.testFunctionTargetBeginning_FunctionTargetEnd -->
+ <modify-function signature="simpleMethod1(int, int)">
+ <inject-code class="target" position="beginning">
+ %1 += 1;
+ </inject-code>
+ <inject-code class="target" position="end">
+ PyObject* tmp = Shiboken::String::fromCString("end");
+ Shiboken::String::concat(&amp;%PYARG_0, tmp);
+ Py_DECREF(tmp);
+ </inject-code>
+ </modify-function>
+
+ <!-- Tested in InjectCodeTest.testFunctionTargetBeginning -->
+ <modify-function signature="simpleMethod2()">
+ <inject-code class="target" position="end">
+ PyObject* tmp = Shiboken::String::fromCString("end");
+ Shiboken::String::concat(&amp;%PYARG_0, tmp);
+ Py_DECREF(tmp);
+ </inject-code>
+ </modify-function>
+
+ <!-- Tested in InjectCodeTest.testArgsModification -->
+ <modify-function signature="overloadedMethod(int, char**)">
+ <modify-argument index="1">
+ <replace-type modified-type="PySequence" />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ int argc;
+ char** argv;
+ if (!Shiboken::listToArgcArgv(%PYARG_1, &amp;argc, &amp;argv)) {
+ PyErr_SetString(PyExc_TypeError, "error");
+ return 0;
+ }
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(argc, argv);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ for (int i = 0; i &lt; argc; ++i)
+ free(argv[i]);
+ delete[] argv;
+ </inject-code>
+ </modify-function>
+
+ <!-- Tested in InjectCodeTest.testArgsModification2 -->
+ <modify-function signature="simpleMethod3(int, char**)">
+ <modify-argument index="1">
+ <replace-type modified-type="PySequence" />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ int argc;
+ char** argv;
+ if (!Shiboken::listToArgcArgv(%PYARG_1, &amp;argc, &amp;argv)) {
+ PyErr_SetString(PyExc_TypeError, "error");
+ return 0;
+ }
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(argc, argv);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ for (int i = 0; i &lt; argc; ++i)
+ free(argv[i]);
+ delete[] argv;
+ </inject-code>
+ </modify-function>
+ </value-type>
+
+ <value-type name="ImplicitBase"/>
+ <value-type name="SortedOverload">
+ <add-function signature="overload(PyObject *)" return-type="const char *">
+ <inject-code class="target" position="beginning">
+ return Shiboken::String::fromCString("PyObject");
+ </inject-code>
+ </add-function>
+
+ <add-function signature="overloadDeep(int, PyObject *)" return-type="const char *">
+ <inject-code class="target" position="beginning">
+ return Shiboken::String::fromCString("PyObject");
+ </inject-code>
+ </add-function>
+ <modify-function signature="pyObjOverload(unsigned char*, int)">
+ <modify-argument index="1">
+ <replace-type modified-type="PyObject" />
+ <conversion-rule class="native">
+ unsigned char* %out = 0;
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <value-type name="ImplicitTarget"/>
+
+ <object-type name="CustomOverloadSequence">
+ <modify-function signature="overload(int) const" overload-number="0"/>
+ <modify-function signature="overload(short) const" overload-number="1"/>
+ </object-type>
+
+ <value-type name="Point">
+ <add-function signature="__str__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ int x1 = (int) %CPPSELF.x();
+ int x2 = ((int) (%CPPSELF.x() * 100)) - (x1 * 100);
+ int y1 = (int) %CPPSELF.y();
+ int y2 = ((int) (%CPPSELF.y() * 100)) - (y1 * 100);
+ %PYARG_0 = Shiboken::String::fromFormat("Point(%d.%d, %d.%d)", x1, x2, y1, y2);
+ </inject-code>
+ </add-function>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ int x1 = (int) %CPPSELF.x();
+ int x2 = ((int) (%CPPSELF.x() * 10)) - (x1 * 10);
+ int y1 = (int) %CPPSELF.y();
+ int y2 = ((int) (%CPPSELF.y() * 10)) - (y1 * 10);
+ %PYARG_0 = Shiboken::String::fromFormat("&lt;Point object at %p: (%d.%d, %d.%d)&gt;", %CPPSELF, x1, x2, y1, y2);
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ PyObject* type = PyObject_Type(%PYSELF);
+ PyObject* args = NULL;
+
+ args = Py_BuildValue("(dd)", %CPPSELF.x(), %CPPSELF.y());
+
+ %PYARG_0 = Py_BuildValue("(OO)", type, args);
+ </inject-code>
+ </add-function>
+
+ <modify-function signature="midpoint(const Point&amp;, Point*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="Point" />
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ Point _midpoint;
+ // The test consists in *NOT* using the ARGUMENT_NAMES type system variable.
+ %CPPSELF.%FUNCTION_NAME(%1, &amp;_midpoint);
+ %PYARG_0 = %CONVERTTOPYTHON[Point](_midpoint);
+ </inject-code>
+ </modify-function>
+
+ <template name="return_self">
+ %PYARG_0 = %PYARG_1;
+ Py_INCREF(%PYARG_1);
+ </template>
+ <add-function signature="operator-(PyUnicode)">
+ <inject-code>
+ <insert-template name="return_self" />
+ </inject-code>
+ </add-function>
+ <!-- A reverse operator -->
+ <add-function signature="operator-(PyUnicode, Point)">
+ <inject-code>
+ <insert-template name="return_self" />
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="PointF">
+ <add-function signature="__str__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ int x1 = (int) %CPPSELF.x();
+ int x2 = ((int) (%CPPSELF.x() * 100)) - (x1 * 100);
+ int y1 = (int) %CPPSELF.y();
+ int y2 = ((int) (%CPPSELF.y() * 100)) - (y1 * 100);
+ %PYARG_0 = Shiboken::String::fromFormat("PointF(%d.%d, %d.%d)", x1, x2, y1, y2);
+ </inject-code>
+ </add-function>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ int x1 = (int) %CPPSELF.x();
+ int x2 = ((int) (%CPPSELF.x() * 10)) - (x1 * 10);
+ int y1 = (int) %CPPSELF.y();
+ int y2 = ((int) (%CPPSELF.y() * 10)) - (y1 * 10);
+ %PYARG_0 = Shiboken::String::fromFormat("&lt;PointF object at %p: (%d.%d, %d.%d)&gt;", %CPPSELF, x1, x2, y1, y2);
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ PyObject *type = PyObject_Type(%PYSELF);
+ PyObject *args = NULL;
+
+ args = Py_BuildValue("(dd)", %CPPSELF.x(), %CPPSELF.y());
+
+ %PYARG_0 = Py_BuildValue("(OO)", type, args);
+ </inject-code>
+ </add-function>
+
+ <modify-function signature="midpoint(const PointF&amp;, PointF*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PointF" />
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ PointF _midpoint;
+ // The test consists in using the ARGUMENT_NAMES type system variable.
+ %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;_midpoint);
+ %PYARG_0 = %CONVERTTOPYTHON[PointF](_midpoint);
+ </inject-code>
+ </modify-function>
+ </value-type>
+
+ <value-type name="Rect" />
+ <value-type name="RectF" />
+
+ <value-type name="Polygon">
+ <modify-function signature="stealOwnershipFromPython(Point*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="stealOwnershipFromPython(Polygon*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="Time">
+ <extra-includes>
+ <include file-name="datetime.h" location="global"/>
+ </extra-includes>
+ <enum-type name="NumArgs"/>
+ <add-function signature="operator!=(const PyObject*)" return-type="PyObject">
+ <inject-code>
+ if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+ if (PyTime_Check(%1)) {
+ int pyH = PyDateTime_TIME_GET_HOUR(%1);
+ int pyM = PyDateTime_TIME_GET_MINUTE(%1);
+ int pyS = PyDateTime_TIME_GET_SECOND(%1);
+ if ((pyH == %CPPSELF.hour()) &amp;&amp;
+ (pyM == %CPPSELF.minute()) &amp;&amp;
+ (pyS == %CPPSELF.second()))
+ %PYARG_0 = Py_False;
+ else
+ %PYARG_0 = Py_True;
+ Py_INCREF(%PYARG_0);
+ }
+ </inject-code>
+ </add-function>
+ <add-function signature="operator==(const PyObject*)" return-type="PyObject">
+ <inject-code>
+ if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+ if (PyTime_Check(%1)) {
+ int pyH = PyDateTime_TIME_GET_HOUR(%1);
+ int pyM = PyDateTime_TIME_GET_MINUTE(%1);
+ int pyS = PyDateTime_TIME_GET_SECOND(%1);
+ if ((pyH == %CPPSELF.hour()) &amp;&amp;
+ (pyM == %CPPSELF.minute()) &amp;&amp;
+ (pyS == %CPPSELF.second()))
+ %PYARG_0 = Py_True;
+ else
+ %PYARG_0 = Py_False;
+ Py_INCREF(%PYARG_0);
+ }
+ </inject-code>
+ </add-function>
+
+ </value-type>
+ <value-type name="Size">
+ <extra-includes>
+ <include file-name="string" location="global"/>
+ <include file-name="sstream" location="global"/>
+ </extra-includes>
+ <add-function signature="Size(const char*)">
+ <inject-code class="target" position="beginning"
+ file="samplesnippets.cpp" snippet="size_char_ct"/>
+ </add-function>
+ </value-type>
+ <value-type name="SizeF"/>
+ <function signature="SnakeCaseGlobalFunction()" snake-case="yes"/>
+ <object-type name="SnakeCaseTest" snake-case="yes">
+ <modify-function signature="testFunctionDisabled()const" snake-case="no"/>
+ <modify-function signature="testFunctionBoth()const" snake-case="both"/>
+ <modify-field name="testFieldDisabled" snake-case="no"/>
+ <modify-field name="testFieldBoth" snake-case="both"/>
+ </object-type>
+ <object-type name="SnakeCaseDerivedTest" snake-case="yes"/>
+ <value-type name="MapUser"/>
+ <value-type name="PairUser"/>
+ <value-type name="ListUser">
+ <enum-type name="ListOfSomething"/>
+ </value-type>
+ <value-type name="NoImplicitConversion" />
+ <value-type name="NonDefaultCtor" />
+ <value-type name="OddBoolUser" />
+ <object-type name="Overload">
+ <enum-type name="FunctionEnum"/>
+ <enum-type name="ParamEnum"/>
+ <modify-function signature="intOverloads(int, int, double)">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target">
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, 2, %3);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </modify-function>
+ <modify-function signature="singleOverload(Point*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="acceptSequence(const char*const[])">
+ <modify-argument index="1">
+ <replace-type modified-type="PySequence" />
+ <conversion-rule class="native">
+ {
+ Shiboken::AutoDecRef strList(PySequence_Fast(%PYARG_1, "The argument must be a sequence."));
+ int lineCount = PySequence_Fast_GET_SIZE(strList.object());
+ for (int line = 0; line &lt; lineCount; ++line) {
+ if (!Shiboken::String::check(PySequence_Fast_GET_ITEM(strList.object(), line))) {
+ PyErr_SetString(PyExc_TypeError, "The argument must be a sequence of strings.");
+ break;
+ }
+ }
+ }
+ // PySIDE-1735: Enums are now implemented in Python, so we need to avoid asserts.
+ if (PyErr_Occurred())
+ break;
+ const char** %out = 0;
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="acceptSequence(void*)">
+ <modify-argument index="1">
+ <replace-type modified-type="PyObject" />
+ <conversion-rule class="native">
+ void* %out = 0;
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+
+ <template name="buffer_argument">
+ unsigned char* %out = (unsigned char*) Shiboken::Buffer::getPointer(%PYARG_1);
+ </template>
+
+ <modify-function signature="strBufferOverloads(unsigned char*,int)">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ <conversion-rule class="native">
+ <insert-template name="buffer_argument" />
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ <!--
+ This added function simulates the solution given to PySide's QImage
+ constructor problem, as seen in PySide/bbba1cc4, and described in
+ bug #489 [http://bugs.pyside.org/show_bug.cgi?id=489].
+ This is not the best solution, just one that works. The proper way
+ to handle it would be to fix the overload decisor.
+ -->
+ <add-function signature="strBufferOverloads(Str&amp;,int)" return-type="Overload::FunctionEnum">
+ <inject-code class="target" position="beginning">
+ <insert-template name="buffer_argument">
+ <replace from="%out" to="argOut" />
+ </insert-template>
+ %BEGIN_ALLOW_THREADS
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(argOut, %2);
+ %END_ALLOW_THREADS
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="Overload2" />
+
+ <object-type name="Collector" stream="yes"/>
+
+ <value-type name="IntWrapper">
+ <inject-code class="native" position="beginning"
+ file="samplesnippets.cpp" snippet="intwrapper_add_ints"/>
+ <add-pymethoddef name="add_ints" function="Sbk_IntWrapper_add_ints"
+ flags="METH_VARARGS"/>
+ </value-type>
+
+ <value-type name="Str" hash-function="strHash">
+ <add-function signature="__str__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = Shiboken::String::fromCString(%CPPSELF.cstring());
+ </inject-code>
+ </add-function>
+ <add-function signature="__len__" >
+ <inject-code class="target" position="end">
+ return %CPPSELF.size();
+ </inject-code>
+ </add-function>
+ <add-function signature="__getitem__" >
+ <inject-code class="target" position="beginning">
+ if (_i &lt; 0 || _i >= %CPPSELF.size()) {
+ PyErr_BadArgument();
+ return 0;
+ } else {
+ char res[2];
+ res[0] = %CPPSELF.get_char(_i);
+ res[1] = 0;
+ return Shiboken::String::fromCString(res);
+ }
+ </inject-code>
+ </add-function>
+ <add-function signature="__setitem__" >
+ <inject-code class="target" position="beginning">
+ PyObject* args = Py_BuildValue("(iO)", _i, _value);
+ PyObject* result = Sbk_StrFunc_set_char(self, args);
+ Py_DECREF(args);
+ int ok = result == Py_True;
+ if (result) {
+ Py_DECREF(result);
+ }
+ return !ok ? -1 : 0;
+ </inject-code>
+ </add-function>
+ <modify-function signature="toInt(bool*, int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="boolptr_at_start_and_one_arg_fix_beginning"/>
+ </inject-code>
+ <inject-code class="target" position="end">
+ <insert-template name="boolptr_fix_end"/>
+ </inject-code>
+ </modify-function>
+ </value-type>
+
+ <value-type name="ByteArray" hash-function="ByteArray::hash">
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion type="Py_None">
+ SBK_UNUSED(%in)
+ %out = %OUTTYPE();
+ </add-conversion>
+ <add-conversion type="PyObject" check="Shiboken::String::check(%in) || PyBytes_Check(%in)">
+ Py_ssize_t len;
+ const char* str = Shiboken::String::toCString(%in, &amp;len);
+ %out = %OUTTYPE(str, len);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+
+ <modify-function signature="ByteArray(const char*,int)" remove="all" />
+ <modify-function signature="ByteArray(const char*)" remove="all" >
+ <!-- Keep \x00 bytes passed in Python strings. -->
+ <modify-argument index="1">
+ <replace-type modified-type="PyBytes"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ PyObject* data = 0;
+ if (PyUnicode_CheckExact(%PYARG_1)) {
+ data = PyUnicode_AsASCIIString(%PYARG_1);
+ } else {
+ data = %PYARG_1;
+ Py_INCREF(data);
+ }
+
+ %0 = new %TYPE(PyBytes_AsString(data), PyBytes_GET_SIZE(data));
+ Py_DECREF(data);
+ </inject-code>
+ </modify-function>
+
+ <!-- buffer protocol -->
+ <inject-code class="target" position="end">
+ </inject-code>
+
+ <modify-function signature="data() const">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = PyBytes_FromStringAndSize(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size());
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="hash(const ByteArray&amp;)" remove="all" />
+ <!-- Functions removed to proper deal with strings containing zeroes -->
+ <modify-function signature="append(const char*)" remove="all" />
+ <modify-function signature="append(const char*,int)" remove="all" />
+ <modify-function signature="operator==(const char*,ByteArray)" remove="all" />
+ <modify-function signature="operator==(ByteArray,const char*)" remove="all" />
+ <modify-function signature="operator!=(const char*,ByteArray)" remove="all" />
+ <modify-function signature="operator!=(ByteArray,const char*)" remove="all" />
+ <modify-function signature="operator+(ByteArray,const char*)" remove="all" />
+ <modify-function signature="operator+(const char*,ByteArray)" remove="all" />
+ <modify-function signature="operator+=(const char*)" remove="all" />
+ <modify-function signature="operator[](int)const" remove="all"/>
+
+ <add-function signature="operator+(PyUnicode)" return-type="ByteArray">
+ <inject-code>
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ if (!data.isNull()) {
+ ByteArray ba(*%CPPSELF);
+ ba.append(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ %PYARG_0 = %CONVERTTOPYTHON[ByteArray](ba);
+ }
+ </inject-code>
+ </add-function>
+ <add-function signature="operator+(PyUnicode,ByteArray)" return-type="ByteArray">
+ <inject-code>
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ if (!data.isNull()) {
+ ByteArray ba(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ ba.append(*%CPPSELF);
+ %PYARG_0 = %CONVERTTOPYTHON[ByteArray](ba);
+ }
+ </inject-code>
+ </add-function>
+ <add-function signature="operator+(PyBytes,ByteArray)">
+ <inject-code>
+ ByteArray ba(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
+ ba = ba + *%CPPSELF;
+ %PYARG_0 = %CONVERTTOPYTHON[ByteArray](ba);
+ </inject-code>
+ </add-function>
+ <add-function signature="operator+(PyBytes)">
+ <inject-code>
+ ByteArray ba(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
+ ba.append(*%CPPSELF);
+ %PYARG_0 = %CONVERTTOPYTHON[ByteArray](ba);
+ </inject-code>
+ </add-function>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ ByteArray b(Py_TYPE(%PYSELF)->tp_name);
+ PyObject* aux = Shiboken::String::fromStringAndSize(%CPPSELF.data(), %CPPSELF.size());
+ if (PyUnicode_CheckExact(aux)) {
+ PyObject* tmp = PyUnicode_AsASCIIString(aux);
+ Py_DECREF(aux);
+ aux = tmp;
+ }
+ b += "('";
+ b += ByteArray(PyBytes_AS_STRING(aux), PyBytes_GET_SIZE(aux));
+ b += "')";
+ %PYARG_0 = Shiboken::String::fromStringAndSize(b.data(), b.size());
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__str__" return-type="str">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = Shiboken::String::fromStringAndSize(%CPPSELF.data(), %CPPSELF.size());
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__len__">
+ <inject-code class="target" position="beginning">
+ return %CPPSELF.size();
+ </inject-code>
+ </add-function>
+ <add-function signature="__getitem__">
+ <inject-code class="target" position="beginning">
+ if (_i &lt; 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+ } else {
+ char res[2];
+ res[0] = %CPPSELF.at(_i);
+ res[1] = 0;
+ return PyBytes_FromStringAndSize(res, 1);
+ }
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="StrList">
+ <enum-type name="CtorEnum"/>
+ <add-function signature="__len__" >
+ <inject-code class="target" position="end">
+ return %CPPSELF.size();
+ </inject-code>
+ </add-function>
+ <add-function signature="__getitem__" >
+ <inject-code class="target" position="beginning">
+ if (_i &lt; 0 || _i >= static_cast&lt;Py_ssize_t>(%CPPSELF.size())) {
+ PyErr_BadArgument();
+ return 0;
+ } else {
+ %TYPE::const_iterator it = %CPPSELF.begin();
+ for (Py_ssize_t i = 1; i &lt;= _i; i++)
+ ++it;
+ return %CONVERTTOPYTHON[Str](*it);
+ }
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <object-type name="SimpleFile">
+ <modify-function signature="open()">
+ <modify-argument index="return">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="simplefile_glue.cpp"/>
+ </modify-function>
+ </object-type>
+
+ <value-type name="VoidHolder" />
+
+ <object-type name="PrivateCtor" />
+ <object-type name="PrivateDtor" />
+ <value-type name="DeletedDefaultCtor"/>
+
+ <object-type name="Base1"/>
+ <object-type name="Base2"/>
+ <object-type name="Base3"/>
+ <object-type name="Base4"/>
+ <object-type name="Base5"/>
+ <object-type name="Base6"/>
+ <object-type name="MDerived1"/>
+ <object-type name="MDerived2"/>
+ <object-type name="MDerived3"/>
+ <object-type name="MDerived4"/>
+ <object-type name="MDerived5"/>
+ <object-type name="SonOfMDerived1"/>
+
+ <object-type name="Bucket" private="true">
+ <modify-function signature="lock()" allow-thread="yes" />
+ <modify-function signature="virtualBlockerMethod()" allow-thread="yes"/>
+ <modify-function signature="callVirtualBlockerMethodButYouDontKnowThis()" allow-thread="yes"/>
+ </object-type>
+
+ <value-type name="Echo">
+ <add-function signature="echo(const char *)" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = Shiboken::String::fromCString(%1);
+ </inject-code>
+ </add-function>
+ <add-function signature="operator>(int)">
+ <inject-code>
+ // This should test if code injections works inside rich comparison operators
+ Py_INCREF(Py_True);
+ %PYARG_0 = Py_True;
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="Color" />
+ <value-type name="Brush" operator-bool="true">
+ <enum-type name="Style"/>
+ </value-type>
+ <value-type name="Pen">
+ <enum-type identified-by-value="EnumCtor"/>
+ <enum-type name="RenderHints"/>
+ <property type="RenderHints" name="renderHints" get="getRenderHints" set="setRenderHints"/>
+ </value-type>
+
+ <value-type name="CtorConvRule" private="true">
+ <modify-function signature="CtorConvRule(long)">
+ <modify-argument index="1">
+ <!--<replace-type modified-type="long"/>-->
+ <conversion-rule class="native">
+ // Does nothing really, just test the code generation
+ // of constructors whose arguments where
+ long %out = PyLong_AS_LONG(%PYARG_1) + 1;
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <add-function signature="multiplyString(str, unsigned int)" return-type="const char*">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = Shiboken::String::fromCString("");
+ for (unsigned int i = 0; i &lt; %2; ++i)
+ Shiboken::String::concat(&amp;%PYARG_0, %PYARG_1);
+ </inject-code>
+ </add-function>
+
+ <add-function signature="countVarargs(int, ...)" return-type="int">
+ <inject-code class="target" position="beginning">
+ %RETURN_TYPE %0 = PyTuple_GET_SIZE(%PYARG_2);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+
+ <value-type name="SbkDate">
+ <extra-includes>
+ <include file-name="datetime.h" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning">
+ static bool PyDate_ImportAndCheck(PyObject* pyIn) {
+ if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+ return PyDate_Check(pyIn);
+ }
+ </inject-code>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion type="PyDate" check="PyDate_ImportAndCheck(%in)">
+ int day = PyDateTime_GET_DAY(%in);
+ int month = PyDateTime_GET_MONTH(%in);
+ int year = PyDateTime_GET_YEAR(%in);
+ %out = %OUTTYPE(day, month, year);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ <add-function signature="toPython()" return-type="PyDate">
+ <inject-code class="target">
+ if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+ %PYARG_0 = PyDate_FromDate(%CPPSELF.day(), %CPPSELF.month(), %CPPSELF.year());
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <object-type name="HandleHolder" />
+ <value-type name="PrimitiveStructPointerHolder" />
+
+ <object-type name="ObjectTypeOperators">
+ <add-function signature="operator!=(std::string)" return-type="bool">
+ <inject-code class="target">
+ %RETURN_TYPE %0 = %CPPSELF.key() != %1;
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+ </object-type>
+
+ <value-type name="Filter" />
+ <value-type name="Data">
+ <enum-type name="Field" />
+ <add-function signature="operator&amp;(const Union&amp;)" return-type="Intersection">
+ <inject-code class="target">
+ %RETURN_TYPE %0 = *%CPPSELF &amp; %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+ </value-type>
+ <value-type name="Union">
+ <add-function signature="operator&amp;(const Data&amp;)" return-type="Intersection">
+ <inject-code class="target">
+ %RETURN_TYPE %0 = *%CPPSELF &amp; %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ </inject-code>
+ </add-function>
+ </value-type>
+ <value-type name="Intersection" />
+
+ <!-- type used in abstract method -->
+ <object-type name="HideType" generate="no" />
+
+ <value-type name="Expression" />
+
+ <object-type name="ExceptionTest" exception-handling="auto-on">
+ <modify-function signature="create(bool)">
+ <modify-argument index="return">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ // Test comment
+ </inject-code>
+ </modify-function>
+ </object-type>
+
+ <value-type name="ModelIndex" />
+ <value-type name="ReferentModelIndex">
+ <modify-function signature="operator const ModelIndex&amp;()const">
+ <modify-argument index="return">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <value-type name="PersistentModelIndex" />
+
+ <!-- test rejections using full signatures; this method is a template and
+ cannot be wrapped, but is otherwise recognized by shiboken and will
+ result in a compile error if the rejection is not matched -->
+ <rejection class="Photon::Base" function-name="isType()"/>
+
+ <value-type name="ValueAndVirtual" />
+
+ <object-type name="ObjectTypeByValue" />
+
+ <value-type name="StdComplex">
+ <extra-includes>
+ <include file-name="cmath" location="global"/>
+ </extra-includes>
+ <!-- PYSIDE-2446: number protocols without a Py_nb_ constant. -->
+ <add-function signature="__floor__()" return-type="double">
+ <inject-code class="target" position="end"
+ file="samplesnippets.cpp" snippet="stdcomplex_floor"/>
+ </add-function>
+ <add-function signature="__ceil__()" return-type="double">
+ <inject-code class="target" position="end"
+ file="samplesnippets.cpp" snippet="stdcomplex_ceil"/>
+ </add-function>
+ <!-- PYSIDE-2446: number protocols with Py_nb_ constants. -->
+ <add-function signature="__abs__()" return-type="double">
+ <inject-code class="target" position="end"
+ file="samplesnippets.cpp" snippet="stdcomplex_abs"/>
+ </add-function>
+ <add-function signature="__pow__(StdComplex@exp@)" return-type="StdComplex">
+ <inject-code class="target" position="end"
+ file="samplesnippets.cpp" snippet="stdcomplex_pow"/>
+ </add-function>
+
+ </value-type>
+
+ <object-type name="TemplatePtr">
+ <modify-function signature="dummy(std::list&lt;std::pair&lt;BlackBox *, BlackBox *&gt; &gt; &amp;)" rename="dummy_method" />
+ </object-type>
+
+ <value-type name="ToBeRenamedValue" target-lang-name="RenamedValue"/>
+ <value-type name="RenamedUser"/>
+
+ <enum-type name="LengthUnit"/>
+ <value-type name="ValueWithUnit" generate="no"/>
+ <typedef-type name="ValueWithUnitDoubleInch" source="ValueWithUnit&lt;double,LengthUnit::Inch&gt;"/>
+ <typedef-type name="ValueWithUnitDoubleMillimeter" source="ValueWithUnit&lt;double,LengthUnit::Millimeter&gt;"/>
+ <value-type name="ValueWithUnitUser"/>
+
+ <suppress-warning text="horribly broken type '__off64_t'" />
+ <suppress-warning text="enum '__codecvt_result' does not have a type entry or is not an enum" />
+ <suppress-warning text="Pure virtual method 'Abstract::hideFunction(HideType*)' must be implemented but was completely removed on type system." />
+ <suppress-warning text="Shadowing: MDerived2::castToBase3() and MDerived3::castToBase3()" />
+ <suppress-warning text="Visibility of function 'publicMethod' modified in class 'MDerived1'" />
+
+ <suppress-warning text="^skipping public function 'std::enable_if.*ComparisonTester::operator[!=]=.*ComparisonTester.*$"/>
+</typesystem>
diff --git a/sources/shiboken6/tests/samplebinding/typesystypedef_test.py b/sources/shiboken6/tests/samplebinding/typesystypedef_test.py
new file mode 100644
index 000000000..f7f5342ee
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/typesystypedef_test.py
@@ -0,0 +1,29 @@
+#!/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 sample import ValueWithUnitUser, ValueWithUnitDoubleInch
+
+
+class TypeSysTypeDefTest(unittest.TestCase):
+ '''Test case type system typedefs.'''
+
+ def test(self):
+ inch_value = ValueWithUnitDoubleInch(10)
+ mm_value = ValueWithUnitUser.doubleInchToMillimeter(inch_value)
+ self.assertEqual(int(mm_value.value()), 2540)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/unsafe_parent_test.py b/sources/shiboken6/tests/samplebinding/unsafe_parent_test.py
new file mode 100644
index 000000000..2a7e5cac7
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/unsafe_parent_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 cases for ...'''
+
+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 ObjectType
+
+
+class DerivedObjectType(ObjectType):
+ def isPython(self):
+ return True
+
+ def createChild(self, parent):
+ return DerivedObjectType(parent)
+
+
+class ParentTest(unittest.TestCase):
+
+ def testUunsafeParent(self):
+ o = DerivedObjectType()
+ o.callVirtualCreateChild()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/useraddedctor_test.py b/sources/shiboken6/tests/samplebinding/useraddedctor_test.py
new file mode 100644
index 000000000..45d4095b6
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/useraddedctor_test.py
@@ -0,0 +1,26 @@
+#!/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 user added constructors'''
+
+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 Size
+
+
+class PointTest(unittest.TestCase):
+ def testUsingSelfOnCtor(self):
+ # This is a user added ctor and no errors should happen!
+ s = Size("3x2")
+ self.assertEqual(s.height(), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/virtualdtor_test.py b/sources/shiboken6/tests/samplebinding/virtualdtor_test.py
new file mode 100644
index 000000000..6be870269
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/virtualdtor_test.py
@@ -0,0 +1,63 @@
+#!/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 virtual destructor.'''
+
+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 VirtualDtor
+
+
+class ExtendedVirtualDtor(VirtualDtor):
+ def __init__(self):
+ VirtualDtor.__init__(self)
+
+
+class VirtualDtorTest(unittest.TestCase):
+ '''Test case for virtual destructor.'''
+
+ def setUp(self):
+ VirtualDtor.resetDtorCounter()
+
+ def testVirtualDtor(self):
+ '''Original virtual destructor is being called.'''
+ dtor_called = VirtualDtor.dtorCalled()
+ for i in range(1, 10):
+ vd = VirtualDtor()
+ del vd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(VirtualDtor.dtorCalled(), dtor_called + i)
+
+ def testVirtualDtorOnCppCreatedObject(self):
+ '''Original virtual destructor is being called for a C++ created object.'''
+ dtor_called = VirtualDtor.dtorCalled()
+ for i in range(1, 10):
+ vd = VirtualDtor.create()
+ del vd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(VirtualDtor.dtorCalled(), dtor_called + i)
+
+ def testDtorOnDerivedClass(self):
+ '''Original virtual destructor is being called for a derived class.'''
+ dtor_called = ExtendedVirtualDtor.dtorCalled()
+ for i in range(1, 10):
+ evd = ExtendedVirtualDtor()
+ del evd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(ExtendedVirtualDtor.dtorCalled(), dtor_called + i)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/virtualmethods_test.py b/sources/shiboken6/tests/samplebinding/virtualmethods_test.py
new file mode 100644
index 000000000..52dc66c90
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/virtualmethods_test.py
@@ -0,0 +1,130 @@
+#!/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 virtual methods.'''
+
+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 Point, Str, StrList, VirtualDaughter, VirtualMethods
+
+import warnings
+
+
+class ExtendedVirtualMethods(VirtualMethods):
+ def __init__(self):
+ VirtualMethods.__init__(self)
+ self.virtual_method0_called = False
+
+ def virtualMethod0(self, pt, val, cpx, b):
+ self.virtual_method0_called = True
+ return VirtualMethods.virtualMethod0(self, pt, val, cpx, b) * -1.0
+
+ def strListToStdList(self, arg):
+ warnings.simplefilter('error')
+ # returning wrong type for test purposes.
+ return True
+
+ def recursionOnModifiedVirtual(self, arg):
+ # check if recursion is caused by injected code that calls C++.
+ return VirtualMethods.recursionOnModifiedVirtual(self, arg) + 10
+
+
+class ExtendedVirtualDaughter(VirtualDaughter):
+ def __init__(self, name):
+ VirtualDaughter.__init__(self, name)
+ self.grand_daughter_name_called = False
+
+ def name(self):
+ self.grand_daughter_name_called = True
+ return VirtualDaughter.name(self).prepend('Extended')
+
+
+class ExtendedExtendedVirtualDaughter(ExtendedVirtualDaughter):
+ def __init__(self, name):
+ ExtendedVirtualDaughter.__init__(self, name)
+ self.grand_grand_daughter_name_called = False
+
+ def name(self):
+ self.grand_grand_daughter_name_called = True
+ return ExtendedVirtualDaughter.name(self).prepend('Extended')
+
+
+class VirtualMethodsTest(unittest.TestCase):
+ '''Test case for virtual methods'''
+
+ def setUp(self):
+ self.prefix_from_codeinjection = Str('Pimped')
+
+ def tearDown(self):
+ del self.prefix_from_codeinjection
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testReimplementedVirtualMethod0(self):
+ '''Test Python override of a virtual method with various different parameters
+ is correctly called from C++.'''
+ vm = VirtualMethods()
+ evm = ExtendedVirtualMethods()
+ pt = Point(1.1, 2.2)
+ val = 4
+ cpx = complex(3.3, 4.4)
+ b = True
+ result0 = vm.callVirtualMethod0(pt, val, cpx, b)
+ result1 = evm.callVirtualMethod0(pt, val, cpx, b)
+ self.assertEqual(result0 * -1.0, result1)
+
+ def testRecursionOnModifiedVirtual(self):
+ evm = ExtendedVirtualMethods()
+ self.assertEqual(evm.recursionOnModifiedVirtual(''), 10)
+ self.assertEqual(evm.callRecursionOnModifiedVirtual(''), 10)
+
+ def testReimplementedVirtualMethodInheritedFromGrandParent(self):
+ '''Test Python override of a virtual method inherited from a grand parent.'''
+ original_name = 'Foo'
+ evd = ExtendedVirtualDaughter(original_name)
+
+ self.assertEqual(VirtualDaughter.name(evd), original_name)
+ self.assertEqual(VirtualMethods.name(evd), original_name)
+ self.assertFalse(evd.grand_daughter_name_called)
+
+ name = evd.callName()
+ self.assertTrue(evd.grand_daughter_name_called)
+ self.assertEqual(evd.name().prepend(self.prefix_from_codeinjection), name)
+
+ def testReimplementedVirtualMethodInheritedFromGrandGrandParent(self):
+ '''Test Python override of a virtual method inherited from a grand grand parent.'''
+ original_name = 'Foo'
+ eevd = ExtendedExtendedVirtualDaughter(original_name)
+
+ self.assertEqual(VirtualDaughter.name(eevd), original_name)
+ self.assertEqual(VirtualMethods.name(eevd), original_name)
+ self.assertFalse(eevd.grand_daughter_name_called)
+ self.assertFalse(eevd.grand_grand_daughter_name_called)
+
+ name = eevd.callName()
+ self.assertTrue(eevd.grand_daughter_name_called)
+ self.assertTrue(eevd.grand_grand_daughter_name_called)
+ self.assertEqual(eevd.name().prepend(self.prefix_from_codeinjection), name)
+
+ def testStringView(self):
+ virtual_methods = VirtualMethods()
+ self.assertEqual(virtual_methods.stringViewLength('bla'), 3)
+
+
+class PrettyErrorMessageTest(unittest.TestCase):
+ def testIt(self):
+ obj = ExtendedVirtualMethods()
+ self.assertRaises(RuntimeWarning, obj.callStrListToStdList, StrList())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/visibilitychange_test.py b/sources/shiboken6/tests/samplebinding/visibilitychange_test.py
new file mode 100644
index 000000000..becdf7423
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/visibilitychange_test.py
@@ -0,0 +1,27 @@
+#!/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 Base1, MDerived1
+
+
+class VisibilityChangeTest(unittest.TestCase):
+
+ def testVisibilityChange(self):
+ b1 = Base1()
+ b1.publicMethod() # ok...
+ d1 = MDerived1()
+ self.assertRaises(TypeError, d1.publicMethod)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/voidholder_test.py b/sources/shiboken6/tests/samplebinding/voidholder_test.py
new file mode 100644
index 000000000..186cb473e
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/voidholder_test.py
@@ -0,0 +1,50 @@
+#!/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 sample import VoidHolder, Point
+from shiboken6 import Shiboken
+
+
+class VoidHolderTest(unittest.TestCase):
+ '''Test case for void pointer manipulation.'''
+
+ def testGetVoidPointerFromCppAndPutsOnVoidHolder(self):
+ '''Passes a void pointer created in C++ to be kept by VoidHolder.'''
+ voidptr = VoidHolder.gimmeMeSomeVoidPointer()
+ voidholder = VoidHolder(voidptr)
+ self.assertEqual(voidptr, voidholder.voidPointer())
+
+ def testPassVoidPointerAsArgument(self):
+ '''Passes a void pointer created in C++ as an argument to a function.'''
+ voidptr = VoidHolder.gimmeMeSomeVoidPointer()
+ voidHolder = VoidHolder()
+ returnValue = voidHolder.takeVoidPointer(voidptr)
+ self.assertEqual(returnValue, voidptr)
+
+ def testPutRandomObjectInsideVoidHolder(self):
+ '''Passes a C++ pointer for an object created in Python to be kept by VoidHolder.'''
+ obj = Point(1, 2)
+ voidholder = VoidHolder(obj)
+ self.assertEqual(Shiboken.getCppPointer(obj)[0], int(voidholder.voidPointer()))
+
+ def testGetNoneObjectFromVoidHolder(self):
+ '''A VoidHolder created without parameters returns a NULL pointer
+ that should be converted to a Python None.'''
+ voidholder = VoidHolder()
+ self.assertEqual(voidholder.voidPointer(), None)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/weakref_test.py b/sources/shiboken6/tests/samplebinding/weakref_test.py
new file mode 100644
index 000000000..01c6d58d5
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/weakref_test.py
@@ -0,0 +1,50 @@
+#!/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 weakref support'''
+
+import gc
+import os
+import sys
+import unittest
+import weakref
+
+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 ObjectType, PrivateDtor
+
+
+class WeakrefBasicTest(unittest.TestCase):
+ '''Simple test case of using a weakref'''
+
+ def setUp(self):
+ self.called = False
+
+ def cb(self, *args):
+ self.called = True
+
+ def testBasic(self):
+ '''ObjectType weakref'''
+ obj = ObjectType()
+ ref = weakref.ref(obj, self.cb) # noqa: F841
+ del obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self.called)
+
+ def testPrivateDtor(self):
+ '''PrivateDtor weakref'''
+ obj = PrivateDtor.instance()
+ ref = weakref.ref(obj, self.cb) # noqa: F841
+ del obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/writableclassdict_test.py b/sources/shiboken6/tests/samplebinding/writableclassdict_test.py
new file mode 100644
index 000000000..dfc962db9
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/writableclassdict_test.py
@@ -0,0 +1,37 @@
+#!/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 Point
+
+
+class ExtPoint(Point):
+ pass
+
+
+class TestWritableClassDict(unittest.TestCase):
+ def testSetattrOnClass(self):
+ setattr(Point, 'foo', 123)
+ self.assertEqual(Point.foo, 123)
+ pt = Point()
+ self.assertEqual(pt.foo, 123)
+
+ def testSetattrOnInheritingClass(self):
+ setattr(Point, 'bar', 321)
+ self.assertEqual(Point.bar, 321)
+ self.assertEqual(ExtPoint.bar, 321)
+ pt = ExtPoint()
+ self.assertEqual(pt.bar, 321)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/shiboken_paths.py b/sources/shiboken6/tests/shiboken_paths.py
new file mode 100644
index 000000000..3ec940f2e
--- /dev/null
+++ b/sources/shiboken6/tests/shiboken_paths.py
@@ -0,0 +1,109 @@
+# 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
+
+
+def get_dir_env_var(var_name):
+ """Return a directory set by an environment variable"""
+ result = os.environ.get(var_name)
+ if not result:
+ raise ValueError(f'{var_name} is not set!')
+ if not Path(result).is_dir():
+ raise ValueError(f'{result} is not a directory!')
+ return result
+
+
+def get_build_dir():
+ """
+ Return the env var `BUILD_DIR`.
+ If not set (interactive mode), take the last build history entry.
+ """
+ try:
+ return get_dir_env_var('BUILD_DIR')
+ except ValueError:
+ look_for = Path("testing")
+ here = Path(__file__).resolve().parent
+ while here / look_for not in here.iterdir():
+ import pprint
+ parent = here.parent
+ if parent == here:
+ raise SystemError(look_for + " not found!")
+ here = parent
+ try:
+ sys.path.insert(0, os.fspath(here))
+ from testing.buildlog import builds
+ if not builds.history:
+ raise
+ return builds.history[-1].build_dir
+ finally:
+ del sys.path[0]
+
+
+def _prepend_path_var(var_name, paths):
+ """Prepend additional paths to a path environment variable
+ like PATH, LD_LIBRARY_PATH"""
+ old_paths = os.environ.get(var_name)
+ new_paths = os.pathsep.join(paths)
+ if old_paths:
+ new_paths += f'{os.pathsep}{old_paths}'
+ os.environ[var_name] = new_paths
+
+
+def add_python_dirs(python_dirs):
+ """Add directories to the Python path unless present.
+ Care is taken that the added directories come before
+ site-packages."""
+ new_paths = []
+ for python_dir in python_dirs:
+ new_paths.append(python_dir)
+ if python_dir in sys.path:
+ sys.path.remove(python_dir)
+ sys.path[:0] = new_paths
+
+
+def add_lib_dirs(lib_dirs):
+ """Add directories to the platform's library path."""
+ if sys.platform == 'win32':
+ if sys.version_info >= (3, 8, 0):
+ for lib_dir in lib_dirs:
+ os.add_dll_directory(lib_dir)
+ else:
+ _prepend_path_var('PATH', lib_dirs)
+ else:
+ _prepend_path_var('LD_LIBRARY_PATH', lib_dirs)
+
+
+def shiboken_paths(include_shiboken_tests=False):
+ """Return a tuple of python directories/lib directories to be set for
+ using the shiboken6 module from the build directory or running the
+ shiboken tests depending on a single environment variable BUILD_DIR
+ pointing to the build directory."""
+ src_dir = Path(__file__).resolve().parent
+ python_dirs = []
+ if include_shiboken_tests:
+ python_dirs.append(os.fspath(src_dir)) # For shiboken_test_helper
+ python_dirs.append(get_build_dir()) # for toplevel shiboken6 import
+ shiboken_dir = Path(get_build_dir()) / 'shiboken6'
+ lib_dirs = [os.fspath(shiboken_dir / 'libshiboken')]
+ if include_shiboken_tests:
+ shiboken_test_dir = shiboken_dir /'tests'
+ for module in ['minimal', 'sample', 'smart', 'other']:
+ module_dir = shiboken_test_dir / f"{module}binding"
+ python_dirs.append(os.fspath(module_dir))
+ lib_dir = shiboken_test_dir / f"lib{module}"
+ lib_dirs.append(os.fspath(lib_dir))
+ return (python_dirs, lib_dirs)
+
+
+def init_paths():
+ """Sets the correct import paths (Python modules and C++ library
+ paths) for testing shiboken depending on a single
+ environment variable BUILD_DIR pointing to the build
+ directory."""
+ paths = shiboken_paths(True)
+ add_python_dirs(paths[0])
+ add_lib_dirs(paths[1])
diff --git a/sources/shiboken6/tests/shiboken_test_helper.py b/sources/shiboken6/tests/shiboken_test_helper.py
new file mode 100644
index 000000000..14fe6a2d1
--- /dev/null
+++ b/sources/shiboken6/tests/shiboken_test_helper.py
@@ -0,0 +1,13 @@
+#!/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
+
+
+def objectFullname(t):
+ # '__qualname__' for Python 2 does exist for PySide types, only.
+ name = getattr(t, "__qualname__", t.__name__)
+ module = t.__module__
+ if module is None or module == str.__class__.__module__:
+ return name
+ else:
+ return module + '.' + name
diff --git a/sources/shiboken6/tests/shibokenmodule/module_test.py b/sources/shiboken6/tests/shibokenmodule/module_test.py
new file mode 100644
index 000000000..9f9f8f5a4
--- /dev/null
+++ b/sources/shiboken6/tests/shibokenmodule/module_test.py
@@ -0,0 +1,112 @@
+# 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 # noqa: E402
+init_paths()
+
+from shiboken6 import Shiboken # noqa: E402
+from sample import BlackBox, ObjectType, ObjectModel, ObjectView, Point # noqa: E402
+
+
+class MultipleInherited (ObjectType, Point):
+ def __init__(self):
+ ObjectType.__init__(self)
+ Point.__init__(self)
+
+
+class TestShiboken(unittest.TestCase):
+ def testIsValid(self):
+ self.assertTrue(Shiboken.isValid(object()))
+ self.assertTrue(Shiboken.isValid(None))
+
+ bb = BlackBox()
+ item = ObjectType()
+ ticket = bb.keepObjectType(item)
+ bb.disposeObjectType(ticket)
+ self.assertFalse(Shiboken.isValid(item))
+
+ def testWrapInstance(self):
+ addr = ObjectType.createObjectType()
+ obj = Shiboken.wrapInstance(addr, ObjectType)
+ self.assertFalse(Shiboken.createdByPython(obj))
+ obj.setObjectName("obj")
+ self.assertEqual(obj.objectName(), "obj")
+ self.assertEqual(addr, obj.identifier())
+ self.assertFalse(Shiboken.createdByPython(obj))
+
+ # avoid mem leak =]
+ bb = BlackBox()
+ self.assertTrue(Shiboken.createdByPython(bb))
+ bb.disposeObjectType(bb.keepObjectType(obj))
+
+ def testWrapInstancePreserveId(self):
+ """PYSIDE-31: Verify that wrapInstance() returns the existing wrapper
+ even if a base class type is specified."""
+ v = ObjectView() # inherits ObjectType
+ addresses = Shiboken.getCppPointer(v)
+ self.assertTrue(addresses)
+ address = addresses[0]
+ wrapped = Shiboken.wrapInstance(address, ObjectType)
+ self.assertEqual(id(wrapped), id(v))
+
+ def testIsOwnedByPython(self):
+ obj = ObjectType()
+ self.assertTrue(Shiboken.ownedByPython(obj))
+ p = ObjectType()
+ obj.setParent(p)
+ self.assertFalse(Shiboken.ownedByPython(obj))
+
+ def testDump(self):
+ """Just check if dump doesn't crash on certain use cases"""
+ p = ObjectType()
+ obj = ObjectType(p)
+ obj2 = ObjectType(obj)
+ obj3 = ObjectType(obj) # noqa: F841
+ self.assertEqual(Shiboken.dump(None), "Ordinary Python type.")
+ Shiboken.dump(obj)
+
+ model = ObjectModel(p)
+ v = ObjectView(model, p)
+ Shiboken.dump(v)
+
+ m = MultipleInherited()
+ Shiboken.dump(m)
+ self.assertEqual(len(Shiboken.getCppPointer(m)), 2)
+
+ # Don't crash even after deleting an object
+ Shiboken.invalidate(obj)
+ Shiboken.dump(obj) # deleted
+ Shiboken.dump(p) # child deleted
+ Shiboken.dump(obj2) # parent deleted
+
+ def testDelete(self):
+ obj = ObjectType()
+ child = ObjectType(obj)
+ self.assertTrue(Shiboken.isValid(obj))
+ self.assertTrue(Shiboken.isValid(child))
+ # Note: this test doesn't assure that the object dtor was really called
+ Shiboken.delete(obj)
+ self.assertFalse(Shiboken.isValid(obj))
+ self.assertFalse(Shiboken.isValid(child))
+
+ def testVersionAttr(self):
+ self.assertEqual(type(Shiboken.__version__), str)
+ self.assertTrue(len(Shiboken.__version__) >= 5)
+ self.assertEqual(type(Shiboken.__version_info__), tuple)
+ self.assertEqual(len(Shiboken.__version_info__), 5)
+
+ def testAllWrappers(self):
+ obj = ObjectType()
+ self.assertTrue(obj in Shiboken.getAllValidWrappers())
+ Shiboken.delete(obj)
+ self.assertFalse(obj in Shiboken.getAllValidWrappers())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/CMakeLists.txt b/sources/shiboken6/tests/smartbinding/CMakeLists.txt
new file mode 100644
index 000000000..594744840
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(smart)
+
+set(smart_TYPESYSTEM
+${CMAKE_CURRENT_SOURCE_DIR}/typesystem_smart.xml
+)
+
+set(smart_SRC
+${CMAKE_CURRENT_BINARY_DIR}/smart/smart_module_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/obj_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/integer_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/sharedptr_obj_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/sharedptr_integer_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/registry_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/smart_integer2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/sharedptr_integer2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stdsharedptrtestbench_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stdsharedptrvirtualmethodtester_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_double_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_integer_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_int_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_std_string_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_optional_int_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_optional_integer_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_integer_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_integer2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_int_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stdoptionaltestbench_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stduniqueptrtestbench_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stduniqueptrvirtualmethodtester_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/test_wrapper.cpp
+)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/smart-binding.txt.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt" @ONLY)
+
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${smart_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --project-file=${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt
+ ${GENERATOR_EXTRA_FLAGS}
+ DEPENDS ${smart_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for 'smart' test binding..."
+)
+
+add_library(smart MODULE ${smart_SRC})
+target_include_directories(smart PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(smart PUBLIC libsmart libshiboken)
+set_property(TARGET smart PROPERTY PREFIX "")
+set_property(TARGET smart PROPERTY OUTPUT_NAME "smart${PYTHON_EXTENSION_SUFFIX}")
+
+if(WIN32)
+ set_property(TARGET smart PROPERTY SUFFIX ".pyd")
+endif()
+
+create_generator_target(smart)
diff --git a/sources/shiboken6/tests/smartbinding/global.h b/sources/shiboken6/tests/smartbinding/global.h
new file mode 100644
index 000000000..5bec15063
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/global.h
@@ -0,0 +1,4 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "smart.h"
diff --git a/sources/shiboken6/tests/smartbinding/smart-binding.txt.in b/sources/shiboken6/tests/smartbinding/smart-binding.txt.in
new file mode 100644
index 000000000..a2c73c6bf
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/smart-binding.txt.in
@@ -0,0 +1,16 @@
+[generator-project]
+
+generator-set = shiboken
+
+header-file = @CMAKE_CURRENT_SOURCE_DIR@/global.h
+typesystem-file = @smart_TYPESYSTEM@
+
+output-directory = @CMAKE_CURRENT_BINARY_DIR@
+
+include-path = @libsmart_SOURCE_DIR@
+
+typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@
+
+enable-parent-ctor-heuristic
+use-isnull-as-nb_nonzero
+lean-headers
diff --git a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
new file mode 100644
index 000000000..8d4272558
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
@@ -0,0 +1,302 @@
+#!/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 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 copy import copy
+from smart import (Obj, Registry, Integer, SharedPtr_Integer, std)
+
+
+def objCount():
+ return Registry.getInstance().countObjects()
+
+
+def integerCount():
+ return Registry.getInstance().countIntegers()
+
+
+def integerFromValue(v):
+ result = Integer()
+ result.setValue(v)
+ return result
+
+
+class SmartPointerTests(unittest.TestCase):
+
+ def setUp(self):
+ super().setUp()
+ if os.environ.get("VERBOSE"):
+ Registry.getInstance().setVerbose(True)
+
+ def testObjSmartPointer(self):
+ # Create Obj.
+ o = Obj()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 1)
+
+ # Create a shared pointer to an Obj together with an Obj.
+ ptrToObj = o.createSharedPtrObj()
+ self.assertEqual(objCount(), 2)
+
+ # Delete the old Obj.
+ o = None
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 1)
+
+ # Get a wrapper to the Obj inside of the shared pointer, object count
+ # should not change.
+ obj = ptrToObj.data()
+ self.assertEqual(objCount(), 1)
+ obj.m_integer = 50
+ self.assertEqual(obj.m_integer, 50)
+
+ # Set and get a member value via shared pointer (like operator->).
+ ptrToObj.m_integer = 100
+ self.assertEqual(ptrToObj.m_integer, 100)
+
+ # Get inner PyObject via shared pointer (like operator->) and set
+ # value in it.
+ ptrToObj.m_internalInteger.m_int = 200
+ self.assertEqual(ptrToObj.m_internalInteger.m_int, 200)
+
+ # Pass smart pointer as argument to a method, return value is the value
+ # of m_integer of passed Obj inside the smart pointer.
+ result = ptrToObj.takeSharedPtrToObj(ptrToObj)
+ self.assertEqual(result, 100)
+
+ # Pass an Integer as an argument that returns itself.
+ result = ptrToObj.takeInteger(ptrToObj.m_internalInteger)
+ self.assertEqual(integerCount(), 2)
+ result = None
+ if integerCount() > 1:
+ gc.collect()
+ print('Running garbage collector for reference test',
+ file=sys.stderr)
+ self.assertEqual(integerCount(), 1)
+
+ # Make a copy of the shared pointer, object count should not change.
+ ptrToObj2 = copy(ptrToObj)
+ self.assertEqual(objCount(), 1)
+
+ # Delete the first shared pointer, object count should not change
+ # because the second one still has a reference.
+ del ptrToObj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 1)
+
+ # Delete the second smart pointer, object should be deleted.
+ del ptrToObj2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 0)
+ self.assertEqual(integerCount(), 0)
+
+ def testIntegerSmartPointer(self):
+ # Create Obj.
+ o = Obj()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 1)
+
+ # Create a shared pointer to an Integer together with an Integer.
+ ptrToInteger = o.createSharedPtrInteger()
+ self.assertEqual(objCount(), 1)
+ self.assertEqual(integerCount(), 2)
+
+ # Get a wrapper to the Integer inside of the shared pointer, integer
+ # count should not change.
+ integer = ptrToInteger.data()
+ self.assertEqual(integerCount(), 2)
+ integer.m_int = 50
+ self.assertEqual(integer.m_int, 50)
+
+ # Set and get a member value via shared pointer (like operator->).
+ ptrToInteger.setValue(150)
+ self.assertEqual(ptrToInteger.value(), 150)
+
+ # Set and get a member field via shared pointer (like operator->).
+ ptrToInteger.m_int = 100
+ self.assertEqual(ptrToInteger.m_int, 100)
+
+ # Pass smart pointer as argument to a method, return value is the
+ # value of m_int of passed Integer inside the smart pointer.
+ result = o.takeSharedPtrToInteger(ptrToInteger)
+ self.assertEqual(result, 100)
+
+ # Make a copy of the shared pointer, integer count should not change.
+ ptrToInteger2 = copy(ptrToInteger)
+ self.assertEqual(integerCount(), 2)
+
+ # Delete the first shared pointer, integer count should not change
+ # because the second one still has a reference.
+ del ptrToInteger
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(integerCount(), 2)
+
+ # Delete the second smart pointer, integer should be deleted.
+ del ptrToInteger2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 1)
+ self.assertEqual(integerCount(), 1)
+
+ # Delete the original object which was used to create the integer.
+ del o
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 0)
+ self.assertEqual(integerCount(), 0)
+
+ def testConstIntegerSmartPointer(self):
+ # Create Obj.
+ o = Obj()
+ ptrToConstInteger = o.createSharedPtrConstInteger()
+ self.assertEqual(ptrToConstInteger.m_int, 456)
+ result = o.takeSharedPtrToConstInteger(ptrToConstInteger)
+ self.assertEqual(result, 456)
+ self.assertEqual(ptrToConstInteger.value(), 456)
+
+ def testSmartPointersWithNamespace(self):
+ # Create the main object
+ o = Obj()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 1)
+
+ # Create a shared pointer to an Integer together with an Integer.
+ ptrToInteger = o.createSharedPtrInteger2()
+ self.assertEqual(objCount(), 1)
+ self.assertEqual(integerCount(), 2)
+
+ integer = ptrToInteger.data()
+ self.assertTrue(integer)
+
+ def testListOfSmartPointers(self):
+ # Create the main object
+ o = Obj()
+
+ # Create a list of shared objects
+ ptrToObjList = o.createSharedPtrObjList(10)
+ self.assertEqual(len(ptrToObjList), 10)
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 11)
+
+ # Remove one from the list
+ ptrToObjList.pop()
+ self.assertEqual(len(ptrToObjList), 9)
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
+ self.assertEqual(objCount(), 10)
+
+ # clear and delete all objects in the list
+ del ptrToObjList[:] # Python 2.7 lists have no clear method
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(len(ptrToObjList), 0)
+ self.assertEqual(objCount(), 1)
+
+ def testInvalidParameter(self):
+ # Create Obj.
+ o = Obj()
+ # Create a shared pointer to an Obj together with an Obj.
+ ptrToObj = o.createSharedPtrObj()
+ try:
+ ptrToObj.typo
+ self.assertFail()
+ except AttributeError as error:
+ self.assertEqual(error.args[0], "'smart.SharedPtr_Obj' object has no attribute 'typo'")
+
+ def testSmartPointerConversions(self):
+ # Create Obj.
+ o = Obj()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(objCount(), 1)
+ self.assertEqual(integerCount(), 1)
+
+ # Create a shared pointer to an Integer2
+ integer2 = o.createSharedPtrInteger2()
+ # User defined name
+ self.assertEqual(type(integer2).__name__, "SmartInteger2Ptr")
+ self.assertTrue("smart.Test.SmartInteger2Ptr" in repr(type(integer2)))
+ self.assertEqual(integer2.value(), 456)
+
+ # pass Smart<Integer2> to a function that accepts Smart<Integer>
+ r = o.takeSharedPtrToInteger(integer2)
+ self.assertEqual(r, integer2.value())
+
+ def testSmartPointerValueComparison(self):
+ """Test a pointee class with comparison operators."""
+ four = Obj.createSharedPtrInteger(4)
+ four2 = Obj.createSharedPtrInteger(4)
+ five = Obj.createSharedPtrInteger(5)
+ self.assertTrue(four == four)
+ self.assertTrue(four == four2)
+ self.assertFalse(four != four)
+ self.assertFalse(four != four2)
+ self.assertFalse(four < four)
+ self.assertTrue(four <= four)
+ self.assertFalse(four > four)
+ self.assertTrue(four >= four)
+ self.assertFalse(four == five)
+ self.assertTrue(four != five)
+ self.assertTrue(four < five)
+ self.assertTrue(four <= five)
+ self.assertFalse(four > five)
+ self.assertFalse(four >= five)
+ self.assertTrue(five > four)
+
+ self.assertRaises(NotImplementedError,
+ lambda: Obj.createNullSharedPtrInteger() == four)
+
+ def testSmartPointerObjectComparison(self):
+ """Test a pointee class without comparison operators."""
+ o1 = Obj.createSharedPtrObj()
+ o2 = Obj.createSharedPtrObj()
+ self.assertTrue(o1 == o1)
+ self.assertFalse(o1 != o1)
+ self.assertFalse(o1 == o2)
+ self.assertTrue(o1 != o2)
+
+ def testOperatorNbBool(self):
+ null_ptr = Obj.createNullSharedPtrInteger()
+ self.assertFalse(null_ptr)
+ zero = Obj.createSharedPtrInteger(0)
+ self.assertTrue(zero)
+
+ def testParameterNone(self):
+ o = Obj()
+ null_ptr = Obj.createNullSharedPtrInteger()
+ o.takeSharedPtrToInteger(null_ptr)
+ o.takeSharedPtrToIntegerByConstRef(null_ptr)
+ o.takeSharedPtrToInteger(None)
+ o.takeSharedPtrToIntegerByConstRef(None)
+
+ def testConstruction(self):
+ p1 = SharedPtr_Integer(integerFromValue(42))
+ self.assertEqual(p1.value(), 42)
+
+ p2 = std.shared_ptr_Integer(integerFromValue(42))
+ self.assertEqual(p2.value(), 42)
+ p2.reset(integerFromValue(43))
+ self.assertEqual(p2.value(), 43)
+ gc.collect()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/smartbinding.pyproject b/sources/shiboken6/tests/smartbinding/smartbinding.pyproject
new file mode 100644
index 000000000..d0855ef82
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/smartbinding.pyproject
@@ -0,0 +1,7 @@
+{
+ "files": ["smart_pointer_test.py",
+ "std_optional_test.py",
+ "std_shared_ptr_test.py",
+ "std_unique_ptr_test.py",
+ "typesystem_smart.xml"]
+}
diff --git a/sources/shiboken6/tests/smartbinding/std_optional_test.py b/sources/shiboken6/tests/smartbinding/std_optional_test.py
new file mode 100644
index 000000000..bee573548
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/std_optional_test.py
@@ -0,0 +1,69 @@
+#!/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 smart import Integer, StdOptionalTestBench, std
+
+
+def call_func_on_optional(o):
+ o.printInteger()
+
+
+def integer_from_value(v):
+ result = Integer()
+ result.setValue(v)
+ return result
+
+
+class StdOptionalTests(unittest.TestCase):
+
+ def testCInt(self):
+ b = StdOptionalTestBench()
+ ci = b.optionalInt()
+ self.assertFalse(ci.has_value())
+ b.setOptionalIntValue(42)
+ ci = b.optionalInt()
+ self.assertTrue(ci.has_value())
+ self.assertEqual(ci.value(), 42)
+ b.setOptionalInt(ci)
+ ci = b.optionalInt()
+ self.assertTrue(ci.has_value())
+ self.assertEqual(ci.value(), 42)
+
+ ci = std.optional_int(43)
+ self.assertEqual(ci.value(), 43)
+
+ def testInteger(self):
+ b = StdOptionalTestBench()
+ i = b.optionalInteger()
+ self.assertFalse(i.has_value())
+ self.assertFalse(i)
+ # Must not throw a C++ exception
+ self.assertRaises(AttributeError, call_func_on_optional, i)
+
+ b.setOptionalIntegerValue(integer_from_value(42))
+ i = b.optionalInteger()
+ self.assertTrue(i.has_value())
+ self.assertEqual(i.value().value(), 42)
+ i.printInteger()
+ print(i)
+ b.setOptionalInteger(i)
+ i = b.optionalInteger()
+ self.assertTrue(i.has_value())
+ self.assertEqual(i.value().value(), 42)
+ call_func_on_optional(i)
+
+ i = std.optional_Integer(integer_from_value(43))
+ self.assertEqual(i.value().value(), 43)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py b/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py
new file mode 100644
index 000000000..a37a307a5
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py
@@ -0,0 +1,87 @@
+#!/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 smart import Integer, StdDoublePtr, StdSharedPtrTestBench, StdSharedPtrVirtualMethodTester, std
+
+
+def call_func_on_ptr(ptr):
+ ptr.printInteger()
+
+
+class VirtualTester(StdSharedPtrVirtualMethodTester):
+
+ def doModifyInteger(self, p):
+ p.setValue(p.value() * 2)
+ return p
+
+
+class StdSharedPtrTests(unittest.TestCase):
+ def testInteger(self):
+ p = StdSharedPtrTestBench.createInteger()
+ # PYSIDE-2462: Ensure Integer's __dir__ entries in the pointer's
+ self.assertTrue("printInteger" in dir(p))
+ StdSharedPtrTestBench.printInteger(p)
+ self.assertTrue(p)
+ call_func_on_ptr(p)
+
+ np = StdSharedPtrTestBench.createNullInteger()
+ StdSharedPtrTestBench.printInteger(np)
+ self.assertFalse(np)
+ self.assertRaises(AttributeError, call_func_on_ptr, np)
+
+ iv = Integer()
+ iv.setValue(42)
+ np = std.shared_ptr_Integer(iv)
+ self.assertEqual(np.value(), 42)
+
+ def testInt(self):
+ np = StdSharedPtrTestBench.createNullInt()
+ StdSharedPtrTestBench.printInt(np)
+ self.assertFalse(np)
+ p = StdSharedPtrTestBench.createInt()
+ StdSharedPtrTestBench.printInt(p)
+ ip = std.StdIntPtr(42)
+ StdSharedPtrTestBench.printInt(ip)
+
+ def testDouble(self):
+ np = StdSharedPtrTestBench.createNullDouble()
+ StdSharedPtrTestBench.printDouble(np)
+ self.assertFalse(np)
+ p = StdSharedPtrTestBench.createDouble(67)
+ StdSharedPtrTestBench.printDouble(p)
+ dp = StdDoublePtr(42)
+ StdSharedPtrTestBench.printDouble(dp)
+
+ def testString(self):
+ np = StdSharedPtrTestBench.createNullString()
+ StdSharedPtrTestBench.printString(np)
+ self.assertFalse(np)
+ p = StdSharedPtrTestBench.createString("bla")
+ StdSharedPtrTestBench.printString(p)
+
+ def testVirtuals(self):
+ """Test whether code generating virtual function overrides is generated
+ correctly."""
+ p = StdSharedPtrTestBench.createInteger()
+ p.setValue(42)
+ v = StdSharedPtrVirtualMethodTester()
+ r = v.callModifyInteger(p) # Base implementation increments
+ self.assertEqual(r.value(), 43)
+
+ p.setValue(42)
+ v = VirtualTester()
+ r = v.callModifyInteger(p) # Derived implementation doubles
+ self.assertEqual(r.value(), 84)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py b/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py
new file mode 100644
index 000000000..9c7ef2f01
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py
@@ -0,0 +1,94 @@
+#!/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 smart import Integer, Integer2, StdUniquePtrTestBench, StdUniquePtrVirtualMethodTester, std
+
+
+def call_func_on_ptr(ptr):
+ ptr.printInteger()
+
+
+class VirtualTester(StdUniquePtrVirtualMethodTester):
+
+ def doCreateInteger(self, v):
+ iv = Integer() # Construct from pointee
+ iv.setValue(2 * v)
+ return std.unique_ptr_Integer(iv)
+
+ def doModifyIntegerByRef(self, p):
+ return 2 * p.value()
+
+ def doModifyIntegerByValue(self, p):
+ return 2 * p.value()
+
+
+class StdUniquePtrTests(unittest.TestCase):
+ def testInteger(self):
+ p = StdUniquePtrTestBench.createInteger()
+ StdUniquePtrTestBench.printInteger(p) # unique_ptr by ref
+ self.assertTrue(p)
+
+ call_func_on_ptr(p)
+ self.assertTrue(p)
+
+ StdUniquePtrTestBench.takeInteger(p) # unique_ptr by value, takes pointee
+ self.assertFalse(p)
+
+ np = StdUniquePtrTestBench.createNullInteger()
+ StdUniquePtrTestBench.printInteger(np)
+ self.assertFalse(np)
+ self.assertRaises(AttributeError, call_func_on_ptr, np)
+
+ iv = Integer() # Construct from pointee
+ iv.setValue(42)
+ np = std.unique_ptr_Integer(iv)
+ self.assertEqual(np.value(), 42)
+
+ def test_derived(self):
+ iv2 = Integer2() # Construct from pointee
+ iv2.setValue(42)
+ p = std.unique_ptr_Smart_Integer2(iv2)
+ self.assertEqual(p.value(), 42)
+ StdUniquePtrTestBench.printInteger2(p) # unique_ptr by ref
+ self.assertTrue(p)
+ StdUniquePtrTestBench.printInteger(p) # conversion
+ # FIXME: This fails, pointer is moved in value conversion
+ # self.assertTrue(p)
+
+ def testInt(self):
+ p = StdUniquePtrTestBench.createInt() # unique_ptr by ref
+ StdUniquePtrTestBench.printInt(p)
+ StdUniquePtrTestBench.takeInt(p) # unique_ptr by value, takes pointee
+ self.assertFalse(p)
+
+ np = StdUniquePtrTestBench.createNullInt()
+ StdUniquePtrTestBench.printInt(np)
+ self.assertFalse(np)
+
+ def testVirtuals(self):
+ """Test whether code generating virtual function overrides is generated
+ correctly."""
+ p = StdUniquePtrTestBench.createInteger()
+ p.setValue(42)
+ v = StdUniquePtrVirtualMethodTester()
+ self.assertTrue(v.testCreateInteger(42, 42))
+ self.assertTrue(v.testModifyIntegerByRef(42, 43)) # Default implementation increments
+ self.assertTrue(v.testModifyIntegerValue(42, 43))
+
+ v = VirtualTester() # Reimplemented methods double values
+ self.assertTrue(v.testCreateInteger(42, 84))
+ self.assertTrue(v.testModifyIntegerByRef(42, 84))
+ self.assertTrue(v.testModifyIntegerValue(42, 84))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/typesystem_smart.xml b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
new file mode 100644
index 000000000..e479e4ddf
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<typesystem package="smart">
+ <rejection class="*" argument-type="^std::nullptr_t&amp;?$"/>
+
+ <template name="cpplist_to_pylist_convertion">
+ PyObject *%out = PyList_New(int(%in.size()));
+ int idx = 0;
+ for (const auto &amp;cppItem : %in)
+ PyList_SET_ITEM(%out, idx++, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
+ return %out;
+ </template>
+ <template name="pyseq_to_cpplist_convertion">
+ Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
+ for (int i = 0, size = PySequence_Fast_GET_SIZE(seq.object()); i &lt; size; ++i) {
+ PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), i);
+ %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
+ %out.push_back(cppItem);
+ }
+ </template>
+
+ <!-- Used in tests to check what C++ objects are allocated. -->
+ <object-type name="Registry" />
+
+ <!-- Current limitation: shared pointer python objects can only be instantiated from API usage,
+ like when they are returned as a result of a method, or passed as arguments. It is not
+ possible to explicitly instantiate a new shared pointer in python e.g. o = SharedPtr_Foo()
+ won't work.
+ -->
+ <smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount"
+ null-check-method="isNull"
+ instantiations="Integer,Smart::Integer2=Test::SmartInteger2Ptr,Obj"/>
+
+ <object-type name="Obj" />
+ <value-type name="Integer" />
+ <namespace-type name="Smart" generate="no">
+ <value-type name="Integer2" />
+ </namespace-type>
+ <!-- Just used to silence the warnings that shiboken doens't know what to do with this type -->
+ <custom-type name="RefData" />
+
+ <value-type name="StdOptionalTestBench"/>
+
+ <system-include file-name="memory"/>
+
+ <namespace-type name="std">
+ <include file-name="memory" location="global"/>
+ <modify-function signature="^.*$" remove="all"/>
+ <enum-type name="pointer_safety"/>
+ <smart-pointer-type name="shared_ptr" type="shared" getter="get"
+ value-check-method="operator bool"
+ ref-count-method="use_count"
+ reset-method="reset"
+ instantiations="Integer,int=StdIntPtr,double=::StdDoublePtr,std::string">
+ <include file-name="memory" location="global"/>
+ </smart-pointer-type>
+
+ <smart-pointer-type name="unique_ptr" type="unique" getter="get"
+ value-check-method="operator bool"
+ reset-method="reset"
+ instantiations="Integer,Smart::Integer2,int">
+ <include file-name="memory" location="global"/>
+ </smart-pointer-type>
+
+ <smart-pointer-type name="optional" type="value-handle" getter="value"
+ value-check-method="has_value"
+ instantiations="Integer,int">
+ <include file-name="optional" location="global"/>
+ </smart-pointer-type>
+
+ </namespace-type>
+ <object-type name="StdSharedPtrTestBench"/>
+ <object-type name="StdSharedPtrVirtualMethodTester"/>
+
+ <object-type name="StdUniquePtrTestBench"/>
+ <object-type name="StdUniquePtrVirtualMethodTester"/>
+
+ <namespace-type name="Test">
+ <enum-type name="DummyEnum"/>
+ </namespace-type>
+
+</typesystem>
diff --git a/sources/shiboken6/tests/test_generator/CMakeLists.txt b/sources/shiboken6/tests/test_generator/CMakeLists.txt
new file mode 100644
index 000000000..e1d078894
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+project(test_generator)
+
+set(dummy_generator_SRC dummygenerator.cpp)
+add_library(dummy_generator SHARED ${dummy_generator_SRC})
+target_link_libraries(dummy_generator ${APIEXTRACTOR_LIBRARY} ${QT_QTCORE_LIBRARY} genrunner)
+set_property(TARGET dummy_generator PROPERTY PREFIX "")
+
+add_executable(dummygenerator main.cpp)
+set(DUMMYGENERATOR_EXECUTABLE dummygenerator${generator_SUFFIX})
+set_target_properties(dummygenerator PROPERTIES OUTPUT_NAME ${DUMMYGENERATOR_EXECUTABLE})
+target_link_libraries(dummygenerator ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES})
+
+configure_file(dummygentestconfig.h.in "${CMAKE_CURRENT_BINARY_DIR}/dummygentestconfig.h" @ONLY)
+
+get_filename_component(APIEXTRACTOR_LIBRARY_DIRS ${APIEXTRACTOR_LIBRARY} PATH)
+if(WIN32)
+ set(PATH_SEP ";")
+ find_program(APIEXTRACTOR_BINARY apiextractor.dll HINTS ${APIEXTRACTOR_LIBRARY_DIRS})
+ get_filename_component(APIEXTRACTOR_BINARY_DIR ${APIEXTRACTOR_BINARY} PATH)
+ set(APIEXTRACTOR_LIBRARY_DIRS "${APIEXTRACTOR_LIBRARY_DIRS}${PATH_SEP}${APIEXTRACTOR_BINARY_DIR}")
+else()
+ set(PATH_SEP ":")
+endif()
+
+set(ENV_PATH "${generatorrunner_BINARY_DIR}${PATH_SEP}${CMAKE_CURRENT_BINARY_DIR}${PATH_SEP}$ENV{PATH}${PATH_SEP}${APIEXTRACTOR_LIBRARY_DIRS}")
+set(ENV_QT_PLUGIN_PATH "${CMAKE_CURRENT_BINARY_DIR}${PATH_SEP}$ENV{QT_PLUGIN_PATH}")
+if(WIN32)
+ string(REPLACE "\\;" ";" ENV_PATH "${ENV_PATH}")
+ string(REPLACE ";" "\\;" ENV_PATH "${ENV_PATH}")
+ string(REPLACE "\\;" ";" ENV_QT_PLUGIN_PATH "${ENV_QT_PLUGIN_PATH}")
+ string(REPLACE ";" "\\;" ENV_QT_PLUGIN_PATH "${ENV_QT_PLUGIN_PATH}")
+endif()
+
+macro(m_add_test testname)
+ add_test(${testname} ${testname})
+ set_property(TEST ${testname} PROPERTY ENVIRONMENT "PATH=${ENV_PATH}" "QT_PLUGIN_PATH=${ENV_QT_PLUGIN_PATH}")
+endmacro()
+
+macro(declare_test testname)
+ qt4_automoc("${testname}.cpp")
+ add_executable(${testname} "${testname}.cpp")
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+ target_link_libraries(${testname}
+ ${QT_QTTEST_LIBRARY}
+ ${QT_QTCORE_LIBRARY}
+ ${Qt${QT_MAJOR_VERSION}Test_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ )
+ m_add_test(${testname})
+endmacro(declare_test testname)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/test_global.h"
+ "${CMAKE_CURRENT_BINARY_DIR}/test_global.h" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/test_typesystem.xml"
+ "${CMAKE_CURRENT_BINARY_DIR}/test_typesystem.xml" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/dummygentest-project.txt.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/dummygentest-project.txt" @ONLY)
+declare_test(dummygentest)
+
+add_dependencies(dummygenerator generatorrunner)
+
diff --git a/sources/shiboken6/tests/test_generator/dummygenerator.cpp b/sources/shiboken6/tests/test_generator/dummygenerator.cpp
new file mode 100644
index 000000000..8a5079820
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/dummygenerator.cpp
@@ -0,0 +1,45 @@
+// 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 <iostream>
+#include "dummygenerator.h"
+
+EXPORT_GENERATOR_PLUGIN(new DummyGenerator)
+
+using namespace std;
+
+QString
+DummyGenerator::fileNameForClass(const AbstractMetaClass* metaClass) const
+{
+ return metaClass->name().toLower() + u"_generated.txt"_qs;
+}
+
+void
+DummyGenerator::generateClass(QTextStream& s, const AbstractMetaClass* metaClass)
+{
+ s << "// Generated code for class: " << qPrintable(metaClass->name()) << endl;
+}
+
+bool
+DummyGenerator::doSetup(const QMap<QString, QString>& args)
+{
+ if (args.contains("dump-arguments") && !args["dump-arguments"].isEmpty()) {
+ QFile logFile(args["dump-arguments"]);
+ logFile.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out(&logFile);
+ for (QMap<QString, QString>::const_iterator it = args.cbegin(), end = args.cend(); it != end; ++it) {
+ const QString& key = it.key();
+ if (key == "arg-1")
+ out << "header-file";
+ else if (key == "arg-2")
+ out << "typesystem-file";
+ else
+ out << key;
+ if (!args[key].isEmpty())
+ out << " = " << args[key];
+ out << endl;
+ }
+ }
+ return true;
+}
+
diff --git a/sources/shiboken6/tests/test_generator/dummygenerator.h b/sources/shiboken6/tests/test_generator/dummygenerator.h
new file mode 100644
index 000000000..d17206809
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/dummygenerator.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+#ifndef DUMMYGENERATOR_H
+#define DUMMYGENERATOR_H
+
+#include "generator.h"
+
+class GENRUNNER_API DummyGenerator : public Generator
+{
+public:
+ DummyGenerator() {}
+ ~DummyGenerator() {}
+ bool doSetup(const QMap<QString, QString>& args);
+ const char* name() const { return "DummyGenerator"; }
+
+protected:
+ void writeFunctionArguments(QTextStream&, const AbstractMetaFunction*, Options) const {}
+ void writeArgumentNames(QTextStream&, const AbstractMetaFunction*, Options) const {}
+ QString fileNameForClass(const AbstractMetaClass* metaClass) const;
+ void generateClass(QTextStream& s, const AbstractMetaClass* metaClass);
+ void finishGeneration() {}
+};
+
+#endif // DUMMYGENERATOR_H
diff --git a/sources/shiboken6/tests/test_generator/dummygentest-project.txt.in b/sources/shiboken6/tests/test_generator/dummygentest-project.txt.in
new file mode 100644
index 000000000..0a076d8bd
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/dummygentest-project.txt.in
@@ -0,0 +1,20 @@
+[generator-project]
+
+generator-set = dummy
+header-file = @CMAKE_CURRENT_BINARY_DIR@/test_global.h
+typesystem-file = @CMAKE_CURRENT_BINARY_DIR@/test_typesystem.xml
+output-directory = /tmp/output
+
+dump-arguments = @CMAKE_CURRENT_BINARY_DIR@/dummygen-args.log
+
+include-path = /include/path/location1
+include-path = /include/path/location2
+
+typesystem-path = /typesystem/path/location1
+typesystem-path = /typesystem/path/location2
+
+api-version = 1.2.3
+debug = sparse
+
+no-suppress-warnings
+
diff --git a/sources/shiboken6/tests/test_generator/dummygentest.cpp b/sources/shiboken6/tests/test_generator/dummygentest.cpp
new file mode 100644
index 000000000..d439e3d8c
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/dummygentest.cpp
@@ -0,0 +1,114 @@
+// 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 "dummygentest.h"
+#include "dummygenerator.h"
+#include "dummygentestconfig.h"
+
+#include <QtCore/QProcess>
+#include <QtCore/QTemporaryFile>
+#include <QtTest/QTest>
+
+#define GENERATED_CONTENTS "// Generated code for class: Dummy"
+
+void DummyGenTest::initTestCase()
+{
+ int argc = 0;
+ char* argv[] = {NULL};
+ QCoreApplication app(argc, argv);
+ workDir = QDir::currentPath();
+
+ headerFilePath = workDir + "/test_global.h";
+ typesystemFilePath = workDir + "/test_typesystem.xml";
+ projectFilePath = workDir + "/dummygentest-project.txt";
+ generatedFilePath = QDir::tempPath() + u"/dummy/dummy_generated.txt"_qs;
+}
+
+void DummyGenTest::testCallGenRunnerWithFullPathToDummyGenModule()
+{
+ QStringList args;
+ args.append("--generator-set=" DUMMYGENERATOR_BINARY_DIR "/dummy_generator" MODULE_EXTENSION);
+ args.append(u"--output-directory="_qs + QDir::tempPath());
+ args.append(headerFilePath);
+ args.append(typesystemFilePath);
+ int result = QProcess::execute("generatorrunner", args);
+ QCOMPARE(result, 0);
+
+ QFile generatedFile(generatedFilePath);
+ generatedFile.open(QIODevice::ReadOnly);
+ QCOMPARE(generatedFile.readAll().trimmed(), QByteArray(GENERATED_CONTENTS).trimmed());
+ generatedFile.close();
+
+ QVERIFY(generatedFile.remove());
+}
+
+void DummyGenTest::testCallGenRunnerWithNameOfDummyGenModule()
+{
+ QStringList args;
+ args.append("--generator-set=dummy");
+ args.append(u"--output-directory="_qs + QDir::tempPath());
+ args.append(headerFilePath);
+ args.append(typesystemFilePath);
+ int result = QProcess::execute("generatorrunner", args);
+ QCOMPARE(result, 0);
+
+ QFile generatedFile(generatedFilePath);
+ generatedFile.open(QIODevice::ReadOnly);
+ QCOMPARE(generatedFile.readAll().trimmed(), QByteArray(GENERATED_CONTENTS).trimmed());
+ generatedFile.close();
+
+ QVERIFY(generatedFile.remove());
+}
+
+void DummyGenTest::testCallDummyGeneratorExecutable()
+{
+ QStringList args;
+ args.append(u"--output-directory="_qs + QDir::tempPath());
+ args.append(headerFilePath);
+ args.append(typesystemFilePath);
+ int result = QProcess::execute(DUMMYGENERATOR_BINARY, args);
+ QCOMPARE(result, 0);
+
+ QFile generatedFile(generatedFilePath);
+ generatedFile.open(QIODevice::ReadOnly);
+ QCOMPARE(generatedFile.readAll().trimmed(), QByteArray(GENERATED_CONTENTS).trimmed());
+ generatedFile.close();
+
+ QVERIFY(generatedFile.remove());
+}
+
+void DummyGenTest::testProjectFileArgumentsReading()
+{
+ QStringList args(u"--project-file="_qs + workDir + u"/dummygentest-project.txt"_qs);
+ int result = QProcess::execute("generatorrunner", args);
+ QCOMPARE(result, 0);
+
+ QFile logFile(workDir + "/dummygen-args.log");
+ logFile.open(QIODevice::ReadOnly);
+ QStringList logContents;
+ while (!logFile.atEnd())
+ logContents << logFile.readLine().trimmed();
+ logContents.sort();
+ QCOMPARE(logContents[0], QString("api-version = 1.2.3"));
+ QCOMPARE(logContents[1], QString("debug = sparse"));
+ QVERIFY(logContents[2].startsWith("dump-arguments = "));
+ QVERIFY(logContents[2].endsWith("dummygen-args.log"));
+ QCOMPARE(logContents[3], QString("generator-set = dummy"));
+ QVERIFY(logContents[4].startsWith("header-file = "));
+ QVERIFY(logContents[4].endsWith("test_global.h"));
+ QCOMPARE(logContents[5],
+ QDir::toNativeSeparators(QString("include-paths = /include/path/location1%1/include/path/location2").arg(PATH_SPLITTER)));
+ QCOMPARE(logContents[6], QString("no-suppress-warnings"));
+ QCOMPARE(logContents[7], QString("output-directory = /tmp/output"));
+ QVERIFY(logContents[8].startsWith("project-file = "));
+ QVERIFY(logContents[8].endsWith("dummygentest-project.txt"));
+ QVERIFY(logContents[9].startsWith("typesystem-file = "));
+ QVERIFY(logContents[9].endsWith("test_typesystem.xml"));
+ QCOMPARE(logContents[10],
+ QDir::toNativeSeparators(QString("typesystem-paths = /typesystem/path/location1%1/typesystem/path/location2").arg(PATH_SPLITTER)));
+}
+
+QTEST_APPLESS_MAIN(DummyGenTest)
+
+#include "dummygentest.moc"
+
diff --git a/sources/shiboken6/tests/test_generator/dummygentest.h b/sources/shiboken6/tests/test_generator/dummygentest.h
new file mode 100644
index 000000000..1b1143b0a
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/dummygentest.h
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef DUMMYGENTABLETEST_H
+#define DUMMYGENTABLETEST_H
+
+#include <QObject>
+
+class DummyGenerator;
+
+class DummyGenTest : public QObject
+{
+ Q_OBJECT
+
+private:
+ QString workDir;
+ QString headerFilePath;
+ QString typesystemFilePath;
+ QString generatedFilePath;
+ QString projectFilePath;
+
+private slots:
+ void initTestCase();
+ void testCallGenRunnerWithFullPathToDummyGenModule();
+ void testCallGenRunnerWithNameOfDummyGenModule();
+ void testCallDummyGeneratorExecutable();
+ void testProjectFileArgumentsReading();
+};
+
+#endif
+
diff --git a/sources/shiboken6/tests/test_generator/dummygentestconfig.h.in b/sources/shiboken6/tests/test_generator/dummygentestconfig.h.in
new file mode 100644
index 000000000..9da17dcd3
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/dummygentestconfig.h.in
@@ -0,0 +1,15 @@
+#ifndef DUMMYGENTESTCONFIG_H
+#define DUMMYGENTESTCONFIG_H
+
+#define MODULE_EXTENSION "@CMAKE_SHARED_LIBRARY_SUFFIX@"
+#define DUMMYGENERATOR_BINARY "@DUMMYGENERATOR_EXECUTABLE@"
+#define DUMMYGENERATOR_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@"
+
+#ifdef _WINDOWS
+ #define PATH_SPLITTER ";"
+#else
+ #define PATH_SPLITTER ":"
+#endif
+
+#endif // DUMMYGENTESTCONFIG_H
+
diff --git a/sources/shiboken6/tests/test_generator/main.cpp b/sources/shiboken6/tests/test_generator/main.cpp
new file mode 100644
index 000000000..ba4440b2f
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/main.cpp
@@ -0,0 +1,14 @@
+// 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 <QtCore>
+
+int main(int argc, char *argv[])
+{
+ QStringList args;
+ args.append("--generator-set=dummy");
+ for (int i = 1; i < argc; i++)
+ args.append(argv[i]);
+ return QProcess::execute("generatorrunner", args);
+}
+
diff --git a/sources/shiboken6/tests/test_generator/run_test.cmake b/sources/shiboken6/tests/test_generator/run_test.cmake
new file mode 100644
index 000000000..37e40b993
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/run_test.cmake
@@ -0,0 +1,14 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# The tests are run through this script due to a limitation
+# on versions of CMake lesser than 2.8, that prevent setting
+# environment variables for tests from working.
+
+set(ENV{PATH} "${ENV_PATH}")
+set(ENV{QT_PLUGIN_PATH} "${ENV_QT_PLUGIN_PATH}")
+execute_process(COMMAND ${TEST} WORKING_DIRECTORY "${WORKDIR}" RESULT_VARIABLE OK)
+
+if(NOT OK EQUAL 0)
+ message(SEND_ERROR "${TEST} failed!")
+endif()
diff --git a/sources/shiboken6/tests/test_generator/test_global.h b/sources/shiboken6/tests/test_generator/test_global.h
new file mode 100644
index 000000000..6a95200cf
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/test_global.h
@@ -0,0 +1 @@
+struct Dummy {};
diff --git a/sources/shiboken6/tests/test_generator/test_typesystem.xml b/sources/shiboken6/tests/test_generator/test_typesystem.xml
new file mode 100644
index 000000000..c19a4e95e
--- /dev/null
+++ b/sources/shiboken6/tests/test_generator/test_typesystem.xml
@@ -0,0 +1,3 @@
+<typesystem package='dummy'>
+ <value-type name='Dummy'/>
+</typesystem>