Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #ifndef INCLUDED_SC_QA_UNIT_HELPER_QAHELPER_HXX
11 : #define INCLUDED_SC_QA_UNIT_HELPER_QAHELPER_HXX
12 :
13 : #include "scdllapi.h"
14 : #include "debughelper.hxx"
15 : #include "docsh.hxx"
16 : #include "address.hxx"
17 :
18 : #include <test/bootstrapfixture.hxx>
19 : #include <comphelper/documentconstants.hxx>
20 :
21 : #include <osl/detail/android-bootstrap.h>
22 :
23 : #include <unotools/tempfile.hxx>
24 : #include <comphelper/storagehelper.hxx>
25 : #include <sfx2/docfilt.hxx>
26 : #include <sfx2/docfile.hxx>
27 : #include <svl/stritem.hxx>
28 : #include <formula/grammar.hxx>
29 :
30 : #include <string>
31 : #include <sstream>
32 :
33 : #include <sal/types.h>
34 :
35 : #include <boost/shared_ptr.hpp>
36 :
37 : #if defined(SCQAHELPER_DLLIMPLEMENTATION)
38 : #define SCQAHELPER_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
39 : #else
40 : #define SCQAHELPER_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
41 : #endif
42 :
43 : #define ODS_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::TEMPLATE | SfxFilterFlags::OWN | SfxFilterFlags::DEFAULT | SfxFilterFlags::ENCRYPTION | SfxFilterFlags::PASSWORDTOMODIFY)
44 : #define XLS_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::ENCRYPTION | SfxFilterFlags::PASSWORDTOMODIFY | SfxFilterFlags::PREFERED)
45 : #define XLSX_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::STARONEFILTER | SfxFilterFlags::PREFERED)
46 : #define LOTUS123_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::USESOPTIONS | SfxFilterFlags::PREFERED)
47 : #define CSV_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::USESOPTIONS)
48 : #define HTML_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::USESOPTIONS)
49 : #define DIF_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::USESOPTIONS)
50 : #define XLS_XML_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::ALIEN)
51 : #define XLSB_XML_FORMAT_TYPE (SfxFilterFlags::IMPORT | SfxFilterFlags::ALIEN | SfxFilterFlags::STARONEFILTER | SfxFilterFlags::PREFERED)
52 :
53 : #define ODS 0
54 : #define XLS 1
55 : #define XLSX 2
56 : #define XLSM 3
57 : #define CSV 4
58 : #define HTML 5
59 : #define LOTUS123 6
60 : #define DIF 7
61 : #define XLS_XML 8
62 : #define XLSB 9
63 :
64 : enum StringType { PureString, FormulaValue, StringValue };
65 :
66 : SCQAHELPER_DLLPUBLIC bool testEqualsWithTolerance( long nVal1, long nVal2, long nTol );
67 :
68 : #define CHECK_OPTIMAL 0x1
69 :
70 : class SdrOle2Obj;
71 : class ScRangeList;
72 : class ScTokenArray;
73 :
74 : // data format for row height tests
75 : struct TestParam
76 : {
77 : struct RowData
78 : {
79 : SCROW nStartRow;
80 : SCROW nEndRow;
81 : SCTAB nTab;
82 : int nExpectedHeight; // -1 for default height
83 : int nCheck; // currently only CHECK_OPTIMAL ( we could add CHECK_MANUAL etc.)
84 : bool bOptimal;
85 : };
86 : const char* sTestDoc;
87 : int nImportType;
88 : int nExportType; // -1 for import test, otherwise this is an export test
89 : int nRowData;
90 : RowData* pData;
91 : };
92 :
93 : struct FileFormat {
94 : const char* pName; const char* pFilterName; const char* pTypeName; SfxFilterFlags nFormatType;
95 : };
96 :
97 : // Printers for the calc data structures. Needed for the EQUAL assertion
98 : // macros from CPPUNIT.
99 :
100 : SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const ScAddress& rAddr);
101 :
102 : SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const ScRange& rRange);
103 :
104 : SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const ScRangeList& rList);
105 :
106 : SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const Color& rColor);
107 :
108 : SCQAHELPER_DLLPUBLIC std::ostream& operator<<(std::ostream& rStrm, const OpCode& rCode);
109 :
110 : // Why is this here and not in osl, and using the already existing file
111 : // handling APIs? Do we really want to add arbitrary new file handling
112 : // wrappers here and there (and then having to handle the Android (and
113 : // eventually perhaps iOS) special cases here, too)? Please move this to osl,
114 : // it sure looks gemerally useful. Or am I missing something?
115 :
116 : SCQAHELPER_DLLPUBLIC void loadFile(const OUString& aFileName, std::string& aContent);
117 :
118 : SCQAHELPER_DLLPUBLIC void testFile(OUString& aFileName, ScDocument& rDoc, SCTAB nTab, StringType aStringFormat = StringValue);
119 :
120 : //need own handler because conditional formatting strings must be generated
121 : SCQAHELPER_DLLPUBLIC void testCondFile(OUString& aFileName, ScDocument* pDoc, SCTAB nTab);
122 :
123 : SCQAHELPER_DLLPUBLIC const SdrOle2Obj* getSingleChartObject(ScDocument& rDoc, sal_uInt16 nPage);
124 :
125 : SCQAHELPER_DLLPUBLIC std::vector<OUString> getChartRangeRepresentations(const SdrOle2Obj& rChartObj);
126 :
127 : SCQAHELPER_DLLPUBLIC ScRangeList getChartRanges(ScDocument& rDoc, const SdrOle2Obj& rChartObj);
128 :
129 : SCQAHELPER_DLLPUBLIC bool checkFormula(ScDocument& rDoc, const ScAddress& rPos, const char* pExpected);
130 :
131 : SCQAHELPER_DLLPUBLIC bool checkFormulaPosition(ScDocument& rDoc, const ScAddress& rPos);
132 : SCQAHELPER_DLLPUBLIC bool checkFormulaPositions(
133 : ScDocument& rDoc, SCTAB nTab, SCCOL nCol, const SCROW* pRows, size_t nRowCount);
134 :
135 : SCQAHELPER_DLLPUBLIC ScTokenArray* compileFormula(
136 : ScDocument* pDoc, const OUString& rFormula, const ScAddress* pPos = NULL,
137 : formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_NATIVE );
138 :
139 : template<size_t _Size>
140 58 : bool checkOutput(ScDocument* pDoc, const ScRange& aOutRange, const char* aOutputCheck[][_Size], const char* pCaption)
141 : {
142 58 : bool bResult = true;
143 58 : const ScAddress& s = aOutRange.aStart;
144 58 : const ScAddress& e = aOutRange.aEnd;
145 58 : svl::GridPrinter printer(e.Row() - s.Row() + 1, e.Col() - s.Col() + 1, CALC_DEBUG_OUTPUT != 0);
146 58 : SCROW nOutRowSize = e.Row() - s.Row() + 1;
147 58 : SCCOL nOutColSize = e.Col() - s.Col() + 1;
148 401 : for (SCROW nRow = 0; nRow < nOutRowSize; ++nRow)
149 : {
150 1342 : for (SCCOL nCol = 0; nCol < nOutColSize; ++nCol)
151 : {
152 999 : OUString aVal = pDoc->GetString(nCol + s.Col(), nRow + s.Row(), s.Tab());
153 999 : printer.set(nRow, nCol, aVal);
154 999 : const char* p = aOutputCheck[nRow][nCol];
155 999 : if (p)
156 : {
157 834 : OUString aCheckVal = OUString::createFromAscii(p);
158 834 : bool bEqual = aCheckVal.equals(aVal);
159 834 : if (!bEqual)
160 : {
161 0 : cout << "Expected: " << aCheckVal << " Actual: " << aVal << endl;
162 0 : bResult = false;
163 834 : }
164 : }
165 165 : else if (!aVal.isEmpty())
166 : {
167 0 : cout << "Empty cell expected" << endl;
168 0 : bResult = false;
169 : }
170 : }
171 : }
172 58 : printer.print(pCaption);
173 58 : return bResult;
174 : }
175 :
176 : SCQAHELPER_DLLPUBLIC void clearFormulaCellChangedFlag( ScDocument& rDoc, const ScRange& rRange );
177 :
178 : /**
179 : * Check if the cell at specified position is a formula cell that doesn't
180 : * have an error value.
181 : */
182 : SCQAHELPER_DLLPUBLIC bool isFormulaWithoutError(ScDocument& rDoc, const ScAddress& rPos);
183 :
184 : /**
185 : * Convert formula token array to a formula string.
186 : */
187 : SCQAHELPER_DLLPUBLIC OUString toString(
188 : ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rArray,
189 : formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_NATIVE);
190 :
191 0 : inline std::string print(const ScAddress& rAddr)
192 : {
193 0 : std::ostringstream str;
194 0 : str << "Col: " << rAddr.Col();
195 0 : str << " Row: " << rAddr.Row();
196 0 : str << " Tab: " << rAddr.Tab();
197 0 : return str.str();
198 : }
199 :
200 : namespace CppUnit {
201 :
202 : template<>
203 : struct assertion_traits<ScRange>
204 : {
205 6 : static bool equal( const ScRange& x, const ScRange& y )
206 : {
207 6 : return x == y;
208 : }
209 :
210 0 : static std::string toString( const ScRange& x )
211 : {
212 0 : std::stringstream str;
213 0 : str << "Start: " << print(x.aStart);
214 0 : str << "\nEnd: " << print(x.aEnd);
215 0 : return str.str();
216 : }
217 : };
218 :
219 : }
220 :
221 : class SCQAHELPER_DLLPUBLIC ScBootstrapFixture : public test::BootstrapFixture
222 : {
223 : static const FileFormat aFileFormats[];
224 : protected:
225 : OUString m_aBaseString;
226 :
227 : ScDocShellRef load(
228 : bool bReadWrite, const OUString& rURL, const OUString& rFilter, const OUString &rUserData,
229 : const OUString& rTypeName, SfxFilterFlags nFilterFlags, SotClipboardFormatId nClipboardID,
230 : sal_uIntPtr nFilterVersion = SOFFICE_FILEFORMAT_CURRENT, const OUString* pPassword = NULL );
231 :
232 : ScDocShellRef load(
233 : const OUString& rURL, const OUString& rFilter, const OUString &rUserData,
234 : const OUString& rTypeName, SfxFilterFlags nFilterFlags, SotClipboardFormatId nClipboardID,
235 : sal_uIntPtr nFilterVersion = SOFFICE_FILEFORMAT_CURRENT, const OUString* pPassword = NULL );
236 :
237 : ScDocShellRef loadDoc(const OUString& rFileName, sal_Int32 nFormat, bool bReadWrite = false );
238 :
239 : public:
240 42 : static const FileFormat* getFileFormats() { return aFileFormats; }
241 :
242 : ScBootstrapFixture( const OUString& rsBaseString );
243 : virtual ~ScBootstrapFixture();
244 :
245 : void createFileURL(const OUString& aFileBase, const OUString& aFileExtension, OUString& rFilePath);
246 :
247 : void createCSVPath(const OUString& aFileBase, OUString& rCSVPath);
248 :
249 : ScDocShellRef saveAndReload(ScDocShell* pShell, const OUString &rFilter,
250 : const OUString &rUserData, const OUString& rTypeName, SfxFilterFlags nFormatType);
251 :
252 : ScDocShellRef saveAndReload( ScDocShell* pShell, sal_Int32 nFormat );
253 :
254 : static boost::shared_ptr<utl::TempFile> exportTo( ScDocShell* pShell, sal_Int32 nFormat );
255 :
256 : void miscRowHeightsTest( TestParam* aTestValues, unsigned int numElems );
257 : };
258 :
259 : #define ASSERT_DOUBLES_EQUAL( expected, result ) \
260 : CPPUNIT_ASSERT_DOUBLES_EQUAL( (expected), (result), 1e-14 )
261 :
262 : #define ASSERT_DOUBLES_EQUAL_MESSAGE( message, expected, result ) \
263 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( (message), (expected), (result), 1e-14 )
264 :
265 : #define ASSERT_EQUAL_TYPE( type, expected, result ) \
266 : CPPUNIT_ASSERT_EQUAL( static_cast<type>(expected), static_cast<type>(result) );
267 :
268 : SCQAHELPER_DLLPUBLIC void testFormats(ScBootstrapFixture* pTest, ScDocument* pDoc, sal_Int32 nFormat);
269 :
270 : #endif
271 :
272 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|