offapi/org/libreoffice/embindtest/XTest.idl  |    1 
 pyuno/Module_pyuno.mk                        |    1 
 pyuno/PythonTest_pyuno_pytests_embindtest.mk |   16 
 pyuno/qa/pytests/embindtest.py               |  644 +++++++++++++++++++++++++++
 unotest/source/embindtest/embindtest.cxx     |  444 +++++++++---------
 5 files changed, 889 insertions(+), 217 deletions(-)

New commits:
commit 3320b5fe2e3c696f3e0f2e301c922d89108f5c12
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Mon Dec 8 15:44:56 2025 +0100
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Mon Dec 8 21:28:43 2025 +0100

    Add exhaustive testing of PyUNO type mapping based on embindtest
    
    ...in preparation for doing fixes for tdf#169229 "PyUNO: Hard to create 
null UNO
    interface references, to use in a method invocation" etc.  (Basing it on
    embindtest means it requires --enable-embindtest-uno, at least for now.)
    
    Various places in pyuno/qa/pytests/embindtest.py are marked with TODO 
comments.
    (Executing
    
    >         v = test.getAnyException()
    
    would cause an odd
    
    > Fatal Python error: _Py_CheckFunctionResult: a function returned a result 
with an exception set
    
    failure that needs further investigation.)
    
    To not only test calls from PyUNO to binary (C++) UNO, but also from binary
    (C++) UNO to PyUNO, add an executeTest method to the
    org.libreoffice.embindtest.XTest interface.  For now, it only does those 
tests
    that were already done by the org.libreoffice.embindtest.BridgeTest service
    implementation, but the plan is to extend those (e.g., don't just only test
    getAnyVoid, but all the getAny... variants).  And the corresponding Test 
class
    implementation in pyuno/qa/pytests/embindtest.py for now only defines those
    methods that are actually called, and will need to be extended as well.
    
    Change-Id: I0dd66b9aed14cc7e679da78b86d0dc657625fe94
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195238
    Reviewed-by: Stephan Bergmann <[email protected]>
    Tested-by: Jenkins

diff --git a/offapi/org/libreoffice/embindtest/XTest.idl 
b/offapi/org/libreoffice/embindtest/XTest.idl
index e579a606202a..27bdc660f939 100644
--- a/offapi/org/libreoffice/embindtest/XTest.idl
+++ b/offapi/org/libreoffice/embindtest/XTest.idl
@@ -134,6 +134,7 @@ interface XTest {
     boolean checkAttributes([in] org::libreoffice::embindtest::XAttributes 
object);
     [attribute] string StringAttribute;
     boolean testSolarMutex();
+    void executeTest([in] XTest test);
 };
 
 }; }; };
diff --git a/pyuno/Module_pyuno.mk b/pyuno/Module_pyuno.mk
index fc84a52ef89f..e3356bd985ac 100644
--- a/pyuno/Module_pyuno.mk
+++ b/pyuno/Module_pyuno.mk
@@ -53,6 +53,7 @@ endif # !SYSTEM_PYTHON
 $(eval $(call gb_Module_add_subsequentcheck_targets,pyuno, \
     PythonTest_pyuno_pytests_testcollections \
     PythonTest_pyuno_pytests_insertremovecells \
+    $(if $(ENABLE_EMBINDTEST_UNO),PythonTest_pyuno_pytests_embindtest) \
 ))
 
 endif # DISABLE_PYTHON
