/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include "precompiled_cppuhelper.hxx" #include "com/sun/star/lang/XEventListener.hpp" #include "cppuhelper/interfacecontainer.hxx" #include "cppuhelper/queryinterface.hxx" #include "cppuhelper/implbase1.hxx" #include "cppuhelper/propshlp.hxx" #include "gtest/gtest.h" using namespace com::sun::star; using namespace com::sun::star::uno; using namespace com::sun::star::lang; class ContainerListener; struct ContainerStats { int m_nAlive; int m_nDisposed; ContainerStats() : m_nAlive(0), m_nDisposed(0) {} }; class ContainerListener : public ::cppu::WeakImplHelper1< XEventListener > { ContainerStats *m_pStats; public: ContainerListener(ContainerStats *pStats) : m_pStats(pStats) { m_pStats->m_nAlive++; } virtual ~ContainerListener() { m_pStats->m_nAlive--; } virtual void SAL_CALL disposing( const EventObject& ) throw (RuntimeException) { m_pStats->m_nDisposed++; } }; namespace cppu_ifcontainer { class IfTest : public ::testing::Test { protected: osl::Mutex m_aGuard; static const int nTests = 10; public: template < typename ContainerType, typename ContainedType > void doContainerTest(const ContainedType *pTypes) { ContainerStats aStats; ContainerType *pContainer; pContainer = new ContainerType(m_aGuard); int i; Reference xRefs[nTests * 2]; // add these interfaces for (i = 0; i < nTests * 2; i++) { xRefs[i] = new ContainerListener(&aStats); pContainer->addInterface(pTypes[i / 2], xRefs[i]); } // check it is all there for (i = 0; i < nTests; i++) { cppu::OInterfaceContainerHelper *pHelper; pHelper = pContainer->getContainer(pTypes[i]); ASSERT_TRUE(pHelper != NULL) << "no helper"; Sequence > aSeq = pHelper->getElements(); ASSERT_TRUE(aSeq.getLength() == 2) << "wrong num elements"; ASSERT_TRUE(aSeq[0] == xRefs[i*2]) << "match"; ASSERT_TRUE(aSeq[1] == xRefs[i*2+1]) << "match"; } // remove every other interface for (i = 0; i < nTests; i++) pContainer->removeInterface(pTypes[i], xRefs[i*2+1]); // check it is half there for (i = 0; i < nTests; i++) { cppu::OInterfaceContainerHelper *pHelper; pHelper = pContainer->getContainer(pTypes[i]); ASSERT_TRUE(pHelper != NULL) << "no helper"; Sequence > aSeq = pHelper->getElements(); ASSERT_TRUE(aSeq.getLength() == 1) << "wrong num elements"; ASSERT_TRUE(aSeq[0] == xRefs[i*2]) << "match"; } // remove the 1st half of the rest for (i = 0; i < nTests / 2; i++) pContainer->removeInterface(pTypes[i], xRefs[i*2]); // check it is half there for (i = 0; i < nTests / 2; i++) { cppu::OInterfaceContainerHelper *pHelper; pHelper = pContainer->getContainer(pTypes[i]); ASSERT_TRUE(pHelper != NULL) << "no helper"; Sequence > aSeq = pHelper->getElements(); ASSERT_TRUE(aSeq.getLength() == 0) << "wrong num elements"; } delete pContainer; } }; TEST_F(IfTest, testCreateDispose) { ContainerStats aStats; cppu::OInterfaceContainerHelper *pContainer; pContainer = new cppu::OInterfaceContainerHelper(m_aGuard); ASSERT_TRUE(pContainer->getLength() == 0) << "Empty container not empty"; int i; for (i = 0; i < nTests; i++) { Reference xRef = new ContainerListener(&aStats); int nNewLen = pContainer->addInterface(xRef); ASSERT_TRUE(nNewLen == i + 1) << "addition length mismatch"; ASSERT_TRUE(pContainer->getLength() == i + 1) << "addition length mismatch"; } ASSERT_TRUE(aStats.m_nAlive == nTests) << "alive count mismatch"; EventObject aObj; pContainer->disposeAndClear(aObj); ASSERT_TRUE(aStats.m_nDisposed == nTests) << "dispose count mismatch"; ASSERT_TRUE(aStats.m_nAlive == 0) << "leaked container left alive"; delete pContainer; } TEST_F(IfTest, testEnumerate) { int i; ContainerStats aStats; cppu::OInterfaceContainerHelper *pContainer; pContainer = new cppu::OInterfaceContainerHelper(m_aGuard); std::vector< Reference< XEventListener > > aListeners; for (i = 0; i < nTests; i++) { Reference xRef = new ContainerListener(&aStats); pContainer->addInterface(xRef); aListeners.push_back(xRef); } Sequence< Reference< XInterface > > aElements; aElements = pContainer->getElements(); ASSERT_TRUE((int)aElements.getLength() == nTests) << "query contents"; if ((int)aElements.getLength() == nTests) { for (i = 0; i < nTests; i++) { ASSERT_TRUE(aElements[i] == aListeners[i]) << "mismatching elements"; } } pContainer->clear(); ASSERT_TRUE(pContainer->getLength() == 0) << "non-empty container post clear"; delete pContainer; } TEST_F(IfTest, testOMultiTypeInterfaceContainerHelper) { uno::Type pTypes[nTests] = { ::cppu::UnoType< bool >::get(), ::cppu::UnoType< float >::get(), ::cppu::UnoType< double >::get(), ::cppu::UnoType< ::sal_uInt64 >::get(), ::cppu::UnoType< ::sal_Int64 >::get(), ::cppu::UnoType< ::sal_uInt32 >::get(), ::cppu::UnoType< ::sal_Int32 >::get(), ::cppu::UnoType< ::sal_Int16 >::get(), ::cppu::UnoType< ::rtl::OUString >::get(), ::cppu::UnoType< ::sal_Int8 >::get() }; doContainerTest< cppu::OMultiTypeInterfaceContainerHelper, uno::Type> (pTypes); } TEST_F(IfTest, testOMultiTypeInterfaceContainerHelperInt32) { sal_Int32 pTypes[nTests] = { 0, -1, 1, 256, 1024, 3, 7, 8, 9, 10 }; doContainerTest< cppu::OMultiTypeInterfaceContainerHelperInt32, sal_Int32> (pTypes); } TEST_F(IfTest, testOMultiTypeInterfaceContainerHelperVar) { typedef ::cppu::OMultiTypeInterfaceContainerHelperVar< const char*, rtl::CStringHash, rtl::CStringEqual> StrContainer; const char *pTypes[nTests] = { "this_is", "such", "fun", "writing", "unit", "tests", "when", "it", "works", "anyway" }; doContainerTest< StrContainer, const char *> (pTypes); } } // namespace cppu_ifcontainer