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