Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License or as specified alternatively below. You may obtain a copy of
8 : * the License at http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * Major Contributor(s):
16 : * Copyright (C) 2012 Kohei Yoshida <kohei.yoshida@suse.com>
17 : *
18 : * All Rights Reserved.
19 : *
20 : * For minor contributions see the git repository.
21 : *
22 : * Alternatively, the contents of this file may be used under the terms of
23 : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : * instead of those above.
27 : */
28 :
29 : #include "test/beans/xpropertyset.hxx"
30 : #include "cppunit/extensions/HelperMacros.h"
31 :
32 : #include <com/sun/star/uno/Type.h>
33 : #include <com/sun/star/beans/PropertyAttribute.hpp>
34 : #include <com/sun/star/util/DateTime.hpp>
35 :
36 : #include <set>
37 :
38 : using namespace com::sun::star::uno;
39 :
40 : namespace apitest {
41 :
42 0 : XPropertySet::~XPropertySet() {}
43 :
44 0 : XPropertySet::PropsToTest::PropsToTest() : initialized(false) {}
45 :
46 0 : void XPropertySet::testGetPropertySetInfo()
47 : {
48 0 : uno::Reference<beans::XPropertySet> xPropSet(init(), UNO_QUERY_THROW);
49 0 : uno::Reference<beans::XPropertySetInfo> xPropInfo = xPropSet->getPropertySetInfo();
50 0 : if (xPropInfo.is())
51 : {
52 0 : fillPropsToTest(xPropInfo);
53 : }
54 : else
55 : {
56 : // TODO: Add a means for the client code to populate the PropsToTest.
57 0 : }
58 0 : }
59 :
60 0 : void XPropertySet::testAddPropertyChangeListener()
61 : {
62 : // TODO: implement this.
63 0 : }
64 :
65 0 : void XPropertySet::testAddVetoableChangeListener()
66 : {
67 : // TODO: implement this.
68 0 : }
69 :
70 0 : void XPropertySet::testSetPropertyValue()
71 : {
72 0 : testGetPropertySetInfo();
73 :
74 0 : for (size_t i = 0, n = maPropsToTest.normal.size(); i < n; ++i)
75 : {
76 0 : bool bSuccess = isPropertyValueChangeable(maPropsToTest.normal[i]);
77 0 : CPPUNIT_ASSERT(bSuccess);
78 : }
79 0 : }
80 :
81 0 : void XPropertySet::testGetPropertyValue()
82 : {
83 0 : testGetPropertySetInfo();
84 0 : uno::Reference<beans::XPropertySet> xPropSet(init(), UNO_QUERY_THROW);
85 :
86 : // Check read-only properties.
87 0 : for (size_t i = 0, n = maPropsToTest.readonly.size(); i < n; ++i)
88 : {
89 0 : bool bSuccess = getSinglePropertyValue(xPropSet, maPropsToTest.readonly[i]);
90 0 : CPPUNIT_ASSERT(bSuccess);
91 : }
92 :
93 : // Check writable properties.
94 0 : for (size_t i = 0, n = maPropsToTest.normal.size(); i < n; ++i)
95 : {
96 0 : bool bSuccess = getSinglePropertyValue(xPropSet, maPropsToTest.normal[i]);
97 0 : CPPUNIT_ASSERT(bSuccess);
98 0 : }
99 0 : }
100 :
101 0 : void XPropertySet::testRemovePropertyChangeListener()
102 : {
103 : // TODO: implement this.
104 0 : }
105 :
106 0 : void XPropertySet::testRemoveVetoableChangeListener()
107 : {
108 : // TODO: implement this.
109 0 : }
110 :
111 0 : bool XPropertySet::isPropertyValueChangeable(const rtl::OUString& rName)
112 : {
113 0 : uno::Reference<beans::XPropertySet> xPropSet(init(), UNO_QUERY_THROW);
114 : try
115 : {
116 0 : uno::Any any = xPropSet->getPropertyValue(rName);
117 0 : uno::Type type = any.getValueType();
118 0 : if (type == getCppuType<sal_Bool>())
119 : {
120 : // boolean type
121 0 : sal_Bool bOld = any.get<sal_Bool>();
122 0 : xPropSet->setPropertyValue(rName, makeAny(!bOld));
123 : }
124 0 : else if (type == getCppuType<sal_Int8>())
125 : {
126 : // 8-bit integer
127 0 : sal_Int8 nOld = any.get<sal_Int8>();
128 0 : sal_Int8 nNew = nOld + 1;
129 0 : xPropSet->setPropertyValue(rName, makeAny(nNew));
130 : }
131 0 : else if (type == getCppuType<sal_Int16>())
132 : {
133 : // 16-bit integer
134 0 : sal_Int16 nOld = any.get<sal_Int16>();
135 0 : sal_Int16 nNew = nOld + 2;
136 0 : xPropSet->setPropertyValue(rName, makeAny(nNew));
137 : }
138 0 : else if (type == getCppuType<sal_Int32>())
139 : {
140 : // 32-bit integer
141 0 : sal_Int32 nOld = any.get<sal_Int32>();
142 0 : sal_Int32 nNew = nOld + 3;
143 0 : xPropSet->setPropertyValue(rName, makeAny(nNew));
144 : }
145 0 : else if (type == getCppuType<sal_Int64>())
146 : {
147 : // 64-bit integer
148 0 : sal_Int64 nOld = any.get<sal_Int64>();
149 0 : sal_Int64 nNew = nOld + 4;
150 0 : xPropSet->setPropertyValue(rName, makeAny(nNew));
151 : }
152 0 : else if (type == getCppuType<float>())
153 : {
154 : // single precision
155 0 : float fOld = any.get<float>();
156 0 : float fNew = fOld + 1.2;
157 0 : xPropSet->setPropertyValue(rName, makeAny(fNew));
158 : }
159 0 : else if (type == getCppuType<double>())
160 : {
161 : // double precision
162 0 : double fOld = any.get<double>();
163 0 : double fNew = fOld + 1.3;
164 0 : xPropSet->setPropertyValue(rName, makeAny(fNew));
165 : }
166 0 : else if (type == getCppuType<rtl::OUString>())
167 : {
168 : // string type
169 0 : rtl::OUString aOld = any.get<rtl::OUString>();
170 0 : rtl::OUString aNew = aOld + rtl::OUString("foo");
171 0 : xPropSet->setPropertyValue(rName, makeAny(aNew));
172 : }
173 0 : else if (type == getCppuType<util::DateTime>())
174 : {
175 : // date time type
176 0 : util::DateTime aDT = any.get<util::DateTime>();
177 0 : aDT.Year += 1;
178 0 : xPropSet->setPropertyValue(rName, makeAny(aDT));
179 : }
180 : else
181 : {
182 0 : CPPUNIT_ASSERT_MESSAGE("XPropertySet::isChangeable: unknown type in Any tested.", false);
183 : }
184 :
185 0 : uno::Any anyTest = xPropSet->getPropertyValue(rName);
186 0 : return any != anyTest;
187 : }
188 0 : catch (const uno::Exception&)
189 : {
190 0 : CPPUNIT_ASSERT_MESSAGE("XPropertySet::isChangeable: exception thrown while retrieving the property value.", false);
191 : }
192 :
193 0 : return false;
194 : }
195 :
196 0 : void XPropertySet::fillPropsToTest(const uno::Reference<beans::XPropertySetInfo>& xPropInfo)
197 : {
198 0 : if (maPropsToTest.initialized)
199 0 : return;
200 :
201 0 : uno::Sequence<beans::Property> aProps = xPropInfo->getProperties();
202 :
203 : // some properties should not be changed in a unspecific way.
204 : // TODO: Maybe we should mark these properties read-only, instead of
205 : // giving them a special treatment here?
206 0 : std::set<rtl::OUString> aSkip;
207 0 : aSkip.insert("PrinterName");
208 0 : aSkip.insert("CharRelief");
209 0 : aSkip.insert("IsLayerMode");
210 :
211 0 : for (sal_Int32 i = 0; i < aProps.getLength(); ++i)
212 : {
213 0 : beans::Property aProp = aProps[i];
214 0 : if (aSkip.count(aProp.Name) > 0)
215 0 : continue;
216 :
217 0 : if ((aProp.Attributes & beans::PropertyAttribute::READONLY) != 0)
218 : {
219 0 : maPropsToTest.readonly.push_back(aProp.Name);
220 0 : continue;
221 : }
222 :
223 0 : if ((aProp.Attributes & beans::PropertyAttribute::MAYBEVOID) != 0)
224 0 : continue;
225 :
226 0 : bool bBound = (aProp.Attributes & beans::PropertyAttribute::BOUND) != 0;
227 0 : bool bConstrained = (aProp.Attributes & beans::PropertyAttribute::CONSTRAINED) != 0;
228 0 : bool bCanChange = isPropertyValueChangeable(aProp.Name);
229 :
230 0 : if (bBound && bCanChange)
231 0 : maPropsToTest.bound.push_back(aProp.Name);
232 :
233 0 : if (bConstrained && bCanChange)
234 0 : maPropsToTest.constrained.push_back(aProp.Name);
235 :
236 0 : if (bCanChange)
237 0 : maPropsToTest.normal.push_back(aProp.Name);
238 0 : }
239 :
240 0 : maPropsToTest.initialized = true;
241 : }
242 :
243 0 : bool XPropertySet::getSinglePropertyValue(
244 : const uno::Reference<beans::XPropertySet>& xPropSet, const rtl::OUString& rName)
245 : {
246 : try
247 : {
248 0 : xPropSet->getPropertyValue(rName);
249 0 : return true;
250 : }
251 0 : catch (const uno::Exception&)
252 : {
253 : }
254 0 : return false;
255 : }
256 :
257 0 : }
258 :
259 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|