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