1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cppu_ifcontainer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <cppunit/simpleheader.hxx>
33 #include "com/sun/star/lang/XEventListener.hpp"
34 #include "cppuhelper/interfacecontainer.hxx"
35 #include "cppuhelper/queryinterface.hxx"
36 #include "cppuhelper/implbase1.hxx"
37 #include "cppuhelper/propshlp.hxx"
39 using namespace com::sun::star
;
40 using namespace com::sun::star::uno
;
41 using namespace com::sun::star::lang
;
47 const char * const &rA
,
48 const char * const &rB
) const
49 { return !strcmp(rA
, rB
); }
53 size_t operator()( const char * &rName
) const
55 return rtl::OString(rName
).hashCode();
59 class ContainerListener
;
61 struct ContainerStats
{
64 ContainerStats() : m_nAlive(0), m_nDisposed(0) {}
67 class ContainerListener
: public ::cppu::WeakImplHelper1
< XEventListener
>
69 ContainerStats
*m_pStats
;
71 ContainerListener(ContainerStats
*pStats
)
72 : m_pStats(pStats
) { m_pStats
->m_nAlive
++; }
73 virtual ~ContainerListener() { m_pStats
->m_nAlive
--; }
74 virtual void SAL_CALL
disposing( const EventObject
& )
75 throw (RuntimeException
)
77 m_pStats
->m_nDisposed
++;
81 namespace cppu_ifcontainer
83 class IfTest
: public CppUnit::TestFixture
86 static const int nTests
= 10;
88 void testCreateDispose()
90 ContainerStats aStats
;
91 cppu::OInterfaceContainerHelper
*pContainer
;
93 pContainer
= new cppu::OInterfaceContainerHelper(m_aGuard
);
95 CPPUNIT_ASSERT_MESSAGE("Empty container not empty",
96 pContainer
->getLength() == 0);
99 for (i
= 0; i
< nTests
; i
++)
101 Reference
<XEventListener
> xRef
= new ContainerListener(&aStats
);
102 int nNewLen
= pContainer
->addInterface(xRef
);
104 CPPUNIT_ASSERT_MESSAGE("addition length mismatch",
106 CPPUNIT_ASSERT_MESSAGE("addition length mismatch",
107 pContainer
->getLength() == i
+ 1);
109 CPPUNIT_ASSERT_MESSAGE("alive count mismatch",
110 aStats
.m_nAlive
== nTests
);
113 pContainer
->disposeAndClear(aObj
);
115 CPPUNIT_ASSERT_MESSAGE("dispose count mismatch",
116 aStats
.m_nDisposed
== nTests
);
117 CPPUNIT_ASSERT_MESSAGE("leaked container left alive",
118 aStats
.m_nAlive
== 0);
126 ContainerStats aStats
;
127 cppu::OInterfaceContainerHelper
*pContainer
;
128 pContainer
= new cppu::OInterfaceContainerHelper(m_aGuard
);
130 std::vector
< Reference
< XEventListener
> > aListeners
;
131 for (i
= 0; i
< nTests
; i
++)
133 Reference
<XEventListener
> xRef
= new ContainerListener(&aStats
);
134 int nNewLen
= pContainer
->addInterface(xRef
);
135 aListeners
.push_back(xRef
);
137 Sequence
< Reference
< XInterface
> > aElements
;
138 aElements
= pContainer
->getElements();
140 CPPUNIT_ASSERT_MESSAGE("query contents",
141 (int)aElements
.getLength() == nTests
);
142 if ((int)aElements
.getLength() == nTests
)
144 for (i
= 0; i
< nTests
; i
++)
146 CPPUNIT_ASSERT_MESSAGE("mismatching elements",
147 aElements
[i
] == aListeners
[i
]);
152 CPPUNIT_ASSERT_MESSAGE("non-empty container post clear",
153 pContainer
->getLength() == 0);
157 template < typename ContainerType
, typename ContainedType
>
158 void doContainerTest(const ContainedType
*pTypes
)
160 ContainerStats aStats
;
161 ContainerType
*pContainer
;
162 pContainer
= new ContainerType(m_aGuard
);
165 Reference
<XEventListener
> xRefs
[nTests
* 2];
167 // add these interfaces
168 for (i
= 0; i
< nTests
* 2; i
++)
170 xRefs
[i
] = new ContainerListener(&aStats
);
171 pContainer
->addInterface(pTypes
[i
/ 2], xRefs
[i
]);
174 // check it is all there
175 for (i
= 0; i
< nTests
; i
++)
177 cppu::OInterfaceContainerHelper
*pHelper
;
179 pHelper
= pContainer
->getContainer(pTypes
[i
]);
181 CPPUNIT_ASSERT_MESSAGE("no helper", pHelper
!= NULL
);
182 Sequence
<Reference
< XInterface
> > aSeq
= pHelper
->getElements();
183 CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq
.getLength() == 2);
184 CPPUNIT_ASSERT_MESSAGE("match", aSeq
[0] == xRefs
[i
*2]);
185 CPPUNIT_ASSERT_MESSAGE("match", aSeq
[1] == xRefs
[i
*2+1]);
188 // remove every other interface
189 for (i
= 0; i
< nTests
; i
++)
190 pContainer
->removeInterface(pTypes
[i
], xRefs
[i
*2+1]);
192 // check it is half there
193 for (i
= 0; i
< nTests
; i
++)
195 cppu::OInterfaceContainerHelper
*pHelper
;
197 pHelper
= pContainer
->getContainer(pTypes
[i
]);
199 CPPUNIT_ASSERT_MESSAGE("no helper", pHelper
!= NULL
);
200 Sequence
<Reference
< XInterface
> > aSeq
= pHelper
->getElements();
201 CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq
.getLength() == 1);
202 CPPUNIT_ASSERT_MESSAGE("match", aSeq
[0] == xRefs
[i
*2]);
205 // remove the 1st half of the rest
206 for (i
= 0; i
< nTests
/ 2; i
++)
207 pContainer
->removeInterface(pTypes
[i
], xRefs
[i
*2]);
209 // check it is half there
210 for (i
= 0; i
< nTests
/ 2; i
++)
212 cppu::OInterfaceContainerHelper
*pHelper
;
214 pHelper
= pContainer
->getContainer(pTypes
[i
]);
215 CPPUNIT_ASSERT_MESSAGE("no helper", pHelper
!= NULL
);
216 Sequence
<Reference
< XInterface
> > aSeq
= pHelper
->getElements();
217 CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq
.getLength() == 0);
223 void testOMultiTypeInterfaceContainerHelper()
225 uno::Type pTypes
[nTests
] =
227 ::cppu::UnoType
< bool >::get(),
228 ::cppu::UnoType
< float >::get(),
229 ::cppu::UnoType
< double >::get(),
230 ::cppu::UnoType
< ::sal_uInt64
>::get(),
231 ::cppu::UnoType
< ::sal_Int64
>::get(),
232 ::cppu::UnoType
< ::sal_uInt32
>::get(),
233 ::cppu::UnoType
< ::sal_Int32
>::get(),
234 ::cppu::UnoType
< ::sal_Int16
>::get(),
235 ::cppu::UnoType
< ::rtl::OUString
>::get(),
236 ::cppu::UnoType
< ::sal_Int8
>::get()
238 doContainerTest
< cppu::OMultiTypeInterfaceContainerHelper
,
242 void testOMultiTypeInterfaceContainerHelperInt32()
244 sal_Int32 pTypes
[nTests
] =
257 doContainerTest
< cppu::OMultiTypeInterfaceContainerHelperInt32
, sal_Int32
> (pTypes
);
260 void testOMultiTypeInterfaceContainerHelperVar()
262 typedef ::cppu::OMultiTypeInterfaceContainerHelperVar
<
263 const char *,hashStr
,equalStr
> StrContainer
;
265 const char *pTypes
[nTests
] =
267 "this_is", "such", "fun", "writing", "unit", "tests", "when", "it", "works", "anyway"
269 doContainerTest
< StrContainer
, const char *> (pTypes
);
272 // Automatic registration code
273 CPPUNIT_TEST_SUITE(IfTest
);
274 CPPUNIT_TEST(testCreateDispose
);
275 CPPUNIT_TEST(testEnumerate
);
276 CPPUNIT_TEST(testOMultiTypeInterfaceContainerHelper
);
277 CPPUNIT_TEST(testOMultiTypeInterfaceContainerHelperVar
);
278 CPPUNIT_TEST(testOMultiTypeInterfaceContainerHelperInt32
);
279 CPPUNIT_TEST_SUITE_END();
281 } // namespace cppu_ifcontainer
283 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(cppu_ifcontainer::IfTest
,