diff --git a/pyuno/PythonTest_pyuno_pytests_embindtest.mk 
b/pyuno/PythonTest_pyuno_pytests_embindtest.mk
new file mode 100644
index 000000000000..8f8341f7c50e
--- /dev/null
+++ b/pyuno/PythonTest_pyuno_pytests_embindtest.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 
100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_PythonTest_PythonTest,pyuno_pytests_embindtest))
+
+$(eval $(call 
gb_PythonTest_add_modules,pyuno_pytests_embindtest,$(SRCDIR)/pyuno/qa/pytests, \
+    embindtest \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/pyuno/qa/pytests/embindtest.py b/pyuno/qa/pytests/embindtest.py
new file mode 100644
index 000000000000..88d9fb6e98d5
--- /dev/null
+++ b/pyuno/qa/pytests/embindtest.py
@@ -0,0 +1,644 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+import org.libreoffice.unotest
+import unittest
+import uno
+import unohelper
+from com.sun.star.uno import RuntimeException
+from org.libreoffice.embindtest import Struct
+from org.libreoffice.embindtest import StructLong
+from org.libreoffice.embindtest import StructString
+from org.libreoffice.embindtest import XTest
+from org.libreoffice.embindtest.Enum import E3
+from org.libreoffice.embindtest.Enum import E_10
+from org.libreoffice.embindtest.Enum import E_2
+
+class Test(unohelper.Base, XTest):
+    def getBoolean(self):
+        return True
+
+    def isBoolean(self, value):
+        return value == True
+
+    def getByte(self):
+        return -12
+
+    def isByte(self, value):
+        return value == -12
+
+    def getShort(self):
+        return -1234
+
+    def isShort(self, value):
+        return value == -1234
+
+    def getUnsignedShort(self):
+        return 54321
+
+    def isUnsignedShort(self, value):
+        return value == 54321
+
+    def getLong(self):
+        return -123456
+
+    def isLong(self, value):
+        return value == -123456
+
+    def getUnsignedLong(self):
+        return 3456789012
+
+    def isUnsignedLong(self, value):
+        return value == 3456789012
+
+    def getHyper(self):
+        return -123456789
+
+    def isHyper(self, value):
+        return value == -123456789
+
+    def getUnsignedHyper(self):
+        return 9876543210
+
+    def isUnsignedHyper(self, value):
+        return value == 9876543210
+
+    def getFloat(self):
+        return -10.25
+
+    def isFloat(self, value):
+        return value == -10.25
+
+    def getDouble(self):
+        return 100.5
+
+    def isDouble(self, value):
+        return value == 100.5
+
+    def getChar(self):
+        return 'Ö'
+
+    def isChar(self, value):
+        return value == 'Ö'
+
+    def getString(self):
+        return 'hä'
+
+    def isString(self, value):
+        return value == 'hä'
+
+    def getType(self):
+        return uno.getTypeByName('long')
+
+    def isType(self, value):
+        return value == uno.getTypeByName('long')
+
+    def getAnyVoid(self):
+        return None
+
+    def isAnyVoid(self, value):
+        return value == None
+
+    def getEnum(self):
+        return E_2
+
+    def isEnum(self, value):
+        return value == E_2
+
+    def getStruct(self):
+        return Struct(
+            True, -12, -1234, 54321, -123456, 3456789012, -123456789, 
9876543210, -10.25, 100.5,
+            'Ö', 'hä', uno.getTypeByName('long'), -123456, ('foo', 'barr', 
'bazzz'), E_2,
+            StructLong(-123456),
+            uno.createUnoStruct(
+                
'org.libreoffice.embindtest.Template<any,org.libreoffice.embindtest.StructString>',
+                StructString('foo'), -123456, -123456, StructString('barr')),
+            self)
+
+    def isStruct(self, value):
+        return value == Struct(
+            True, -12, -1234, 54321, -123456, 3456789012, -123456789, 
9876543210, -10.25, 100.5,
+            'Ö', 'hä', uno.getTypeByName('long'), -123456, ('foo', 'barr', 
'bazzz'), E_2,
+            StructLong(-123456),
+            uno.createUnoStruct(
+                
'org.libreoffice.embindtest.Template<any,org.libreoffice.embindtest.StructString>',
+                StructString('foo'), -123456, -123456, StructString('barr')),
+            self)
+
+    def getStructLong(self):
+        return StructLong(-123456)
+
+    def isStructLong(self, value):
+        return value == StructLong(-123456)
+
+    def getStructString(self):
+        return StructString('hä')
+
+    def isStructString(self, value):
+        return value == StructString('hä')
+
+    def getSequenceBoolean(self):
+        return (True, True, False)
+
+    def isSequenceBoolean(self, value):
+        return value == (True, True, False)
+
+    def getNull(self):
+        return None
+
+    def isNull(self, value):
+        return value == None
+
+    def getOut(
+            self, value1, value2, value3, value4, value5, value6, value7, 
value8, value9, value10,
+            value11, value12, value13, value14, value15, value16, value17, 
value18):
+        return (
+            None, True, -12, -1234, 54321, -123456, 3456789012, -123456789, 
9876543210, -10.25,
+            100.5, 'Ö', 'hä', uno.getTypeByName('long'), -123456, ('foo', 
'barr', 'bazzz'), E_2,
+            Struct(
+                True, -12, -1234, 54321, -123456, 3456789012, -123456789, 
9876543210, -10.25, 100.5,
+                'Ö', 'hä', uno.getTypeByName('long'), -123456, ('foo', 'barr', 
'bazzz'), E_2,
+                StructLong(-123456),
+                uno.createUnoStruct(
+                    'org.libreoffice.embindtest.Template<'
+                        'any,org.libreoffice.embindtest.StructString>',
+                    StructString('foo'), -123456, -123456, 
StructString('barr')),
+                self),
+            self)
+
+    def throwRuntimeException(self):
+        raise RuntimeException('test', None)
+
+class EmbindTest(unittest.TestCase):
+    def test(self):
+        ctx = org.libreoffice.unotest.pyuno.getComponentContext()
+        test = ctx.getServiceManager().createInstanceWithContext(
+            'org.libreoffice.embindtest.Test', ctx)
+        self.assertIsNotNone(test)
+
+        v = test.getBoolean()
+        self.assertEqual(v, True)
+        self.assertTrue(test.isBoolean(v))
+        self.assertTrue(test.isBoolean(True))
+
+        v = test.getByte()
+        self.assertEqual(v, -12)
+        self.assertTrue(test.isByte(v))
+        self.assertTrue(test.isByte(-12))
+
+        v = test.getShort()
+        self.assertEqual(v, -1234)
+        self.assertTrue(test.isShort(v))
+        self.assertTrue(test.isShort(-1234))
+
+        v = test.getUnsignedShort()
+        self.assertEqual(v, 54321)
+        self.assertTrue(test.isUnsignedShort(v))
+        self.assertTrue(test.isUnsignedShort(54321))
+
+        v = test.getLong()
+        self.assertEqual(v, -123456)
+        self.assertTrue(test.isLong(v))
+        self.assertTrue(test.isLong(-123456))
+
+        v = test.getUnsignedLong()
+        self.assertEqual(v, 3456789012)
+        self.assertTrue(test.isUnsignedLong(v))
+        self.assertTrue(test.isUnsignedLong(3456789012))
+
+        v = test.getHyper()
+        self.assertEqual(v, -123456789)
+        self.assertTrue(test.isHyper(v))
+        self.assertTrue(test.isHyper(-123456789))
+
+        v = test.getUnsignedHyper()
+        self.assertEqual(v, 9876543210)
+        self.assertTrue(test.isUnsignedHyper(v))
+        self.assertTrue(test.isUnsignedHyper(9876543210))
+
+        v = test.getFloat()
+        self.assertEqual(v, -10.25)
+        self.assertTrue(test.isFloat(v))
+        self.assertTrue(test.isFloat(-10.25))
+
+        v = test.getDouble()
+        self.assertEqual(v, 100.5)
+        self.assertTrue(test.isDouble(v))
+        self.assertTrue(test.isDouble(100.5))
+
+        v = test.getChar()
+        self.assertEqual(v, 'Ö')
+        self.assertTrue(test.isChar(v))
+        self.assertTrue(test.isChar('Ö'))
+
+        v = test.getString()
+        self.assertEqual(v, 'hä')
+        self.assertTrue(test.isString(v))
+        self.assertTrue(test.isString('hä'))
+
+        v = test.getType()
+        self.assertEqual(v, uno.getTypeByName('long'))
+        self.assertTrue(test.isType(v))
+        self.assertTrue(test.isType(uno.getTypeByName('long')))
+
+        v = test.getEnum()
+        self.assertEqual(v, E_2)
+        self.assertTrue(test.isEnum(v))
+        self.assertTrue(test.isEnum(E_2))
+
+        v = test.getStruct()
+        self.assertEqual(
+            v,
+            Struct(
+                True, -12, -1234, 54321, -123456, 3456789012, -123456789, 
9876543210, -10.25, 100.5,
+                'Ö', 'hä', uno.getTypeByName('long'), -123456, ('foo', 'barr', 
'bazzz'), E_2,
+                StructLong(-123456),
+                uno.createUnoStruct(
+                    'org.libreoffice.embindtest.Template<'
+                        'any,org.libreoffice.embindtest.StructString>',
+                    StructString('foo'), -123456, -123456, 
StructString('barr')),
+                test))
+        self.assertTrue(test.isStruct(v))
+        self.assertTrue(
+            test.isStruct(
+                Struct(
+                    True, -12, -1234, 54321, -123456, 3456789012, -123456789, 
9876543210, -10.25,
+                    100.5, 'Ö', 'hä', uno.getTypeByName('long'), -123456, 
('foo', 'barr', 'bazzz'),
+                    E_2, StructLong(-123456),
+                    uno.createUnoStruct(
+                        'org.libreoffice.embindtest.Template<'
+                            'any,org.libreoffice.embindtest.StructString>',
+                        StructString('foo'), -123456, -123456, 
StructString('barr')),
+                    test)))
+
+        v = test.getStructLong()
+        self.assertEqual(v, StructLong(-123456))
+        self.assertTrue(test.isStructLong(v))
+        self.assertTrue(test.isStructLong(StructLong(-123456)))
+
+        v = test.getStructString()
+        self.assertEqual(v, StructString('hä'))
+        self.assertTrue(test.isStructString(v))
+        self.assertTrue(test.isStructString(StructString('hä')))
+
+        v = test.getTemplate()
+        self.assertEqual(
+            v,
+            uno.createUnoStruct(
+                
'org.libreoffice.embindtest.Template<any,org.libreoffice.embindtest.StructString>',
+                StructString('foo'), -123456, -123456, StructString('barr')))
+        self.assertTrue(test.isTemplate(v))
+        self.assertTrue(
+            test.isTemplate(
+                uno.createUnoStruct(
+                    'org.libreoffice.embindtest.Template<'
+                        'any,org.libreoffice.embindtest.StructString>',
+                    StructString('foo'), -123456, -123456, 
StructString('barr'))))
+
+        v = test.getAnyVoid()
+        self.assertEqual(v, None)
+        self.assertTrue(test.isAnyVoid(v))
+        self.assertTrue(uno.invoke(test, 'isAnyVoid', (uno.Any('void', 
None),))) #TODO: direct call?
+
+        v = test.getAnyBoolean()
+        self.assertEqual(v, True)
+        self.assertTrue(test.isAnyBoolean(v))
+        self.assertTrue(uno.invoke(test, 'isAnyBoolean', (uno.Any('boolean', 
True),)))
+            #TODO: direct call?
+
+        v = test.getAnyByte()
+        self.assertEqual(v, -12)
+        self.assertTrue(test.isAnyByte(v))
+        self.assertTrue(uno.invoke(test, 'isAnyByte', (uno.Any('byte', -12),)))
+            #TODO: direct call?
+
+        v = test.getAnyShort()
+        self.assertEqual(v, -1234)
+        self.assertTrue(test.isAnyShort(v))
+        self.assertTrue(uno.invoke(test, 'isAnyShort', (uno.Any('short', 
-1234),)))
+            #TODO: direct call?
+
+        v = test.getAnyUnsignedShort()
+        self.assertEqual(v, 54321)
+        self.assertFalse(test.isAnyUnsignedShort(v)) # long
+        self.assertTrue(uno.invoke(test, 'isAnyUnsignedShort', 
(uno.Any('unsigned short', 54321),)))
+            #TODO: direct call?
+
+        v = test.getAnyLong()
+        self.assertEqual(v, -123456)
+        self.assertTrue(test.isAnyLong(v))
+        self.assertTrue(uno.invoke(test, 'isAnyLong', (uno.Any('long', 
-123456),)))
+            #TODO: direct call?
+
+        v = test.getAnyUnsignedLong()
+        self.assertEqual(v, 3456789012)
+        self.assertFalse(test.isAnyUnsignedLong(v)) # hyper
+        self.assertTrue(
+            uno.invoke(test, 'isAnyUnsignedLong', (uno.Any('unsigned long', 
3456789012),)))
+            #TODO: direct call?
+
+        v = test.getAnyHyper()
+        self.assertEqual(v, -123456789)
+        self.assertFalse(test.isAnyHyper(v)) # long
+        self.assertTrue(uno.invoke(test, 'isAnyHyper', (uno.Any('hyper', 
-123456789),)))
+            #TODO: direct call?
+
+        v = test.getAnyUnsignedHyper()
+        self.assertEqual(v, 9876543210)
+        self.assertFalse(test.isAnyUnsignedHyper(v)) # hyper
+        self.assertTrue(
+            uno.invoke(test, 'isAnyUnsignedHyper', (uno.Any('unsigned hyper', 
9876543210),)))
+            #TODO: direct call?
+
+        v = test.getAnyFloat()
+        self.assertEqual(v, -10.25)
+        self.assertFalse(test.isAnyFloat(v)) # double
+        self.assertTrue(uno.invoke(test, 'isAnyFloat', (uno.Any('float', 
-10.25),)))
+            #TODO: direct call?
+
+        v = test.getAnyDouble()
+        self.assertEqual(v, 100.5)
+        self.assertTrue(test.isAnyDouble(v))
+        self.assertTrue(uno.invoke(test, 'isAnyDouble', (uno.Any('double', 
100.5),)))
+            #TODO: direct call?
+
+        v = test.getAnyChar()
+        self.assertEqual(v, 'Ö')
+        self.assertTrue(test.isAnyChar(v))
+        self.assertTrue(uno.invoke(test, 'isAnyChar', (uno.Any('char', 'Ö'),)))
+            #TODO: direct call?
+
+        v = test.getAnyString()
+        self.assertEqual(v, 'hä')
+        self.assertTrue(test.isAnyString(v))
+        self.assertTrue(uno.invoke(test, 'isAnyString', (uno.Any('string', 
'hä'),)))
+            #TODO: direct call?
+
+        v = test.getAnyType()
+        self.assertEqual(v, uno.getTypeByName('long'))
+        self.assertTrue(test.isAnyType(v))
+        self.assertTrue(
+            uno.invoke(test, 'isAnyType', (uno.Any('type', 
uno.getTypeByName('long')),)))
+            #TODO: direct call?
+
+        v = test.getAnySequence()
+        self.assertEqual(v, ('foo', 'barr', 'bazzz'))
+        self.assertFalse(test.isAnySequence(v)) # []any
+        self.assertTrue(
+            uno.invoke(
+                test, 'isAnySequence', (uno.Any('[]string', ('foo', 'barr', 
'bazzz')),)))
+            #TODO: direct call?
+
+        v = test.getAnyEnum()
+        self.assertEqual(v, E_2)
+        self.assertTrue(test.isAnyEnum(v))
+        self.assertTrue(
+            uno.invoke(test, 'isAnyEnum', 
(uno.Any('org.libreoffice.embindtest.Enum', E_2),)))
+            #TODO: direct call?
+
+        v = test.getAnyStruct()
+        self.assertEqual(
+            v,
+            Struct(
+                True, -12, -1234, 54321, -123456, 3456789012, -123456789, 
9876543210, -10.25, 100.5,
+                'Ö', 'hä', uno.getTypeByName('long'), -123456, ('foo', 'barr', 
'bazzz'), E_2,
+                StructLong(-123456),
+                uno.createUnoStruct(
+                    'org.libreoffice.embindtest.Template<'
+                        'any,org.libreoffice.embindtest.StructString>',
+                    StructString('foo'), -123456, -123456, 
StructString('barr')),
+                test))
+        self.assertTrue(test.isAnyStruct(v))
+        self.assertTrue(
+            uno.invoke(
+                test, 'isAnyStruct',
+                (uno.Any(
+                    'org.libreoffice.embindtest.Struct',
+                    Struct(
+                        True, -12, -1234, 54321, -123456, 3456789012, 
-123456789, 9876543210,
+                        -10.25, 100.5, 'Ö', 'hä', uno.getTypeByName('long'), 
-123456,
+                        ('foo', 'barr', 'bazzz'), E_2, StructLong(-123456),
+                        uno.createUnoStruct(
+                            'org.libreoffice.embindtest.Template<'
+                                'any,org.libreoffice.embindtest.StructString>',
+                                StructString('foo'), -123456, -123456, 
StructString('barr')),
+                        test)),)))
+            #TODO: direct call?
+
+        #TODO: v = test.getAnyException()
+
+        v = test.getAnyInterface()
+        self.assertEqual(v, test)
+        self.assertTrue(test.isAnyInterface(v))
+        self.assertTrue(
+            uno.invoke(
+                test, 'isAnyInterface', 
(uno.Any('org.libreoffice.embindtest.XTest', test),)))
+            #TODO: direct call?
+
+        v = test.getSequenceBoolean()
+        self.assertEqual(v, (True, True, False))
+        self.assertTrue(test.isSequenceBoolean(v))
+        self.assertTrue(test.isSequenceBoolean((True, True, False)))
+
+        v = test.getSequenceByte()
+        self.assertEqual(v, b'\xF4\x01\x0C')
+        self.assertTrue(test.isSequenceByte(v))
+        self.assertTrue(test.isSequenceByte((-12, 1, 12)))
+
+        v = test.getSequenceShort()
+        self.assertEqual(v, (-1234, 1, 1234))
+        self.assertTrue(test.isSequenceShort(v))
+        self.assertTrue(test.isSequenceShort((-1234, 1, 1234)))
+
+        v = test.getSequenceUnsignedShort()
+        self.assertEqual(v, (1, 10, 54321))
+        self.assertTrue(test.isSequenceUnsignedShort(v))
+        self.assertTrue(test.isSequenceUnsignedShort((1, 10, 54321)))
+
+        v = test.getSequenceLong()
+        self.assertEqual(v, (-123456, 1, 123456))
+        self.assertTrue(test.isSequenceLong(v))
+        self.assertTrue(test.isSequenceLong((-123456, 1, 123456)))
+
+        v = test.getSequenceUnsignedLong()
+        self.assertEqual(v, (1, 10, 3456789012))
+        self.assertTrue(test.isSequenceUnsignedLong(v))
+        self.assertTrue(test.isSequenceUnsignedLong((1, 10, 3456789012)))
+
+        v = test.getSequenceHyper()
+        self.assertEqual(v, (-123456789, 1, 123456789))
+        self.assertTrue(test.isSequenceHyper(v))
+        self.assertTrue(test.isSequenceHyper((-123456789, 1, 123456789)))
+
+        v = test.getSequenceUnsignedHyper()
+        self.assertEqual(v, (1, 10, 9876543210))
+        self.assertTrue(test.isSequenceUnsignedHyper(v))
+        self.assertTrue(test.isSequenceUnsignedHyper((1, 10, 9876543210)))
+
+        v = test.getSequenceFloat()
+        self.assertEqual(v, (-10.25, 1.5, 10.75))
+        self.assertTrue(test.isSequenceFloat(v))
+        self.assertTrue(test.isSequenceFloat((-10.25, 1.5, 10.75)))
+
+        v = test.getSequenceDouble()
+        self.assertEqual(v, (-100.5, 1.25, 100.75))
+        self.assertTrue(test.isSequenceDouble(v))
+        self.assertTrue(test.isSequenceDouble((-100.5, 1.25, 100.75)))
+
+        v = test.getSequenceChar()
+        self.assertEqual(v, ('a', 'B', 'Ö'))
+        self.assertTrue(test.isSequenceChar(v))
+        self.assertTrue(test.isSequenceChar(('a', 'B', 'Ö')))
+
+        v = test.getSequenceString()
+        self.assertEqual(v, ('foo', 'barr', 'bazzz'))
+        self.assertTrue(test.isSequenceString(v))
+        self.assertTrue(test.isSequenceString(('foo', 'barr', 'bazzz')))
+
+        v = test.getSequenceType()
+        self.assertEqual(
+            v,
+            (uno.getTypeByName('long'), uno.getTypeByName('void'),
+             uno.getTypeByName('[]org.libreoffice.embindtest.Enum')))
+        self.assertTrue(test.isSequenceType(v))
+        self.assertTrue(
+            test.isSequenceType(
+                (uno.getTypeByName('long'), uno.getTypeByName('void'),
+                 uno.getTypeByName('[]org.libreoffice.embindtest.Enum'))))
+
+        v = test.getSequenceAny()
+        self.assertEqual(v, (-123456, None, (E_2, E3, E_10)))
+        self.assertFalse(test.isSequenceAny(v)) # (long, void, []any)
+        self.assertTrue(
+            uno.invoke(
+                test, 'isSequenceAny',
+                ((-123456, None, uno.Any('[]org.libreoffice.embindtest.Enum', 
(E_2, E3, E_10))),)))
+            #TODO: direct call?
+
+        v = test.getSequenceSequenceString()
+        self.assertEqual(v, ((), ('foo', 'barr'), ('baz',)))
+        self.assertTrue(test.isSequenceSequenceString(v))
+        self.assertTrue(test.isSequenceSequenceString(((), ('foo', 'barr'), 
('baz',))))
+
+        v = test.getSequenceEnum()
+        self.assertEqual(v, (E_2, E3, E_10))
+        self.assertTrue(test.isSequenceEnum(v))
+        self.assertTrue(test.isSequenceEnum((E_2, E3, E_10)))
+
+        v = test.getSequenceStruct()
+        self.assertEqual(
+            v,
+            (Struct(
+                True, -12, -1234, 1, -123456, 1, -123456789, 1, -10.25, 
-100.5, 'a', 'hä',
+                uno.getTypeByName('long'), -123456, (), E_2, 
StructLong(-123456),
+                uno.createUnoStruct(
+                    'org.libreoffice.embindtest.Template<'
+                        'any,org.libreoffice.embindtest.StructString>',
+                    StructString('foo'), -123456, -123456, 
StructString('barr')),
+                test),
+             Struct(
+                 True, 1, 1, 10, 1, 10, 1, 10, 1.5, 1.25, 'B', 'barr', 
uno.getTypeByName('void'),
+                 None, ('foo', 'barr'), E3, StructLong(1),
+                 uno.createUnoStruct(
+                     'org.libreoffice.embindtest.Template<'
+                         'any,org.libreoffice.embindtest.StructString>',
+                     StructString('baz'), 1, None, StructString('foo')),
+                 None),
+             Struct(
+                 False, 12, 1234, 54321, 123456, 3456789012, 123456789, 
9876543210, 10.75, 100.75,
+                 'Ö', 'bazzz', 
uno.getTypeByName('[]org.libreoffice.embindtest.Enum'),
+                 uno.Any('[]org.libreoffice.embindtest.Enum', (E_2, E3, 
E_10)), ('baz',), E_10,
+                 StructLong(123456),
+                 uno.createUnoStruct(
+                     'org.libreoffice.embindtest.Template<'
+                         'any,org.libreoffice.embindtest.StructString>',
+                     StructString('barr'), 123456,
+                     uno.Any('[]org.libreoffice.embindtest.Enum', (E_2, E3, 
E_10)),
+                     StructString('bazz')),
+                 test)))
+        self.assertTrue(test.isSequenceStruct(v))
+        self.assertTrue(
+            test.isSequenceStruct(
+                (Struct(
+                    True, -12, -1234, 1, -123456, 1, -123456789, 1, -10.25, 
-100.5, 'a', 'hä',
+                    uno.getTypeByName('long'), -123456, (), E_2, 
StructLong(-123456),
+                    uno.createUnoStruct(
+                        'org.libreoffice.embindtest.Template<'
+                            'any,org.libreoffice.embindtest.StructString>',
+                        StructString('foo'), -123456, -123456, 
StructString('barr')),
+                    test),
+                 Struct(
+                     True, 1, 1, 10, 1, 10, 1, 10, 1.5, 1.25, 'B', 'barr',
+                     uno.getTypeByName('void'), None, ('foo', 'barr'), E3, 
StructLong(1),
+                     uno.createUnoStruct(
+                         'org.libreoffice.embindtest.Template<'
+                             'any,org.libreoffice.embindtest.StructString>',
+                         StructString('baz'), 1, None, StructString('foo')),
+                     None),
+                 Struct(
+                     False, 12, 1234, 54321, 123456, 3456789012, 123456789, 
9876543210, 10.75,
+                     100.75, 'Ö', 'bazzz', 
uno.getTypeByName('[]org.libreoffice.embindtest.Enum'),
+                     uno.Any('[]org.libreoffice.embindtest.Enum', (E_2, E3, 
E_10)), ('baz',), E_10,
+                     StructLong(123456),
+                     uno.createUnoStruct(
+                         'org.libreoffice.embindtest.Template<'
+                             'any,org.libreoffice.embindtest.StructString>',
+                         StructString('barr'), 123456,
+                         uno.Any('[]org.libreoffice.embindtest.Enum', (E_2, 
E3, E_10)),
+                         StructString('bazz')),
+                     test))))
+
+        v = test.getNull()
+        self.assertEqual(v, None)
+        self.assertTrue(test.isNull(v))
+        self.assertTrue(test.isNull(None))
+
+        (v, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, 
v16, v17,
+         v18) = test.getOut(
+             None, None, None, None, None, None, None, None, None, None, None, 
None, None, None,
+             None, None, None, None)
+        self.assertIsNone(v)
+        self.assertEqual(v1, True)
+        self.assertEqual(v2, -12)
+        self.assertEqual(v3, -1234)
+        self.assertEqual(v4, 54321)
+        self.assertEqual(v5, -123456)
+        self.assertEqual(v6, 3456789012)
+        self.assertEqual(v7, -123456789)
+        self.assertEqual(v8, 9876543210)
+        self.assertEqual(v9, -10.25)
+        self.assertEqual(v10, 100.5)
+        self.assertEqual(v11, 'Ö')
+        self.assertEqual(v12, 'hä')
+        self.assertEqual(v13, uno.getTypeByName('long'))
+        self.assertEqual(v14, -123456)
+        self.assertEqual(v15, ('foo', 'barr', 'bazzz'))
+        self.assertEqual(v16, E_2)
+        self.assertEqual(
+            v17,
+            Struct(
+                True, -12, -1234, 54321, -123456, 3456789012, -123456789, 
9876543210, -10.25, 100.5,
+                'Ö', 'hä', uno.getTypeByName('long'), -123456, ('foo', 'barr', 
'bazzz'), E_2,
+                StructLong(-123456),
+                uno.createUnoStruct(
+                    'org.libreoffice.embindtest.Template<'
+                        'any,org.libreoffice.embindtest.StructString>',
+                    StructString('foo'), -123456, -123456, 
StructString('barr')),
+                test))
+        self.assertEqual(v18, test)
+
+        with self.assertRaises(RuntimeException) as cm:
+            test.throwRuntimeException()
+        self.assertTrue(cm.exception.Message.startswith('test'))
+            #TODO: use Python 3.14 assertStartsWith
+        self.assertIsNone(cm.exception.Context)
+
+        test.executeTest(Test())
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/unotest/source/embindtest/embindtest.cxx 
b/unotest/source/embindtest/embindtest.cxx
index 424c2f6d0a87..e858f36504f9 100644
--- a/unotest/source/embindtest/embindtest.cxx
+++ b/unotest/source/embindtest/embindtest.cxx
@@ -66,6 +66,226 @@ void verify(bool value, std::source_location const& 
location = std::source_locat
     }
 }
 
+void doExecuteTest(css::uno::Reference<org::libreoffice::embindtest::XTest> 
const& test)
+{
+    {
+        bool const val = test->getBoolean();
+        verify(val);
+        bool const ok = test->isBoolean(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getByte();
+        verify(val == -12);
+        bool const ok = test->isByte(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getShort();
+        verify(val == -1234);
+        bool const ok = test->isShort(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getUnsignedShort();
+        verify(val == 54321);
+        bool const ok = test->isUnsignedShort(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getLong();
+        verify(val == -123456);
+        bool const ok = test->isLong(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getUnsignedLong();
+        verify(val == 3456789012);
+        bool const ok = test->isUnsignedLong(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getHyper();
+        verify(val == -123456789);
+        bool const ok = test->isHyper(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getUnsignedHyper();
+        verify(val == 9876543210);
+        bool const ok = test->isUnsignedHyper(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getFloat();
+        verify(val == -10.25);
+        bool const ok = test->isFloat(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getDouble();
+        verify(val == 100.5);
+        bool const ok = test->isDouble(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getChar();
+        verify(val == u'Ö');
+        bool const ok = test->isChar(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getString();
+        verify(val == u"hä"_ustr);
+        bool const ok = test->isString(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getType();
+        verify(val == cppu::UnoType<sal_Int32>::get());
+        bool const ok = test->isType(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getAnyVoid();
+        verify(val == css::uno::Any());
+        bool const ok = test->isAnyVoid(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getEnum();
+        verify(val == org::libreoffice::embindtest::Enum_E_2);
+        bool const ok = test->isEnum(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getStruct();
+        verify(
+            val
+            == org::libreoffice::embindtest::Struct{ true,
+                                                     -12,
+                                                     -1234,
+                                                     54321,
+                                                     -123456,
+                                                     3456789012,
+                                                     -123456789,
+                                                     9876543210,
+                                                     -10.25,
+                                                     100.5,
+                                                     u'Ö',
+                                                     u"hä"_ustr,
+                                                     
cppu::UnoType<sal_Int32>::get(),
+                                                     
css::uno::Any(sal_Int32(-123456)),
+                                                     { u"foo"_ustr, 
u"barr"_ustr, u"bazzz"_ustr },
+                                                     
org::libreoffice::embindtest::Enum_E_2,
+                                                     { -123456 },
+                                                     { { u"foo"_ustr },
+                                                       -123456,
+                                                       
css::uno::Any(sal_Int32(-123456)),
+                                                       { u"barr"_ustr } },
+                                                     test });
+        bool const ok = test->isStruct(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getStructLong();
+        verify(val == org::libreoffice::embindtest::StructLong{ -123456 });
+        bool const ok = test->isStructLong(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getStructString();
+        verify(val == org::libreoffice::embindtest::StructString{ u"hä"_ustr 
});
+        bool const ok = test->isStructString(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getSequenceBoolean();
+        verify(val == css::uno::Sequence<sal_Bool>{ true, true, false });
+        bool const ok = test->isSequenceBoolean(val);
+        verify(ok);
+    }
+    {
+        auto const val = test->getNull();
+        verify(val == 
css::uno::Reference<org::libreoffice::embindtest::XTest>());
+        bool const ok = test->isNull(val);
+        verify(ok);
+    }
+    {
+        sal_Bool value1;
+        sal_Int8 value2;
+        sal_Int16 value3;
+        sal_uInt16 value4;
+        sal_Int32 value5;
+        sal_uInt32 value6;
+        sal_Int64 value7;
+        sal_uInt64 value8;
+        float value9;
+        double value10;
+        sal_Unicode value11;
+        OUString value12;
+        css::uno::Type value13;
+        css::uno::Any value14;
+        css::uno::Sequence<OUString> value15;
+        org::libreoffice::embindtest::Enum value16;
+        org::libreoffice::embindtest::Struct value17;
+        css::uno::Reference<org::libreoffice::embindtest::XTest> value18;
+        test->getOut(value1, value2, value3, value4, value5, value6, value7, 
value8, value9,
+                     value10, value11, value12, value13, value14, value15, 
value16, value17,
+                     value18);
+        verify(value1);
+        verify(value2 == -12);
+        verify(value3 == -1234);
+        verify(value4 == 54321);
+        verify(value5 == -123456);
+        verify(value6 == 3456789012);
+        verify(value7 == -123456789);
+        verify(value8 == 9876543210);
+        verify(value9 == -10.25);
+        verify(value10 == 100.5);
+        verify(value11 == u'Ö');
+        verify(value12 == u"hä"_ustr);
+        verify(value13 == cppu::UnoType<sal_Int32>::get());
+        verify(value14 == css::uno::Any(sal_Int32(-123456)));
+        verify(value15 == css::uno::Sequence<OUString>{ u"foo"_ustr, 
u"barr"_ustr, u"bazzz"_ustr });
+        verify(value16 == org::libreoffice::embindtest::Enum_E_2);
+        verify(
+            value17
+            == org::libreoffice::embindtest::Struct{ true,
+                                                     -12,
+                                                     -1234,
+                                                     54321,
+                                                     -123456,
+                                                     3456789012,
+                                                     -123456789,
+                                                     9876543210,
+                                                     -10.25,
+                                                     100.5,
+                                                     u'Ö',
+                                                     u"hä"_ustr,
+                                                     
cppu::UnoType<sal_Int32>::get(),
+                                                     
css::uno::Any(sal_Int32(-123456)),
+                                                     { u"foo"_ustr, 
u"barr"_ustr, u"bazzz"_ustr },
+                                                     
org::libreoffice::embindtest::Enum_E_2,
+                                                     { -123456 },
+                                                     { { u"foo"_ustr },
+                                                       -123456,
+                                                       
css::uno::Any(sal_Int32(-123456)),
+                                                       { u"barr"_ustr } },
+                                                     test });
+        verify(value18 == test);
+    }
+    try
+    {
+        test->throwRuntimeException();
+        verify(false);
+    }
+    catch (css::uno::RuntimeException& e)
+    {
+        verify(e.Message.startsWith("test"));
+    }
+}
+
 class TestThread : public salhelper::Thread
 {
 public:
@@ -958,6 +1178,12 @@ class Test
         return t->value;
     }
 
+    void SAL_CALL
+    executeTest(css::uno::Reference<org::libreoffice::embindtest::XTest> 
const& test) override
+    {
+        doExecuteTest(test);
+    }
+
     OUString stringAttribute_ = u"hä"_ustr;
 };
 
@@ -1010,223 +1236,7 @@ private:
         {
             throw css::uno::RuntimeException(u"cannot map from UNO to 
C++"_ustr);
         }
-        {
-            bool const val = ifcCpp->getBoolean();
-            verify(val);
-            bool const ok = ifcCpp->isBoolean(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getByte();
-            verify(val == -12);
-            bool const ok = ifcCpp->isByte(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getShort();
-            verify(val == -1234);
-            bool const ok = ifcCpp->isShort(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getUnsignedShort();
-            verify(val == 54321);
-            bool const ok = ifcCpp->isUnsignedShort(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getLong();
-            verify(val == -123456);
-            bool const ok = ifcCpp->isLong(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getUnsignedLong();
-            verify(val == 3456789012);
-            bool const ok = ifcCpp->isUnsignedLong(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getHyper();
-            verify(val == -123456789);
-            bool const ok = ifcCpp->isHyper(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getUnsignedHyper();
-            verify(val == 9876543210);
-            bool const ok = ifcCpp->isUnsignedHyper(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getFloat();
-            verify(val == -10.25);
-            bool const ok = ifcCpp->isFloat(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getDouble();
-            verify(val == 100.5);
-            bool const ok = ifcCpp->isDouble(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getChar();
-            verify(val == u'Ö');
-            bool const ok = ifcCpp->isChar(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getString();
-            verify(val == u"hä"_ustr);
-            bool const ok = ifcCpp->isString(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getType();
-            verify(val == cppu::UnoType<sal_Int32>::get());
-            bool const ok = ifcCpp->isType(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getEnum();
-            verify(val == org::libreoffice::embindtest::Enum_E_2);
-            bool const ok = ifcCpp->isEnum(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getStruct();
-            verify(val
-                   == org::libreoffice::embindtest::Struct{
-                          true,
-                          -12,
-                          -1234,
-                          54321,
-                          -123456,
-                          3456789012,
-                          -123456789,
-                          9876543210,
-                          -10.25,
-                          100.5,
-                          u'Ö',
-                          u"hä"_ustr,
-                          cppu::UnoType<sal_Int32>::get(),
-                          css::uno::Any(sal_Int32(-123456)),
-                          { u"foo"_ustr, u"barr"_ustr, u"bazzz"_ustr },
-                          org::libreoffice::embindtest::Enum_E_2,
-                          { -123456 },
-                          { { u"foo"_ustr },
-                            -123456,
-                            css::uno::Any(sal_Int32(-123456)),
-                            { u"barr"_ustr } },
-                          ifcCpp });
-            bool const ok = ifcCpp->isStruct(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getStructLong();
-            verify(val == org::libreoffice::embindtest::StructLong{ -123456 });
-            bool const ok = ifcCpp->isStructLong(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getStructString();
-            verify(val == org::libreoffice::embindtest::StructString{ 
u"hä"_ustr });
-            bool const ok = ifcCpp->isStructString(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getAnyVoid();
-            verify(val == css::uno::Any());
-            bool const ok = ifcCpp->isAnyVoid(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getSequenceBoolean();
-            verify(val == css::uno::Sequence<sal_Bool>{ true, true, false });
-            bool const ok = ifcCpp->isSequenceBoolean(val);
-            verify(ok);
-        }
-        {
-            auto const val = ifcCpp->getNull();
-            verify(val == 
css::uno::Reference<org::libreoffice::embindtest::XTest>());
-            bool const ok = ifcCpp->isNull(val);
-            verify(ok);
-        }
-        {
-            sal_Bool value1;
-            sal_Int8 value2;
-            sal_Int16 value3;
-            sal_uInt16 value4;
-            sal_Int32 value5;
-            sal_uInt32 value6;
-            sal_Int64 value7;
-            sal_uInt64 value8;
-            float value9;
-            double value10;
-            sal_Unicode value11;
-            OUString value12;
-            css::uno::Type value13;
-            css::uno::Any value14;
-            css::uno::Sequence<OUString> value15;
-            org::libreoffice::embindtest::Enum value16;
-            org::libreoffice::embindtest::Struct value17;
-            css::uno::Reference<org::libreoffice::embindtest::XTest> value18;
-            ifcCpp->getOut(value1, value2, value3, value4, value5, value6, 
value7, value8, value9,
-                           value10, value11, value12, value13, value14, 
value15, value16, value17,
-                           value18);
-            verify(value1);
-            verify(value2 == -12);
-            verify(value3 == -1234);
-            verify(value4 == 54321);
-            verify(value5 == -123456);
-            verify(value6 == 3456789012);
-            verify(value7 == -123456789);
-            verify(value8 == 9876543210);
-            verify(value9 == -10.25);
-            verify(value10 == 100.5);
-            verify(value11 == u'Ö');
-            verify(value12 == u"hä"_ustr);
-            verify(value13 == cppu::UnoType<sal_Int32>::get());
-            verify(value14 == css::uno::Any(sal_Int32(-123456)));
-            verify(value15
-                   == css::uno::Sequence<OUString>{ u"foo"_ustr, u"barr"_ustr, 
u"bazzz"_ustr });
-            verify(value16 == org::libreoffice::embindtest::Enum_E_2);
-            verify(value17
-                   == org::libreoffice::embindtest::Struct{
-                          true,
-                          -12,
-                          -1234,
-                          54321,
-                          -123456,
-                          3456789012,
-                          -123456789,
-                          9876543210,
-                          -10.25,
-                          100.5,
-                          u'Ö',
-                          u"hä"_ustr,
-                          cppu::UnoType<sal_Int32>::get(),
-                          css::uno::Any(sal_Int32(-123456)),
-                          { u"foo"_ustr, u"barr"_ustr, u"bazzz"_ustr },
-                          org::libreoffice::embindtest::Enum_E_2,
-                          { -123456 },
-                          { { u"foo"_ustr },
-                            -123456,
-                            css::uno::Any(sal_Int32(-123456)),
-                            { u"barr"_ustr } },
-                          ifcCpp });
-            verify(value18 == ifcCpp);
-        }
-        try
-        {
-            ifcCpp->throwRuntimeException();
-            verify(false);
-        }
-        catch (css::uno::RuntimeException& e)
-        {
-            verify(e.Message.startsWith("test"));
-        }
+        doExecuteTest(ifcCpp);
         {
             auto const val1 = ifcCpp->getStringAttribute();
             verify(val1 == u"hä"_ustr);

Reply via email to