calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / configmgr / qa / unit / test.cxx
blob7aa2daf6f96dfb729639d09050372a97d57f89d6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <com/sun/star/beans/NamedValue.hpp>
23 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
24 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/beans/XPropertyState.hpp>
27 #include <com/sun/star/configuration/ReadOnlyAccess.hpp>
28 #include <com/sun/star/configuration/theDefaultProvider.hpp>
29 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <com/sun/star/container/XNameReplace.hpp>
32 #include <com/sun/star/container/XNamed.hpp>
33 #include <com/sun/star/lang/EventObject.hpp>
34 #include <com/sun/star/lang/XComponent.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
37 #include <com/sun/star/uno/Any.hxx>
38 #include <com/sun/star/uno/Reference.hxx>
39 #include <com/sun/star/uno/Sequence.hxx>
40 #include <com/sun/star/uno/XInterface.hpp>
41 #include <com/sun/star/util/XChangesBatch.hpp>
42 #include <cppuhelper/implbase.hxx>
43 #include <osl/time.h>
44 #include <rtl/ref.hxx>
45 #include <rtl/ustring.hxx>
46 #include <sal/types.h>
47 #include <comphelper/processfactory.hxx>
48 #include <comphelper/configuration.hxx>
49 #include <comphelper/configurationlistener.hxx>
50 #include <cppunit/TestAssert.h>
51 #include <cppunit/TestFixture.h>
52 #include <cppunit/extensions/HelperMacros.h>
53 #include <cppunit/plugin/TestPlugIn.h>
54 #include <officecfg/Office/Math.hxx>
56 namespace {
58 class Test: public CppUnit::TestFixture {
59 public:
60 virtual void setUp() override;
62 void testKeyFetch();
63 void testKeySet();
64 void testKeyReset();
65 void testSetSetMemberName();
66 void testInsertSetMember();
67 void testLocalizedProperty();
68 void testReadCommands();
69 void testListener();
70 void testRecursive();
71 void testCrossThreads();
73 css::uno::Any getKey(
74 OUString const & path, OUString const & relative) const;
76 void setKey(
77 OUString const & path, OUString const & name,
78 css::uno::Any const & value) const;
80 bool resetKey(OUString const & path, OUString const & name) const;
82 css::uno::Reference< css::uno::XInterface > createViewAccess(
83 OUString const & path) const;
85 css::uno::Reference< css::uno::XInterface > createUpdateAccess(
86 OUString const & path) const;
88 CPPUNIT_TEST_SUITE(Test);
89 CPPUNIT_TEST(testKeyFetch);
90 CPPUNIT_TEST(testKeySet);
91 CPPUNIT_TEST(testKeyReset);
92 CPPUNIT_TEST(testSetSetMemberName);
93 CPPUNIT_TEST(testInsertSetMember);
94 CPPUNIT_TEST(testLocalizedProperty);
95 CPPUNIT_TEST(testReadCommands);
96 CPPUNIT_TEST(testListener);
97 CPPUNIT_TEST(testRecursive);
98 CPPUNIT_TEST(testCrossThreads);
99 CPPUNIT_TEST_SUITE_END();
101 private:
102 css::uno::Reference< css::lang::XMultiServiceFactory > provider_;
105 class RecursiveTest:
106 public cppu::WeakImplHelper< css::beans::XPropertyChangeListener >
108 public:
109 RecursiveTest(Test const & theTest, int count, bool * destroyed);
111 void test();
113 protected:
114 virtual ~RecursiveTest() override;
116 virtual void step() const = 0;
118 Test const & test_;
120 private:
121 virtual void SAL_CALL disposing(css::lang::EventObject const &) override;
123 virtual void SAL_CALL propertyChange(
124 css::beans::PropertyChangeEvent const &) override;
126 int count_;
127 bool * destroyed_;
128 css::uno::Reference< css::beans::XPropertySet > properties_;
131 RecursiveTest::RecursiveTest(
132 Test const & theTest, int count, bool * destroyed):
133 test_(theTest), count_(count), destroyed_(destroyed)
136 void RecursiveTest::test()
138 properties_.set(
139 test_.createUpdateAccess(
140 "/org.openoffice.Office.UI.GenericCommands/UserInterface/Commands/"
141 ".uno:WebHtml"),
142 css::uno::UNO_QUERY_THROW);
143 properties_->addPropertyChangeListener("Label", this);
144 step();
145 CPPUNIT_ASSERT_EQUAL(0, count_);
146 css::uno::Reference< css::lang::XComponent >(
147 properties_, css::uno::UNO_QUERY_THROW)->dispose();
150 RecursiveTest::~RecursiveTest()
152 *destroyed_ = true;
155 void RecursiveTest::disposing(css::lang::EventObject const & Source)
157 CPPUNIT_ASSERT(properties_.is());
158 CPPUNIT_ASSERT_EQUAL(
159 css::uno::Reference<css::uno::XInterface>(
160 properties_, css::uno::UNO_QUERY_THROW),
161 Source.Source);
162 properties_.clear();
165 void RecursiveTest::propertyChange(css::beans::PropertyChangeEvent const & evt)
167 CPPUNIT_ASSERT_EQUAL(
168 css::uno::Reference<css::uno::XInterface>(
169 properties_, css::uno::UNO_QUERY_THROW),
170 evt.Source);
171 CPPUNIT_ASSERT_EQUAL( OUString("Label"), evt.PropertyName );
172 if (count_ > 0) {
173 --count_;
174 step();
178 class SimpleRecursiveTest: public RecursiveTest {
179 public:
180 SimpleRecursiveTest(Test const & theTest, int count, bool * destroyed);
182 private:
183 virtual void step() const override;
186 SimpleRecursiveTest::SimpleRecursiveTest(
187 Test const & theTest, int count, bool * destroyed):
188 RecursiveTest(theTest, count, destroyed)
191 void SimpleRecursiveTest::step() const
193 test_.setKey(
194 "/org.openoffice.Office.UI.GenericCommands/UserInterface/Commands/"
195 ".uno:WebHtml",
196 "Label",
197 css::uno::Any(OUString("step")));
200 void Test::setUp()
202 provider_ = css::configuration::theDefaultProvider::get(
203 comphelper::getProcessComponentContext() );
206 void Test::testKeyFetch()
208 OUString s;
209 CPPUNIT_ASSERT(
210 getKey(
211 "/org.openoffice.System",
212 "L10N/Locale") >>=
216 void Test::testKeySet()
218 setKey(
219 "/org.openoffice.System/L10N",
220 "Locale",
221 css::uno::Any(OUString("com.sun.star.configuration.backend.LocaleBackend UILocale")));
222 OUString s;
223 CPPUNIT_ASSERT(
224 getKey(
225 "/org.openoffice.System/L10N",
226 "Locale") >>=
228 CPPUNIT_ASSERT_EQUAL( OUString("com.sun.star.configuration.backend.LocaleBackend UILocale"), s );
231 void Test::testKeyReset()
233 if (resetKey(
234 "/org.openoffice.System/L10N",
235 "Locale"))
237 OUString s;
238 CPPUNIT_ASSERT(
239 getKey(
240 "/org.openoffice.System/L10N",
241 "Locale") >>=
243 CPPUNIT_ASSERT_EQUAL( OUString("com.sun.star.configuration.backend.LocaleBackend Locale"), s );
247 void Test::testSetSetMemberName()
249 OUString s;
250 CPPUNIT_ASSERT(
251 getKey(
252 "/org.openoffice.Office.UI.GenericCommands/UserInterface/Commands/"
253 ".uno:FontworkShapeType",
254 "Label") >>=
256 CPPUNIT_ASSERT_EQUAL( OUString("Fontwork Shape"), s );
258 css::uno::Reference< css::container::XNameAccess > access(
259 createUpdateAccess(
260 "/org.openoffice.Office.UI.GenericCommands/UserInterface/"
261 "Commands"),
262 css::uno::UNO_QUERY_THROW);
263 css::uno::Reference< css::container::XNamed > member;
264 access->getByName(".uno:FontworkGalleryFloater") >>= member;
265 CPPUNIT_ASSERT(member.is());
266 member->setName(".uno:FontworkShapeType");
267 css::uno::Reference< css::util::XChangesBatch >(
268 access, css::uno::UNO_QUERY_THROW)->commitChanges();
269 css::uno::Reference< css::lang::XComponent >(
270 access, css::uno::UNO_QUERY_THROW)->dispose();
272 CPPUNIT_ASSERT(
273 getKey(
274 "/org.openoffice.Office.UI.GenericCommands/UserInterface/Commands/"
275 ".uno:FontworkShapeType",
276 "Label") >>=
278 CPPUNIT_ASSERT_EQUAL( OUString("Insert Fontwork"), s );
281 void Test::testInsertSetMember() {
282 css::uno::Reference<css::container::XNameContainer> access(
283 createUpdateAccess(
284 "/org.openoffice.Office.UI.GenericCommands/UserInterface/Commands"),
285 css::uno::UNO_QUERY_THROW);
286 css::uno::Reference<css::uno::XInterface> member;
287 member.set(
288 css::uno::Reference<css::lang::XSingleServiceFactory>(
289 access, css::uno::UNO_QUERY_THROW)->createInstance());
290 CPPUNIT_ASSERT(member.is());
291 access->insertByName("A", css::uno::Any(member));
292 member.set(
293 css::uno::Reference<css::lang::XSingleServiceFactory>(
294 access, css::uno::UNO_QUERY_THROW)->createInstance());
295 CPPUNIT_ASSERT(member.is());
296 try {
297 access->insertByName("", css::uno::Any(member));
298 CPPUNIT_FAIL("expected IllegalArgumentException");
299 } catch (css::lang::IllegalArgumentException &) {}
300 try {
301 access->insertByName("\x01", css::uno::Any(member));
302 CPPUNIT_FAIL("expected IllegalArgumentException");
303 } catch (css::lang::IllegalArgumentException &) {}
304 try {
305 access->insertByName("a/b", css::uno::Any(member));
306 } catch (css::lang::IllegalArgumentException &) {
307 CPPUNIT_FAIL("unexpected IllegalArgumentException");
309 css::uno::Reference<css::util::XChangesBatch>(
310 access, css::uno::UNO_QUERY_THROW)->commitChanges();
311 css::uno::Reference<css::lang::XComponent>(
312 access, css::uno::UNO_QUERY_THROW)->dispose();
315 void Test::testLocalizedProperty() {
316 auto const access = css::configuration::ReadOnlyAccess::create(
317 comphelper::getProcessComponentContext(), "*");
319 // See <https://bugs.documentfoundation.org/show_bug.cgi?id=33638> "Pagination extension
320 // not localized in LibreOffice", which wants to retrieve the non-canonical xml:lang="pt-PT"
321 // value for the passed-in "pt" locale:
322 OUString v;
323 CPPUNIT_ASSERT(
324 access->getByHierarchicalName("/org.libreoffice.unittest/localized/*pt") >>= v);
325 CPPUNIT_ASSERT_EQUAL(OUString("pt-PT"), v);
328 // Make sure a degenerate passed-in "-" locale is handled gracefully:
329 OUString v;
330 CPPUNIT_ASSERT(
331 access->getByHierarchicalName("/org.libreoffice.unittest/localized/*-") >>= v);
332 CPPUNIT_ASSERT_EQUAL(OUString("default"), v);
336 void Test::testReadCommands()
338 css::uno::Reference< css::container::XNameAccess > access(
339 createViewAccess(
340 "/org.openoffice.Office.UI.GenericCommands/UserInterface/"
341 "Commands"),
342 css::uno::UNO_QUERY_THROW);
343 const css::uno::Sequence< OUString > names(access->getElementNames());
345 /*CPPUNIT_ASSERT_EQUAL(749, names.getLength());*/
346 // testSetSetMemberName() already removed ".uno:FontworkGalleryFloater"
347 sal_uInt32 n = osl_getGlobalTimer();
348 for (int i = 0; i < 8; ++i) {
349 for (OUString const & childName : names) {
350 css::uno::Reference< css::container::XNameAccess > child;
351 if (access->getByName(childName) >>= child) {
352 CPPUNIT_ASSERT(child.is());
353 child->getByName("Label");
354 child->getByName("ContextLabel");
355 child->getByName("Properties");
359 n = osl_getGlobalTimer() - n;
360 printf("Reading elements took %" SAL_PRIuUINT32 " ms\n", n);
361 css::uno::Reference< css::lang::XComponent >(
362 access, css::uno::UNO_QUERY_THROW)->dispose();
365 void Test::testListener()
367 OUString aRandomPath = "/org.openoffice.Office.Math/View";
369 // test with no props.
371 rtl::Reference xListener(
372 new comphelper::ConfigurationListener(aRandomPath));
373 xListener->dispose();
376 // test some changes
378 rtl::Reference xListener(
379 new comphelper::ConfigurationListener(aRandomPath));
381 comphelper::ConfigurationListenerProperty<bool> aSetting(xListener, "AutoRedraw");
382 CPPUNIT_ASSERT_MESSAGE("check AutoRedraw defaults to true", aSetting.get());
384 // set to false
386 std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
387 comphelper::ConfigurationChanges::create());
388 officecfg::Office::Math::View::AutoRedraw::set(false, xChanges);
389 xChanges->commit();
391 CPPUNIT_ASSERT_MESSAGE("listener failed to trigger", !aSetting.get());
393 // set to true
395 std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
396 comphelper::ConfigurationChanges::create());
397 officecfg::Office::Math::View::AutoRedraw::set(true, xChanges);
398 xChanges->commit();
400 CPPUNIT_ASSERT_MESSAGE("listener failed to trigger", aSetting.get());
402 xListener->dispose();
406 void Test::testRecursive()
408 bool destroyed = false;
409 rtl::Reference< RecursiveTest >(
410 new SimpleRecursiveTest(*this, 100, &destroyed))->test();
411 CPPUNIT_ASSERT(destroyed);
414 void Test::testCrossThreads()
416 bool destroyed = false;
417 rtl::Reference< RecursiveTest >(
418 new SimpleRecursiveTest(*this, 10, &destroyed))->test();
419 CPPUNIT_ASSERT(destroyed);
422 css::uno::Any Test::getKey(
423 OUString const & path, OUString const & relative) const
425 css::uno::Reference< css::container::XHierarchicalNameAccess > access(
426 createViewAccess(path), css::uno::UNO_QUERY_THROW);
427 css::uno::Any value(access->getByHierarchicalName(relative));
428 css::uno::Reference< css::lang::XComponent >(
429 access, css::uno::UNO_QUERY_THROW)->dispose();
430 return value;
433 void Test::setKey(
434 OUString const & path, OUString const & name,
435 css::uno::Any const & value) const
437 css::uno::Reference< css::container::XNameReplace > access(
438 createUpdateAccess(path), css::uno::UNO_QUERY_THROW);
439 access->replaceByName(name, value);
440 css::uno::Reference< css::util::XChangesBatch >(
441 access, css::uno::UNO_QUERY_THROW)->commitChanges();
442 css::uno::Reference< css::lang::XComponent >(
443 access, css::uno::UNO_QUERY_THROW)->dispose();
446 bool Test::resetKey(OUString const & path, OUString const & name)
447 const
449 //TODO: support setPropertyToDefault
450 css::uno::Reference< css::util::XChangesBatch > access(
451 createUpdateAccess(path), css::uno::UNO_QUERY_THROW);
452 css::uno::Reference< css::beans::XPropertyState > state(
453 access, css::uno::UNO_QUERY);
454 if (!state.is()) {
455 return false;
457 state->setPropertyToDefault(name);
458 access->commitChanges();
459 css::uno::Reference< css::lang::XComponent >(
460 access, css::uno::UNO_QUERY_THROW)->dispose();
461 return true;
464 css::uno::Reference< css::uno::XInterface > Test::createViewAccess(
465 OUString const & path) const
467 css::uno::Any arg(
468 css::beans::NamedValue(
469 "nodepath",
470 css::uno::Any(path)));
471 return provider_->createInstanceWithArguments(
472 "com.sun.star.configuration.ConfigurationAccess",
473 css::uno::Sequence< css::uno::Any >(&arg, 1));
476 css::uno::Reference< css::uno::XInterface > Test::createUpdateAccess(
477 OUString const & path) const
479 css::uno::Any arg(
480 css::beans::NamedValue(
481 "nodepath",
482 css::uno::Any(path)));
483 return provider_->createInstanceWithArguments(
484 "com.sun.star.configuration.ConfigurationUpdateAccess",
485 css::uno::Sequence< css::uno::Any >(&arg, 1));
488 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
492 CPPUNIT_PLUGIN_IMPLEMENT();
494 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */