xref: /aoo41x/main/sal/qa/systools/test_comtools.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_sal.hxx"
31 // autogenerated file with codegen.pl
32 
33 #include <testshl/simpleheader.hxx>
34 #include <systools/win32/comtools.hxx>
35 
36 class COMObject : public IUnknown
37 {
38 public:
39     COMObject() : ref_count_(0)
40     {
41     }
42 
43     ~COMObject()
44     {
45     }
46 
47     ULONG __stdcall AddRef()
48     {
49         ref_count_++;
50         return ref_count_;
51     }
52 
53     ULONG __stdcall Release()
54     {
55         ULONG cnt = --ref_count_;
56         if (cnt == 0)
57             delete this;
58         return cnt;
59     }
60 
61     HRESULT __stdcall QueryInterface(REFIID riid, LPVOID* ppv)
62     {
63         if (riid == IID_IUnknown)
64         {
65             AddRef();
66             *ppv = this;
67             return S_OK;
68         }
69         return E_NOINTERFACE;
70     }
71 
72     ULONG GetRefCount() const
73     {
74         return ref_count_;
75     }
76 
77 private:
78     ULONG ref_count_;
79 };
80 
81 sal::systools::COMReference<IUnknown> comObjectSource()
82 {
83     return sal::systools::COMReference<IUnknown>(new COMObject);
84 }
85 
86 bool comObjectSink(sal::systools::COMReference<IUnknown> r, ULONG expectedRefCountOnReturn)
87 {
88     r = sal::systools::COMReference<IUnknown>();
89     COMObject* p = reinterpret_cast<COMObject*>(r.get());
90     if (p)
91         return (p->GetRefCount() == expectedRefCountOnReturn);
92     else
93         return (0 == expectedRefCountOnReturn);
94 }
95 
96 void comObjectSource2(LPVOID* ppv)
97 {
98     COMObject* p = new COMObject;
99     p->AddRef();
100     *ppv = p;
101 }
102 
103 namespace test_comtools
104 {
105 
106     class test_COMReference : public CppUnit::TestFixture
107     {
108 
109     public:
110         /// test of COMReference<IUnknown> r;
111         void default_ctor()
112         {
113             sal::systools::COMReference<IUnknown> r;
114             CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() == NULL);
115         }
116 
117         void test_ctor_manual_AddRef()
118         {
119             COMObject* p = new COMObject;
120             p->AddRef();
121             sal::systools::COMReference<IUnknown> r(p, false);
122             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1);
123         }
124 
125         void test_copy_ctor()
126         {
127             sal::systools::COMReference<IUnknown> r(comObjectSource());
128             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1);
129         }
130 
131         void test_copy_assignment()
132         {
133             sal::systools::COMReference<IUnknown> r;
134             CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() == NULL);
135 
136             r = comObjectSource();
137             CPPUNIT_ASSERT_MESSAGE("COMReference should be empty", r.get() != NULL);
138             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1);
139         }
140 
141         void test_ref_to_ref_assignment()
142         {
143             sal::systools::COMReference<IUnknown> r1 = comObjectSource();
144             sal::systools::COMReference<IUnknown> r2 = r1;
145             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2);
146         }
147 
148         void test_pointer_to_ref_assignment()
149         {
150             sal::systools::COMReference<IUnknown> r;
151             r = new COMObject;
152             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1);
153         }
154 
155         void test_pointer_to_ref_assignment2()
156         {
157             sal::systools::COMReference<IUnknown> r = comObjectSource();
158             r = new COMObject;
159             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1);
160         }
161 
162         void test_source_sink()
163         {
164             CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 0 is expected", comObjectSink(comObjectSource(), 0));
165         }
166 
167         void test_address_operator()
168         {
169             sal::systools::COMReference<IUnknown> r;
170             comObjectSource2(reinterpret_cast<LPVOID*>(&r));
171             CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1);
172         }
173 
174         void test_address_operator2()
175         {
176             sal::systools::COMReference<IUnknown> r1 = comObjectSource();
177             sal::systools::COMReference<IUnknown> r2 = r1;
178             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2);
179             comObjectSource2(reinterpret_cast<LPVOID*>(&r1));
180             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r1.get())->GetRefCount() == 1);
181             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 1);
182         }
183 
184         void test_clear()
185         {
186             sal::systools::COMReference<IUnknown> r = comObjectSource();
187             CPPUNIT_ASSERT_MESSAGE("Wrong reference count 1 is expected", reinterpret_cast<COMObject*>(r.get())->GetRefCount() == 1);
188             r.clear();
189             CPPUNIT_ASSERT_MESSAGE("Expect reference to be empty", !r.is());
190         }
191 
192         void test_query_interface()
193         {
194             try
195             {
196                 sal::systools::COMReference<IUnknown> r1 = comObjectSource();
197                 sal::systools::COMReference<IUnknown> r2 = r1.QueryInterface<IUnknown>(IID_IUnknown);
198                 CPPUNIT_ASSERT_MESSAGE("Wrong reference count, 2 is expected", reinterpret_cast<COMObject*>(r2.get())->GetRefCount() == 2);
199             }
200             catch(sal::systools::ComError& ex)
201             {
202                 CPPUNIT_ASSERT_MESSAGE("Exception should not have been thrown", false);
203             }
204         }
205 
206         void test_query_interface_throw()
207         {
208             try
209             {
210                 sal::systools::COMReference<IUnknown> r1 = comObjectSource();
211                 sal::systools::COMReference<IPersistFile> r2 = r1.QueryInterface<IPersistFile>(IID_IPersistFile);
212             }
213             catch(sal::systools::ComError& ex)
214             {
215                 return;
216             }
217             CPPUNIT_ASSERT_MESSAGE("Exception should have been thrown", false);
218         }
219 
220         // Change the following lines only, if you add, remove or rename
221         // member functions of the current class,
222         // because these macros are need by auto register mechanism.
223 
224         CPPUNIT_TEST_SUITE(test_COMReference);
225         CPPUNIT_TEST(default_ctor);
226         CPPUNIT_TEST(test_ctor_manual_AddRef);
227         CPPUNIT_TEST(test_copy_ctor);
228         CPPUNIT_TEST(test_copy_assignment);
229         CPPUNIT_TEST(test_ref_to_ref_assignment);
230         CPPUNIT_TEST(test_pointer_to_ref_assignment);
231         CPPUNIT_TEST(test_pointer_to_ref_assignment2);
232         CPPUNIT_TEST(test_source_sink);
233         CPPUNIT_TEST(test_address_operator);
234         CPPUNIT_TEST(test_address_operator2);
235         CPPUNIT_TEST(test_clear);
236         CPPUNIT_TEST(test_query_interface);
237         CPPUNIT_TEST(test_query_interface_throw);
238         CPPUNIT_TEST_SUITE_END();
239     };
240 
241 // -----------------------------------------------------------------------------
242 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_comtools::test_COMReference, "test_comtools");
243 
244 } // namespace rtl_OUString
245 
246 
247 // this macro creates an empty function, which will called by the RegisterAllFunctions()
248 // to let the user the possibility to also register some functions by hand.
249 NOADDITIONAL;
250 
251