summaryrefslogtreecommitdiffstats
path: root/sc/qa/unit/helper/qahelper.hxx
blob: 4b95451c96d14906fd711febed2b382896891fae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * 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/.
 */

#pragma once

#include <docsh.hxx>
#include <address.hxx>

#include <cppunit/SourceLine.h>

#include <test/unoapixml_test.hxx>
#include <test/bootstrapfixture.hxx>
#include <comphelper/documentconstants.hxx>

#include <comphelper/fileformat.h>
#include <formula/grammar.hxx>
#include "scqahelperdllapi.h"

#include <string>
#include <string_view>
#include <sstream>
#include <undoblk.hxx>

#include <sal/types.h>

#include <memory>
#include <tuple>

enum class StringType { PureString, StringValue };

#define CHECK_OPTIMAL 0x1

class SdrOle2Obj;
class ScRangeList;
class ScTokenArray;

// data format for row height tests
struct TestParam
{
    struct RowData
    {
        SCROW nStartRow;
        SCROW nEndRow;
        SCTAB nTab;
        int nExpectedHeight; // -1 for default height
        int nCheck; // currently only CHECK_OPTIMAL ( we could add CHECK_MANUAL etc.)
        bool bOptimal;
    };
    const std::u16string_view sTestDoc;
    const OUString sExportType; // empty for import test, otherwise this is an export test
    int nRowData;
    RowData const * pData;
};

struct RangeNameDef
{
    const char* mpName;
    const char* mpExpr;
    sal_uInt16 mnIndex;
};

// Printers for the calc data structures. Needed for the EQUAL assertion
// macros from CPPUNIT.

SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const ScAddress& rAddr);

SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const ScRange& rRange);

SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const ScRangeList& rList);

SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const OpCode& rCode);

SCQAHELPER_DLLPUBLIC bool checkOutput(
    const ScDocument* pDoc, const ScRange& aOutRange,
    const std::vector<std::vector<const char*>>& aCheck, const char* pCaption );

inline std::string print(const ScAddress& rAddr)
{
    std::ostringstream str;
    str << "Col: " << rAddr.Col();
    str << " Row: " << rAddr.Row();
    str << " Tab: " << rAddr.Tab();
    return str.str();
}

/**
 * Temporarily set formula grammar.
 */
class SCQAHELPER_DLLPUBLIC FormulaGrammarSwitch
{
    ScDocument* mpDoc;
    formula::FormulaGrammar::Grammar meOldGrammar;

public:
    FormulaGrammarSwitch(ScDocument* pDoc, formula::FormulaGrammar::Grammar eGrammar);
    ~FormulaGrammarSwitch();
};

class SCQAHELPER_DLLPUBLIC ScUcalcTestBase : public test::BootstrapFixture
{
public:
    virtual void setUp() override;
    virtual void tearDown() override;

    ScRange insertRangeData(ScDocument* pDoc, const ScAddress& rPos,
                                       const std::vector<std::vector<const char*>>& rData);
    void copyToClip(ScDocument* pSrcDoc, const ScRange& rRange, ScDocument* pClipDoc);
    void pasteFromClip(ScDocument* pDestDoc, const ScRange& rDestRange,
                                        ScDocument* pClipDoc);
    ScUndoPaste* createUndoPaste(ScDocShell& rDocSh, const ScRange& rRange,
                                        ScDocumentUniquePtr pUndoDoc);
    void pasteOneCellFromClip(ScDocument* pDestDoc, const ScRange& rDestRange,
                                         ScDocument* pClipDoc,
                                         InsertDeleteFlags eFlags = InsertDeleteFlags::ALL);
    void setCalcAsShown(ScDocument* pDoc, bool bCalcAsShown);
    ScDocShell* findLoadedDocShellByName(std::u16string_view rName);
    ScUndoCut* cutToClip(ScDocShell& rDocSh, const ScRange& rRange, ScDocument* pClipDoc,
                                        bool bCreateUndo);
    bool insertRangeNames(ScDocument* pDoc, ScRangeName* pNames, const RangeNameDef* p,
                                       const RangeNameDef* pEnd);
    OUString getRangeByName(ScDocument* pDoc, const OUString& aRangeName);
    void printFormula(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab,
                                           const char* pCaption = nullptr);
    void printRange(ScDocument* pDoc, const ScRange& rRange, const char* pCaption,
                                         const bool printFormula = false);
    void printRange(ScDocument* pDoc, const ScRange& rRange,
                                         const OString& rCaption, const bool printFormula = false);
    void clearRange(ScDocument* pDoc, const ScRange& rRange);
    void clearSheet(ScDocument* pDoc, SCTAB nTab);
    bool checkFormulaPosition(ScDocument& rDoc, const ScAddress& rPos);
    bool checkFormulaPositions(
        ScDocument& rDoc, SCTAB nTab, SCCOL nCol, const SCROW* pRows, size_t nRowCount);
    std::unique_ptr<ScTokenArray> compileFormula(
        ScDocument* pDoc, const OUString& rFormula,
        formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_NATIVE );
    void clearFormulaCellChangedFlag( ScDocument& rDoc, const ScRange& rRange );

protected:
    ScDocShellRef m_xDocShell;
    ScDocument* m_pDoc;
};

