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