1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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
;
27 /// Covers framework/source/services/ fixes.
28 class Test
: public UnoApiTest
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
;
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.
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
);
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();
107 SolarMutexReleaser releaser
;
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.
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: */