1*9d7e27acSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9d7e27acSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9d7e27acSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9d7e27acSAndrew Rist  * distributed with this work for additional information
6*9d7e27acSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9d7e27acSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9d7e27acSAndrew Rist  * "License"); you may not use this file except in compliance
9*9d7e27acSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9d7e27acSAndrew Rist  *
11*9d7e27acSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9d7e27acSAndrew Rist  *
13*9d7e27acSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9d7e27acSAndrew Rist  * software distributed under the License is distributed on an
15*9d7e27acSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9d7e27acSAndrew Rist  * KIND, either express or implied.  See the License for the
17*9d7e27acSAndrew Rist  * specific language governing permissions and limitations
18*9d7e27acSAndrew Rist  * under the License.
19*9d7e27acSAndrew Rist  *
20*9d7e27acSAndrew Rist  *************************************************************/
21*9d7e27acSAndrew Rist 
22*9d7e27acSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include <testshl/simpleheader.hxx>
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "com/sun/star/lang/XEventListener.hpp"
27cdf0e10cSrcweir #include "cppuhelper/interfacecontainer.hxx"
28cdf0e10cSrcweir #include "cppuhelper/queryinterface.hxx"
29cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx"
30cdf0e10cSrcweir #include "cppuhelper/propshlp.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir using namespace com::sun::star;
33cdf0e10cSrcweir using namespace com::sun::star::uno;
34cdf0e10cSrcweir using namespace com::sun::star::lang;
35cdf0e10cSrcweir 
36cdf0e10cSrcweir 
37cdf0e10cSrcweir struct equalStr
38cdf0e10cSrcweir {
39cdf0e10cSrcweir     bool operator()(
40cdf0e10cSrcweir         const char * const &rA,
41cdf0e10cSrcweir         const char * const &rB) const
42cdf0e10cSrcweir         { return !strcmp(rA, rB); }
43cdf0e10cSrcweir };
44cdf0e10cSrcweir struct hashStr
45cdf0e10cSrcweir {
46cdf0e10cSrcweir     size_t operator()( const char * &rName ) const
47cdf0e10cSrcweir     {
48cdf0e10cSrcweir         return rtl::OString(rName).hashCode();
49cdf0e10cSrcweir     }
50cdf0e10cSrcweir };
51cdf0e10cSrcweir 
52cdf0e10cSrcweir class ContainerListener;
53cdf0e10cSrcweir 
54cdf0e10cSrcweir struct ContainerStats {
55cdf0e10cSrcweir     int m_nAlive;
56cdf0e10cSrcweir     int m_nDisposed;
57cdf0e10cSrcweir     ContainerStats() : m_nAlive(0), m_nDisposed(0) {}
58cdf0e10cSrcweir };
59cdf0e10cSrcweir 
60cdf0e10cSrcweir class ContainerListener : public ::cppu::WeakImplHelper1< XEventListener >
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     ContainerStats *m_pStats;
63cdf0e10cSrcweir public:
64cdf0e10cSrcweir     ContainerListener(ContainerStats *pStats)
65cdf0e10cSrcweir         : m_pStats(pStats) { m_pStats->m_nAlive++; }
66cdf0e10cSrcweir     virtual ~ContainerListener() { m_pStats->m_nAlive--; }
67cdf0e10cSrcweir     virtual void SAL_CALL disposing( const EventObject& )
68cdf0e10cSrcweir         throw (RuntimeException)
69cdf0e10cSrcweir     {
70cdf0e10cSrcweir         m_pStats->m_nDisposed++;
71cdf0e10cSrcweir     }
72cdf0e10cSrcweir };
73cdf0e10cSrcweir 
74cdf0e10cSrcweir namespace cppu_ifcontainer
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     class IfTest : public CppUnit::TestFixture
77cdf0e10cSrcweir     {
78cdf0e10cSrcweir         osl::Mutex m_aGuard;
79cdf0e10cSrcweir         static const int nTests = 10;
80cdf0e10cSrcweir     public:
81cdf0e10cSrcweir         void testCreateDispose()
82cdf0e10cSrcweir         {
83cdf0e10cSrcweir             ContainerStats aStats;
84cdf0e10cSrcweir             cppu::OInterfaceContainerHelper *pContainer;
85cdf0e10cSrcweir 
86cdf0e10cSrcweir             pContainer = new cppu::OInterfaceContainerHelper(m_aGuard);
87cdf0e10cSrcweir 
88cdf0e10cSrcweir             CPPUNIT_ASSERT_MESSAGE("Empty container not empty",
89cdf0e10cSrcweir                                    pContainer->getLength() == 0);
90cdf0e10cSrcweir 
91cdf0e10cSrcweir             int i;
92cdf0e10cSrcweir             for (i = 0; i < nTests; i++)
93cdf0e10cSrcweir             {
94cdf0e10cSrcweir                 Reference<XEventListener> xRef = new ContainerListener(&aStats);
95cdf0e10cSrcweir                 int nNewLen = pContainer->addInterface(xRef);
96cdf0e10cSrcweir 
97cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("addition length mismatch",
98cdf0e10cSrcweir                                        nNewLen == i + 1);
99cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("addition length mismatch",
100cdf0e10cSrcweir                                        pContainer->getLength() == i + 1);
101cdf0e10cSrcweir             }
102cdf0e10cSrcweir             CPPUNIT_ASSERT_MESSAGE("alive count mismatch",
103cdf0e10cSrcweir                                    aStats.m_nAlive == nTests);
104cdf0e10cSrcweir 
105cdf0e10cSrcweir             EventObject aObj;
106cdf0e10cSrcweir             pContainer->disposeAndClear(aObj);
107cdf0e10cSrcweir 
108cdf0e10cSrcweir             CPPUNIT_ASSERT_MESSAGE("dispose count mismatch",
109cdf0e10cSrcweir                                    aStats.m_nDisposed == nTests);
110cdf0e10cSrcweir             CPPUNIT_ASSERT_MESSAGE("leaked container left alive",
111cdf0e10cSrcweir                                    aStats.m_nAlive == 0);
112cdf0e10cSrcweir 
113cdf0e10cSrcweir             delete pContainer;
114cdf0e10cSrcweir         }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir         void testEnumerate()
117cdf0e10cSrcweir         {
118cdf0e10cSrcweir             int i;
119cdf0e10cSrcweir             ContainerStats aStats;
120cdf0e10cSrcweir             cppu::OInterfaceContainerHelper *pContainer;
121cdf0e10cSrcweir             pContainer = new cppu::OInterfaceContainerHelper(m_aGuard);
122cdf0e10cSrcweir 
123cdf0e10cSrcweir             std::vector< Reference< XEventListener > > aListeners;
124cdf0e10cSrcweir             for (i = 0; i < nTests; i++)
125cdf0e10cSrcweir             {
126cdf0e10cSrcweir                 Reference<XEventListener> xRef = new ContainerListener(&aStats);
127cdf0e10cSrcweir                 int nNewLen = pContainer->addInterface(xRef);
128cdf0e10cSrcweir                 aListeners.push_back(xRef);
129cdf0e10cSrcweir             }
130cdf0e10cSrcweir             Sequence< Reference< XInterface > > aElements;
131cdf0e10cSrcweir             aElements = pContainer->getElements();
132cdf0e10cSrcweir 
133cdf0e10cSrcweir             CPPUNIT_ASSERT_MESSAGE("query contents",
134cdf0e10cSrcweir                                    (int)aElements.getLength() == nTests);
135cdf0e10cSrcweir             if ((int)aElements.getLength() == nTests)
136cdf0e10cSrcweir             {
137cdf0e10cSrcweir                 for (i = 0; i < nTests; i++)
138cdf0e10cSrcweir                 {
139cdf0e10cSrcweir                     CPPUNIT_ASSERT_MESSAGE("mismatching elements",
140cdf0e10cSrcweir                                            aElements[i] == aListeners[i]);
141cdf0e10cSrcweir                 }
142cdf0e10cSrcweir             }
143cdf0e10cSrcweir             pContainer->clear();
144cdf0e10cSrcweir 
145cdf0e10cSrcweir             CPPUNIT_ASSERT_MESSAGE("non-empty container post clear",
146cdf0e10cSrcweir                                    pContainer->getLength() == 0);
147cdf0e10cSrcweir             delete pContainer;
148cdf0e10cSrcweir         }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir         template < typename ContainerType, typename ContainedType >
151cdf0e10cSrcweir         void doContainerTest(const ContainedType *pTypes)
152cdf0e10cSrcweir         {
153cdf0e10cSrcweir             ContainerStats aStats;
154cdf0e10cSrcweir             ContainerType *pContainer;
155cdf0e10cSrcweir             pContainer = new ContainerType(m_aGuard);
156cdf0e10cSrcweir 
157cdf0e10cSrcweir             int i;
158cdf0e10cSrcweir             Reference<XEventListener> xRefs[nTests * 2];
159cdf0e10cSrcweir 
160cdf0e10cSrcweir             // add these interfaces
161cdf0e10cSrcweir             for (i = 0; i < nTests * 2; i++)
162cdf0e10cSrcweir             {
163cdf0e10cSrcweir                 xRefs[i] = new ContainerListener(&aStats);
164cdf0e10cSrcweir                 pContainer->addInterface(pTypes[i / 2], xRefs[i]);
165cdf0e10cSrcweir             }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir             // check it is all there
168cdf0e10cSrcweir             for (i = 0; i < nTests; i++)
169cdf0e10cSrcweir             {
170cdf0e10cSrcweir                 cppu::OInterfaceContainerHelper *pHelper;
171cdf0e10cSrcweir 
172cdf0e10cSrcweir                 pHelper = pContainer->getContainer(pTypes[i]);
173cdf0e10cSrcweir 
174cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL);
175cdf0e10cSrcweir                 Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
176cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 2);
177cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("match", aSeq[0] == xRefs[i*2]);
178cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("match", aSeq[1] == xRefs[i*2+1]);
179cdf0e10cSrcweir             }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir             // remove every other interface
182cdf0e10cSrcweir             for (i = 0; i < nTests; i++)
183cdf0e10cSrcweir                 pContainer->removeInterface(pTypes[i], xRefs[i*2+1]);
184cdf0e10cSrcweir 
185cdf0e10cSrcweir             // check it is half there
186cdf0e10cSrcweir             for (i = 0; i < nTests; i++)
187cdf0e10cSrcweir             {
188cdf0e10cSrcweir                 cppu::OInterfaceContainerHelper *pHelper;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir                 pHelper = pContainer->getContainer(pTypes[i]);
191cdf0e10cSrcweir 
192cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL);
193cdf0e10cSrcweir                 Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
194cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 1);
195cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("match", aSeq[0] == xRefs[i*2]);
196cdf0e10cSrcweir             }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir             // remove the 1st half of the rest
199cdf0e10cSrcweir             for (i = 0; i < nTests / 2; i++)
200cdf0e10cSrcweir                 pContainer->removeInterface(pTypes[i], xRefs[i*2]);
201cdf0e10cSrcweir 
202cdf0e10cSrcweir             // check it is half there
203cdf0e10cSrcweir             for (i = 0; i < nTests / 2; i++)
204cdf0e10cSrcweir             {
205cdf0e10cSrcweir                 cppu::OInterfaceContainerHelper *pHelper;
206cdf0e10cSrcweir 
207cdf0e10cSrcweir                 pHelper = pContainer->getContainer(pTypes[i]);
208cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("no helper", pHelper != NULL);
209cdf0e10cSrcweir                 Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
210cdf0e10cSrcweir                 CPPUNIT_ASSERT_MESSAGE("wrong num elements", aSeq.getLength() == 0);
211cdf0e10cSrcweir             }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir             delete pContainer;
214cdf0e10cSrcweir         }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir         void testOMultiTypeInterfaceContainerHelper()
217cdf0e10cSrcweir         {
218cdf0e10cSrcweir             uno::Type pTypes[nTests] =
219cdf0e10cSrcweir             {
220cdf0e10cSrcweir                 ::cppu::UnoType< bool >::get(),
221cdf0e10cSrcweir                 ::cppu::UnoType< float >::get(),
222cdf0e10cSrcweir                 ::cppu::UnoType< double >::get(),
223cdf0e10cSrcweir                 ::cppu::UnoType< ::sal_uInt64 >::get(),
224cdf0e10cSrcweir                 ::cppu::UnoType< ::sal_Int64 >::get(),
225cdf0e10cSrcweir                 ::cppu::UnoType< ::sal_uInt32 >::get(),
226cdf0e10cSrcweir                 ::cppu::UnoType< ::sal_Int32 >::get(),
227cdf0e10cSrcweir                 ::cppu::UnoType< ::sal_Int16 >::get(),
228cdf0e10cSrcweir                 ::cppu::UnoType< ::rtl::OUString >::get(),
229cdf0e10cSrcweir                 ::cppu::UnoType< ::sal_Int8 >::get()
230cdf0e10cSrcweir             };
231cdf0e10cSrcweir             doContainerTest< cppu::OMultiTypeInterfaceContainerHelper,
232cdf0e10cSrcweir                 uno::Type> (pTypes);
233cdf0e10cSrcweir         }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir         void testOMultiTypeInterfaceContainerHelperInt32()
236cdf0e10cSrcweir         {
237cdf0e10cSrcweir             sal_Int32 pTypes[nTests] =
238cdf0e10cSrcweir             {
239cdf0e10cSrcweir                 0,
240cdf0e10cSrcweir                 -1,
241cdf0e10cSrcweir                 1,
242cdf0e10cSrcweir                 256,
243cdf0e10cSrcweir                 1024,
244cdf0e10cSrcweir                 3,
245cdf0e10cSrcweir                 7,
246cdf0e10cSrcweir                 8,
247cdf0e10cSrcweir                 9,
248cdf0e10cSrcweir                 10
249cdf0e10cSrcweir             };
250cdf0e10cSrcweir             doContainerTest< cppu::OMultiTypeInterfaceContainerHelperInt32, sal_Int32> (pTypes);
251cdf0e10cSrcweir         }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir         void testOMultiTypeInterfaceContainerHelperVar()
254cdf0e10cSrcweir         {
255cdf0e10cSrcweir             typedef ::cppu::OMultiTypeInterfaceContainerHelperVar<
256cdf0e10cSrcweir                 const char *,hashStr,equalStr> StrContainer;
257cdf0e10cSrcweir 
258cdf0e10cSrcweir             const char *pTypes[nTests] =
259cdf0e10cSrcweir             {
260cdf0e10cSrcweir                 "this_is", "such", "fun", "writing", "unit", "tests", "when", "it", "works", "anyway"
261cdf0e10cSrcweir             };
262cdf0e10cSrcweir             doContainerTest< StrContainer, const char *> (pTypes);
263cdf0e10cSrcweir         }
264cdf0e10cSrcweir 
265cdf0e10cSrcweir         // Automatic registration code
266cdf0e10cSrcweir         CPPUNIT_TEST_SUITE(IfTest);
267cdf0e10cSrcweir         CPPUNIT_TEST(testCreateDispose);
268cdf0e10cSrcweir         CPPUNIT_TEST(testEnumerate);
269cdf0e10cSrcweir         CPPUNIT_TEST(testOMultiTypeInterfaceContainerHelper);
270cdf0e10cSrcweir         CPPUNIT_TEST(testOMultiTypeInterfaceContainerHelperVar);
271cdf0e10cSrcweir         CPPUNIT_TEST(testOMultiTypeInterfaceContainerHelperInt32);
272cdf0e10cSrcweir         CPPUNIT_TEST_SUITE_END();
273cdf0e10cSrcweir     };
274cdf0e10cSrcweir } // namespace cppu_ifcontainer
275cdf0e10cSrcweir 
276cdf0e10cSrcweir CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(cppu_ifcontainer::IfTest,
277cdf0e10cSrcweir                                       "cppu_ifcontainer");
278cdf0e10cSrcweir 
279cdf0e10cSrcweir NOADDITIONAL;
280