smoketest.cxx 6.94 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 "boost/noncopyable.hpp"
22
#include "com/sun/star/awt/AsyncCallback.hpp"
23
#include "com/sun/star/awt/XCallback.hpp"
24 25 26
#include "com/sun/star/beans/PropertyState.hpp"
#include "com/sun/star/beans/PropertyValue.hpp"
#include "com/sun/star/document/MacroExecMode.hpp"
27
#include "com/sun/star/frame/Desktop.hpp"
28 29 30 31 32 33 34 35 36
#include "com/sun/star/frame/DispatchResultEvent.hpp"
#include "com/sun/star/frame/DispatchResultState.hpp"
#include "com/sun/star/frame/XComponentLoader.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"
37
#include "com/sun/star/uno/Any.hxx"
38 39 40 41
#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"
42
#include <cppuhelper/implbase.hxx>
43 44 45 46
#include "cppunit/TestAssert.h"
#include "cppunit/TestFixture.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/plugin/TestPlugIn.h"
47 48
#include "osl/conditn.hxx"
#include "osl/diagnose.h"
49
#include "osl/time.h"
50 51
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
52 53 54
#include "unotest/gettestargument.hxx"
#include "unotest/officeconnection.hxx"
#include "unotest/toabsolutefileurl.hxx"
55 56 57 58 59 60

namespace {

struct Result: private boost::noncopyable {
    osl::Condition condition;
    bool success;
61
    OUString result;
62 63 64
};

class Listener:
65
    public cppu::WeakImplHelper< css::frame::XDispatchResultListener >
66 67
{
public:
68
    explicit Listener(Result * result): result_(result) { OSL_ASSERT(result != nullptr); }
69 70 71

private:
    virtual void SAL_CALL disposing(css::lang::EventObject const &)
72
        throw (css::uno::RuntimeException, std::exception) override {}
73 74 75

    virtual void SAL_CALL dispatchFinished(
        css::frame::DispatchResultEvent const & Result)
76
        throw (css::uno::RuntimeException, std::exception) override;
77 78 79 80 81

    Result * result_;
};

void Listener::dispatchFinished(css::frame::DispatchResultEvent const & Result)
82
    throw (css::uno::RuntimeException, std::exception)
83 84 85 86 87 88 89
{
    result_->success =
        (Result.State == css::frame::DispatchResultState::SUCCESS) &&
        (Result.Result >>= result_->result);
    result_->condition.set();
}

90
class Callback: public cppu::WeakImplHelper< css::awt::XCallback > {
91 92 93 94 95 96 97 98 99 100 101 102 103
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)
    { OSL_ASSERT(dispatch.is()); }

private:
    virtual void SAL_CALL notify(css::uno::Any const &)
104
        throw (css::uno::RuntimeException, std::exception) override
105 106 107 108 109 110 111 112
    { dispatch_->dispatchWithNotification(url_, arguments_, listener_); }

    css::uno::Reference< css::frame::XNotifyingDispatch > dispatch_;
    css::util::URL url_;
    css::uno::Sequence< css::beans::PropertyValue > arguments_;
    css::uno::Reference< css::frame::XDispatchResultListener > listener_;
};

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

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

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

    void test();

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

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

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

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

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

157
    css::uno::Reference< css::frame::XNotifyingDispatch > disp(
158 159 160
        css::uno::Reference< css::frame::XDispatchProvider >(
            css::uno::Reference< css::frame::XController >(
                css::uno::Reference< css::frame::XModel >(
161
                    xDesktop->loadComponentFromURL(
162
                            test::toAbsoluteFileUrl(doc),
Noel Grandin's avatar
Noel Grandin committed
163
                            "_default",
164 165 166 167
                            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
168
                url, "_self", 0),
169 170 171
        css::uno::UNO_QUERY_THROW);
    Result result;
    // Shifted to main thread to work around potential deadlocks (i112867):
172
    css::awt::AsyncCallback::create(
173
        connection_.getComponentContext())->addCallback(
174 175 176 177
            new Callback(
                disp, url, css::uno::Sequence< css::beans::PropertyValue >(),
                new Listener(&result)),
            css::uno::Any());
178 179 180 181 182 183 184 185 186 187
    // Wait for result.condition or connection_ going stale:
    for (;;) {
        TimeValue delay = { 1, 0 }; // 1 sec
        osl::Condition::Result res = result.condition.wait(&delay);
        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: */