class SCQAHELPER_DLLPUBLIC ScModelTestBase : public UnoApiXmlTest
{
public:
    ScModelTestBase(OUString path)
        : UnoApiXmlTest(path)
    {
    }

    void createScDoc(const char* pName = nullptr, const char* pPassword = nullptr, bool bCheckErrorCode = true);
    ScDocument* getScDoc();
    ScDocument* getScDoc2();
    ScDocShell* getScDocShell();
    ScTabViewShell* getViewShell();
    void miscRowHeightsTest( TestParam const * aTestValues, unsigned int numElems);

    void enableOpenCL();
    void disableOpenCL();
    void initTestEnv(std::u16string_view fileName);

    void testFile(const OUString& aFileName, ScDocument& rDoc, SCTAB nTab, StringType aStringFormat = StringType::StringValue);

    //need own handler because conditional formatting strings must be generated
    void testCondFile(const OUString& aFileName, ScDocument* pDoc, SCTAB nTab, bool bCommaAsDelimiter = true);

    const SdrOle2Obj* getSingleOleObject(ScDocument& rDoc, sal_uInt16 nPage);

    const SdrOle2Obj* getSingleChartObject(ScDocument& rDoc, sal_uInt16 nPage);

    ScRangeList getChartRanges(ScDocument& rDoc, const SdrOle2Obj& rChartObj);

    void testFormats(ScDocument* pDoc,std::u16string_view sFormat);

    void goToCell(const OUString& rCell);
    void typeString(const std::u16string_view& rStr);
    void insertStringToCell(const OUString& rCell, const std::u16string_view& rStr);
    void insertArrayToCell(const OUString& rCell, const std::u16string_view& rStr);
    void insertNewSheet(ScDocument& rDoc);
    void executeAutoSum();

private:
    // Why is this here and not in osl, and using the already existing file
    // handling APIs? Do we really want to add arbitrary new file handling
    // wrappers here and there (and then having to handle the Android (and
    // eventually perhaps iOS) special cases here, too)?  Please move this to osl,
    // it sure looks generally useful. Or am I missing something?

    void loadFile(const OUString& aFileName, std::string& aContent);
};

#define ASSERT_DOUBLES_EQUAL( expected, result )    \
    CPPUNIT_ASSERT_DOUBLES_EQUAL( (expected), (result), 1e-14 )

#define ASSERT_DOUBLES_EQUAL_MESSAGE( message, expected, result )   \
    CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( (message), (expected), (result), 1e-14 )

inline void assertPointEqual(
    const Point& rExpected, const Point& rActual, const sal_Int32 nTolerance,
    const CppUnit::SourceLine& rSourceLine )
{
    CPPUNIT_NS::assertDoubleEquals( rExpected.X(), rActual.X(), nTolerance, rSourceLine, "different X" );
    CPPUNIT_NS::assertDoubleEquals( rExpected.Y(), rActual.Y(), nTolerance, rSourceLine, "different Y" );
}

#define CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE(aExpected, aActual, aTolerance) \
        assertPointEqual( aExpected, aActual, aTolerance, CPPUNIT_SOURCELINE() )

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