1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/types.h>
22 #include <cppunit/TestFixture.h>
23 #include <cppunit/plugin/TestPlugIn.h>
24 #include <cppunit/extensions/HelperMacros.h>
26 #include <Interface1.hpp>
31 using ::com::sun::star::uno::Type
;
32 using ::com::sun::star::uno::Any
;
33 using ::com::sun::star::uno::Reference
;
34 using ::com::sun::star::uno::RuntimeException
;
35 using ::com::sun::star::uno::UNO_SET_THROW
;
37 class Foo
: public Interface1
45 Foo(const Foo
&) = delete;
46 const Foo
& operator=(const Foo
&) = delete;
48 virtual Any SAL_CALL
queryInterface(const Type
& _type
) override
50 if (_type
== cppu::UnoType
<XInterface
>::get())
52 return css::uno::Any(css::uno::Reference
<css::uno::XInterface
>(
55 if (_type
== cppu::UnoType
<Interface1
>::get())
57 return css::uno::Any(css::uno::Reference
<Interface1
>(this));
63 virtual void SAL_CALL
acquire() noexcept override
65 osl_atomic_increment( &m_refCount
);
68 virtual void SAL_CALL
release() noexcept override
70 if ( 0 == osl_atomic_decrement( &m_refCount
) )
80 oslInterlockedCount m_refCount
;
83 // Check that the up-casting Reference conversion constructor catches the
86 struct Base1
: public css::uno::XInterface
{
87 virtual ~Base1() = delete;
88 static ::css::uno::Type
const & static_type(void * = nullptr) // loplugin:refcounting
89 { return ::cppu::UnoType
<Base1
>::get(); }
91 struct Base2
: public Base1
{
92 virtual ~Base2() override
= delete;
94 struct Base3
: public Base1
{ virtual ~Base3() override
= delete; };
95 struct Derived
: public Base2
, public Base3
{
96 virtual ~Derived() override
= delete;
99 // The special case using the conversion operator instead:
100 css::uno::Reference
< css::uno::XInterface
> testUpcast1(
101 css::uno::Reference
< Derived
> const & ref
)
103 Base1::static_type(); // prevent loplugin:unreffun firing
107 // The normal up-cast case:
108 css::uno::Reference
< Base1
> testUpcast2(
109 css::uno::Reference
< Base2
> const & ref
)
112 // Commenting this in should cause a compiler error due to an ambiguous up-cast:
114 css::uno::Reference< Base1 > testFailingUpcast3(
115 css::uno::Reference< Derived > const & ref)
119 // Commenting this in should cause a compiler error due to a down-cast:
121 css::uno::Reference< Base2 > testFailingUpcast4(
122 css::uno::Reference< Base1 > const & ref)
126 // Commenting this in should cause a compiler error due to a down-cast:
128 css::uno::Reference< Base1 > testFailingUpcast5(
129 css::uno::Reference< css::uno::XInterface > const & ref)
133 class Test
: public ::CppUnit::TestFixture
137 void testUnoSetThrow();
138 void testUpcastCompilation();
140 CPPUNIT_TEST_SUITE(Test
);
141 CPPUNIT_TEST(testUnoSetThrow
);
142 CPPUNIT_TEST(testUpcastCompilation
);
143 CPPUNIT_TEST_SUITE_END();
146 void Test::testUnoSetThrow()
148 Reference
< Interface1
> xNull
;
149 Reference
< Interface1
> xFoo( new Foo
);
151 // ctor taking Reference< interface_type >
152 bool bCaughtException
= false;
153 try { Reference
< Interface1
> x( xNull
, UNO_SET_THROW
); } catch( const RuntimeException
& ) { bCaughtException
= true; }
154 CPPUNIT_ASSERT_EQUAL( true, bCaughtException
);
156 bCaughtException
= false;
157 try { Reference
< Interface1
> x( xFoo
, UNO_SET_THROW
); } catch( const RuntimeException
& ) { bCaughtException
= true; }
158 CPPUNIT_ASSERT_EQUAL( false, bCaughtException
);
160 // ctor taking interface_type*
161 bCaughtException
= false;
162 try { Reference
< Interface1
> x( xNull
.get(), UNO_SET_THROW
); } catch( const RuntimeException
& ) { bCaughtException
= true; }
163 CPPUNIT_ASSERT_EQUAL( true, bCaughtException
);
165 bCaughtException
= false;
166 try { Reference
< Interface1
> x( xFoo
.get(), UNO_SET_THROW
); } catch( const RuntimeException
& ) { bCaughtException
= true; }
167 CPPUNIT_ASSERT_EQUAL( false, bCaughtException
);
169 Reference
< Interface1
> x
;
170 // "set" taking Reference< interface_type >
171 bCaughtException
= false;
172 try { x
.set( xNull
, UNO_SET_THROW
); } catch( const RuntimeException
& ) { bCaughtException
= true; }
173 CPPUNIT_ASSERT_EQUAL( true, bCaughtException
);
175 bCaughtException
= false;
176 try { x
.set( xFoo
, UNO_SET_THROW
); } catch( const RuntimeException
& ) { bCaughtException
= true; }
177 CPPUNIT_ASSERT_EQUAL( false, bCaughtException
);
179 // "set" taking interface_type*
180 bCaughtException
= false;
181 try { x
.set( xNull
.get(), UNO_SET_THROW
); } catch( const RuntimeException
& ) { bCaughtException
= true; }
182 CPPUNIT_ASSERT_EQUAL( true, bCaughtException
);
184 bCaughtException
= false;
185 try { x
.set( xFoo
.get(), UNO_SET_THROW
); } catch( const RuntimeException
& ) { bCaughtException
= true; }
186 CPPUNIT_ASSERT_EQUAL( false, bCaughtException
);
189 // Include a dummy test calling those functions, to avoid warnings about those
190 // functions being unused:
191 void Test::testUpcastCompilation()
193 testUpcast1(css::uno::Reference
< Derived
>());
194 testUpcast2(css::uno::Reference
< Base2
>());
197 CPPUNIT_TEST_SUITE_REGISTRATION(Test
);
201 CPPUNIT_PLUGIN_IMPLEMENT();
203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */