smoketest.cxx 6.75 KB
Newer Older
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
Michael Meeks's avatar
Michael Meeks committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
19

20
#include <sal/types.h>
21
#include <chrono>
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#include <com/sun/star/awt/AsyncCallback.hpp>
#include <com/sun/star/awt/XCallback.hpp>
#include <com/sun/star/beans/PropertyState.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/DispatchResultEvent.hpp>
#include <com/sun/star/frame/DispatchResultState.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/XDispatchResultListener.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XNotifyingDispatch.hpp>
#include <com/sun/star/lang/EventObject.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/util/URL.hpp>
41
#include <cppuhelper/implbase.hxx>
42 43 44 45 46 47 48 49 50 51 52 53
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>
#include <osl/conditn.hxx>
#include <osl/diagnose.h>
#include <osl/time.h>
#include <rtl/ustring.h>
#include <rtl/ustring.hxx>
#include <unotest/gettestargument.hxx>
#include <unotest/officeconnection.hxx>
#include <unotest/toabsolutefileurl.hxx>
54 55 56

namespace {

57
struct Result {
58 59
    osl::Condition condition;
    bool success;
60
    OUString result;
61 62 63 64
    Result()
        : success(false)
    {
    }
65 66
    Result(const Result&) = delete;
    Result& operator=(const Result&) = delete;
67 68 69
};

class Listener:
70
    public cppu::WeakImplHelper< css::frame::XDispatchResultListener >
71 72
{
public:
73
    explicit Listener(Result * result): result_(result) { OSL_ASSERT(result != nullptr); }
74 75

private:
76
    virtual void SAL_CALL disposing(css::lang::EventObject const &) override {}
77 78

    virtual void SAL_CALL dispatchFinished(
79
        css::frame::DispatchResultEvent const & Result) override;
80 81 82 83 84 85 86 87 88 89 90 91

    Result * result_;
};

void Listener::dispatchFinished(css::frame::DispatchResultEvent const & Result)
{
    result_->success =
        (Result.State == css::frame::DispatchResultState::SUCCESS) &&
        (Result.Result >>= result_->result);
    result_->condition.set();
}

92
class Callback: public cppu::WeakImplHelper< css::awt::XCallback > {
93 94 95 96 97 98 99 100 101
public:
    Callback(
        css::uno::Reference< css::frame::XNotifyingDispatch > const & dispatch,
        css::util::URL const & url,
        css::uno::Sequence< css::beans::PropertyValue > const & arguments,
        css::uno::Reference< css::frame::XDispatchResultListener > const &
            listener):
        dispatch_(dispatch), url_(url), arguments_(arguments),
        listener_(listener)
102
    { OSL_ASSERT(dispatch.is()); }
103 104

private:
105
    virtual void SAL_CALL notify(css::uno::Any const &) override
106 107 108
    { dispatch_->dispatchWithNotification(url_, arguments_, listener_); }

    css::uno::Reference< css::frame::XNotifyingDispatch > dispatch_;
109 110
    css::util::URL const url_;
    css::uno::Sequence< css::beans::PropertyValue > const arguments_;
111 112 113
    css::uno::Reference< css::frame::XDispatchResultListener > listener_;
};

114 115
class Test: public CppUnit::TestFixture {
public:
116
    virtual void setUp() override;
117

118
    virtual void tearDown() override;
119 120 121 122 123 124 125 126

private:
    CPPUNIT_TEST_SUITE(Test);
    CPPUNIT_TEST(test);
    CPPUNIT_TEST_SUITE_END();

    void test();

127
    test::OfficeConnection connection_;
128 129 130
};

void Test::setUp() {
131
    connection_.setUp();
132 133 134
}

void Test::tearDown() {
135
    connection_.tearDown();
136 137 138
}

void Test::test() {
139
    OUString doc;
140
    CPPUNIT_ASSERT(
141
        test::getTestArgument(
142
            "smoketest.doc", &doc));
143
    css::uno::Sequence< css::beans::PropertyValue > args(2);
144
    args[0].Name = "MacroExecutionMode";
145
    args[0].Handle = -1;
146
    args[0].Value <<=  css::document::MacroExecMode::ALWAYS_EXECUTE_NO_WARN;
147
    args[0].State = css::beans::PropertyState_DIRECT_VALUE;
148
    args[1].Name = "ReadOnly";
149
    args[1].Handle = -1;
150
    args[1].Value <<= true;
151
    args[1].State = css::beans::PropertyState_DIRECT_VALUE;
152
    css::util::URL url;
153 154
    url.Complete = "vnd.sun.star.script:Standard.Global.StartTestWithDefaultOptions?"
            "language=Basic&location=document";
155 156 157

    css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create(connection_.getComponentContext());

158
    css::uno::Reference< css::frame::XNotifyingDispatch > disp(
159 160 161
        css::uno::Reference< css::frame::XDispatchProvider >(
            css::uno::Reference< css::frame::XController >(
                css::uno::Reference< css::frame::XModel >(
162
                    xDesktop->loadComponentFromURL(
163
                            test::toAbsoluteFileUrl(doc),
Noel Grandin's avatar
Noel Grandin committed
164
                            "_default",
165 166 167 168
                            0, args),
                    css::uno::UNO_QUERY_THROW)->getCurrentController(),
                css::uno::UNO_SET_THROW)->getFrame(),
            css::uno::UNO_QUERY_THROW)->queryDispatch(
Noel Grandin's avatar
Noel Grandin committed
169
                url, "_self", 0),
170 171 172
        css::uno::UNO_QUERY_THROW);
    Result result;
    // Shifted to main thread to work around potential deadlocks (i112867):
173
    css::awt::AsyncCallback::create(
174
        connection_.getComponentContext())->addCallback(
175 176 177 178
            new Callback(
                disp, url, css::uno::Sequence< css::beans::PropertyValue >(),
                new Listener(&result)),
            css::uno::Any());
179 180
    // Wait for result.condition or connection_ going stale:
    for (;;) {
181
        osl::Condition::Result res = result.condition.wait(std::chrono::seconds(1)); // 1 sec delay
182 183 184 185 186 187
        if (res == osl::Condition::result_ok) {
            break;
        }
        CPPUNIT_ASSERT_EQUAL(osl::Condition::result_timeout, res);
        CPPUNIT_ASSERT(connection_.isStillAlive());
    }
188
    CPPUNIT_ASSERT(result.success);
189
    CPPUNIT_ASSERT_EQUAL(OUString(), result.result);
190 191 192 193 194 195 196
}

CPPUNIT_TEST_SUITE_REGISTRATION(Test);

}

CPPUNIT_PLUGIN_IMPLEMENT();
197 198

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */