Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / framework / qa / cppunit / services.cxx
blobbe6c0def70fa8b19c981febcae4870b052efc786
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/.
8 */
10 #include <test/unoapi_test.hxx>
12 #include <com/sun/star/frame/XFrame.hpp>
13 #include <com/sun/star/frame/XComponentLoader.hpp>
14 #include <com/sun/star/frame/FrameSearchFlag.hpp>
15 #include <com/sun/star/util/URLTransformer.hpp>
17 #include <comphelper/propertyvalue.hxx>
18 #include <salhelper/thread.hxx>
19 #include <vcl/svapp.hxx>
20 #include <vcl/scheduler.hxx>
21 #include <vcl/wrkwin.hxx>
23 using namespace ::com::sun::star;
25 namespace
27 /// Covers framework/source/services/ fixes.
28 class Test : public UnoApiTest
30 public:
31 Test()
32 : UnoApiTest("/framework/qa/cppunit/data/")
37 /// Invokes XFrameImpl::loadComponentFromURL() on a thread.
38 class TestThread : public salhelper::Thread
40 uno::Reference<frame::XComponentLoader> mxComponentLoader;
41 uno::Reference<lang::XComponent>& mrComponent;
43 public:
44 TestThread(const uno::Reference<frame::XComponentLoader>& xComponentLoader,
45 uno::Reference<lang::XComponent>& rComponent);
46 void execute() override;
49 TestThread::TestThread(const uno::Reference<frame::XComponentLoader>& xComponentLoader,
50 uno::Reference<lang::XComponent>& rComponent)
51 : salhelper::Thread("TestThread")
52 , mxComponentLoader(xComponentLoader)
53 , mrComponent(rComponent)
57 void TestThread::execute()
59 sal_Int32 nSearchFlags = frame::FrameSearchFlag::AUTO;
60 uno::Sequence<beans::PropertyValue> aArguments = {
61 comphelper::makePropertyValue("OnMainThread", true),
63 // Note how this is invoking loadComponentFromURL() on a frame, not on the desktop, as usual.
64 mrComponent = mxComponentLoader->loadComponentFromURL("private:factory/swriter", "_self",
65 nSearchFlags, aArguments);
68 CPPUNIT_TEST_FIXTURE(Test, testLoadComponentFromURL)
70 // Without the accompanying fix in place, this test would have failed with:
71 // thread 1: comphelper::SolarMutex::doRelease end: m_nCount is 1
72 // thread 2: vcl::SolarThreadExecutor::execute: before SolarMutexReleaser ctor
73 // thread 2: comphelper::SolarMutex::doRelease start: m_nCount is 1, bUnlockAll is 1
74 // thread 2: comphelper::SolarMutex::doRelease: failed IsCurrentThread() check, will abort
75 // Notice how thread 2 attempts to release the solar mutex while thread 1 holds it.
77 // Create a default window, so by the time the thread would post a user event, it doesn't need
78 // the solar mutex to process a SendMessageW() call on Windows.
79 ScopedVclPtrInstance<WorkWindow> xWindow(nullptr, WB_APP | WB_STDWORK);
80 // Variable is not used, it holds the default window.
81 (void)xWindow;
83 rtl::Reference<TestThread> xThread;
85 // Start the thread that will load the component, but hold the solar mutex for now, so we
86 // can see if it blocks.
87 SolarMutexGuard guard;
88 uno::Reference<frame::XFrame> xFrame = mxDesktop->findFrame("_blank", /*nSearchFlags=*/0);
89 uno::Reference<frame::XComponentLoader> xComponentLoader(xFrame, uno::UNO_QUERY);
90 xThread = new TestThread(xComponentLoader, mxComponent);
91 xThread->launch();
92 // If loadComponentFromURL() doesn't lock the solar mutex, the test will abort here.
93 osl::Thread::wait(std::chrono::seconds(1));
96 // Now release the solar mutex, so the thread can post the task on the main loop.
97 SolarMutexReleaser releaser;
98 osl::Thread::wait(std::chrono::seconds(1));
101 // Spin the main loop.
102 SolarMutexGuard guard;
103 Scheduler::ProcessEventsToIdle();
106 // Stop the thread.
107 SolarMutexReleaser releaser;
108 xThread->join();
112 CPPUNIT_TEST_FIXTURE(Test, testURLTransformer_parseSmart)
114 // Without the accompanying fix in place, this test would have failed with
115 // "www.example.com:" treated as scheme, "/8080/foo/" as path, "bar?q=baz"
116 // as name, and "F" as fragment.
118 css::util::URL aURL;
119 aURL.Complete = "www.example.com:8080/foo/bar?q=baz#F";
120 css::uno::Reference xParser(css::util::URLTransformer::create(mxComponentContext));
121 CPPUNIT_ASSERT(xParser->parseSmart(aURL, "http:"));
122 CPPUNIT_ASSERT_EQUAL(OUString("http://www.example.com:8080/foo/bar?q=baz#F"), aURL.Complete);
123 CPPUNIT_ASSERT_EQUAL(OUString("http://www.example.com:8080/foo/bar"), aURL.Main);
124 CPPUNIT_ASSERT_EQUAL(OUString("http://"), aURL.Protocol);
125 CPPUNIT_ASSERT(aURL.User.isEmpty());
126 CPPUNIT_ASSERT(aURL.Password.isEmpty());
127 CPPUNIT_ASSERT_EQUAL(OUString("www.example.com"), aURL.Server);
128 CPPUNIT_ASSERT_EQUAL(sal_Int16(8080), aURL.Port);
129 CPPUNIT_ASSERT_EQUAL(OUString("/foo/"), aURL.Path);
130 CPPUNIT_ASSERT_EQUAL(OUString("bar"), aURL.Name);
131 CPPUNIT_ASSERT_EQUAL(OUString("q=baz"), aURL.Arguments);
132 CPPUNIT_ASSERT_EQUAL(OUString("F"), aURL.Mark);
136 CPPUNIT_PLUGIN_IMPLEMENT();
138 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */