Add a unit test that constructs every service-based singleton via class name
The idea is to check that all of the class names match a singleton declared in a component somewhere and that they return an object that implements the advertised interface. Otherwise the generated getter for the singleton will fail with a runtime exception. Change-Id: I1352e7392e33e9182962e6279fcb62cf3b58352a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200056 Reviewed-by: Neil Roberts <bpeeluk@yahoo.co.uk> Tested-by: Jenkins
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
|
||||
#
|
||||
# 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_CppunitTest_CppunitTest,singletons))
|
||||
|
||||
$(eval $(call gb_CppunitTest_add_exception_objects,singletons, \
|
||||
postprocess/qa/singletons \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_libraries,singletons, \
|
||||
comphelper \
|
||||
cppu \
|
||||
cppuhelper \
|
||||
sal \
|
||||
test \
|
||||
unotest \
|
||||
vcl \
|
||||
))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_sdk_api,singletons))
|
||||
$(eval $(call gb_CppunitTest_use_api,singletons,oovbaapi))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_ure,singletons))
|
||||
$(eval $(call gb_CppunitTest_use_vcl,singletons))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_rdb,singletons,services))
|
||||
|
||||
$(eval $(call gb_CppunitTest_use_configuration,singletons))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
@@ -63,4 +63,8 @@ $(eval $(call gb_Module_add_check_targets,postprocess,\
|
||||
))
|
||||
endif
|
||||
|
||||
$(eval $(call gb_Module_add_check_targets,postprocess,\
|
||||
CppunitTest_singletons \
|
||||
))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
|
||||
*/
|
||||
|
||||
// Tries to get every interface-based singleton registered in the type description manager using its
|
||||
// type name. See tdf#170930 for an example of a mistake that can make this fail.
|
||||
|
||||
#include <sal/config.h>
|
||||
|
||||
#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
|
||||
#include <com/sun/star/reflection/XSingletonTypeDescription2.hpp>
|
||||
#include <test/bootstrapfixture.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr OUString TYPE_DESCRIPTION_MANAGER
|
||||
= u"/singletons/com.sun.star.reflection.theTypeDescriptionManager"_ustr;
|
||||
|
||||
class Test : public test::BootstrapFixture
|
||||
{
|
||||
public:
|
||||
void test();
|
||||
|
||||
CPPUNIT_TEST_SUITE(Test);
|
||||
CPPUNIT_TEST(test);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
};
|
||||
|
||||
void Test::test()
|
||||
{
|
||||
css::uno::Reference<css::reflection::XTypeDescriptionEnumerationAccess> xTDMgr;
|
||||
|
||||
m_xContext->getValueByName(TYPE_DESCRIPTION_MANAGER) >>= xTDMgr;
|
||||
|
||||
if (!xTDMgr.is())
|
||||
throw css::uno::RuntimeException("cannot get singleton " + TYPE_DESCRIPTION_MANAGER);
|
||||
|
||||
css::uno::Sequence<css::uno::TypeClass> aTypes = { css::uno::TypeClass_SINGLETON };
|
||||
|
||||
css::uno::Reference<css::reflection::XTypeDescriptionEnumeration> xTypeEnum
|
||||
= xTDMgr->createTypeDescriptionEnumeration(
|
||||
"", aTypes, css::reflection::TypeDescriptionSearchDepth_INFINITE);
|
||||
|
||||
while (true)
|
||||
{
|
||||
css::uno::Reference<css::reflection::XTypeDescription> xType;
|
||||
|
||||
try
|
||||
{
|
||||
xType = xTypeEnum->nextTypeDescription();
|
||||
}
|
||||
catch (css::container::NoSuchElementException&)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
css::uno::Reference<css::reflection::XSingletonTypeDescription2> xSingleton(
|
||||
xType, css::uno::UNO_QUERY);
|
||||
|
||||
// Skip singletons that are not interface-based
|
||||
if (!xSingleton.is() || !xSingleton->isInterfaceBased())
|
||||
continue;
|
||||
|
||||
OUString sName = "/singletons/" + xSingleton->getName();
|
||||
|
||||
css::uno::Reference<css::uno::XInterface> xImpl;
|
||||
|
||||
m_xContext->getValueByName(sName) >>= xImpl;
|
||||
|
||||
if (!xImpl.is())
|
||||
throw css::uno::RuntimeException("cannot get singleton " + sName);
|
||||
|
||||
css::uno::Reference<css::reflection::XTypeDescription> xInterface
|
||||
= xSingleton->getInterface();
|
||||
|
||||
css::uno::Type interfaceType(xInterface->getTypeClass(), xInterface->getName());
|
||||
|
||||
// Make sure that the returned object supports the interface of the singleton
|
||||
if (!xImpl->queryInterface(interfaceType).hasValue())
|
||||
{
|
||||
throw css::uno::RuntimeException("Singleton " + xSingleton->getName()
|
||||
+ " doesn’t support the " + xInterface->getName()
|
||||
+ " interface");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
|
||||
}
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
Reference in New Issue
Block a user