Resolves: tdf#162093 TableRef item specifier may occur standalone
[LibreOffice.git] / sc / qa / unit / jumbosheets-test.cxx
bloba58d33715b7dde956e33549d9d473d5c30d97863
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <sal/config.h>
11 #include <test/unoapixml_test.hxx>
12 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
13 #include <vcl/scheduler.hxx>
14 #include <vcl/keycodes.hxx>
15 #include <comphelper/servicehelper.hxx>
16 #include <svx/svdpage.hxx>
18 #include <docsh.hxx>
19 #include <defaultsoptions.hxx>
20 #include <scmod.hxx>
21 #include <viewdata.hxx>
22 #include <tabvwsh.hxx>
23 #include <scdll.hxx>
25 using namespace ::com::sun::star;
26 using namespace ::com::sun::star::uno;
28 /* Tests for sheets larger than 1024 columns and/or 1048576 rows. */
30 class ScJumboSheetsTest : public UnoApiXmlTest
32 public:
33 ScJumboSheetsTest();
35 virtual void setUp() override;
36 virtual void tearDown() override;
38 void testRoundtripColumn2000Ods();
39 void testRoundtripColumn2000Xlsx();
40 void testRoundtripColumnRangeOds();
41 void testRoundtripColumnRangeXlsx();
42 void testRoundtripNamedRangesOds();
43 void testRoundtripNamedRangesXlsx();
44 void testNamedRangeNameConflict();
45 void testTdf134553();
46 void testTdf134392();
47 void testTdf147509();
48 void testTdf133033();
49 void testTdf109061();
51 CPPUNIT_TEST_SUITE(ScJumboSheetsTest);
53 CPPUNIT_TEST(testRoundtripColumn2000Ods);
54 CPPUNIT_TEST(testRoundtripColumn2000Xlsx);
55 CPPUNIT_TEST(testRoundtripColumnRangeOds);
56 CPPUNIT_TEST(testRoundtripColumnRangeXlsx);
57 CPPUNIT_TEST(testRoundtripNamedRangesOds);
58 CPPUNIT_TEST(testRoundtripNamedRangesXlsx);
59 CPPUNIT_TEST(testNamedRangeNameConflict);
60 CPPUNIT_TEST(testTdf134553);
61 CPPUNIT_TEST(testTdf134392);
62 CPPUNIT_TEST(testTdf147509);
63 CPPUNIT_TEST(testTdf133033);
64 CPPUNIT_TEST(testTdf109061);
66 CPPUNIT_TEST_SUITE_END();
68 private:
69 void testRoundtripColumn2000(std::u16string_view name, const char* format);
70 void testRoundtripNamedRanges(std::u16string_view name, const char* format);
73 void ScJumboSheetsTest::testRoundtripColumn2000Ods()
75 testRoundtripColumn2000(u"ods/value-in-column-2000.ods", "calc8");
78 void ScJumboSheetsTest::testRoundtripColumn2000Xlsx()
80 testRoundtripColumn2000(u"xlsx/value-in-column-2000.xlsx", "Calc Office Open XML");
83 void ScJumboSheetsTest::testRoundtripColumn2000(std::u16string_view name, const char* format)
85 loadFromFile(name);
87 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
88 CPPUNIT_ASSERT(pModelObj);
89 ScDocument* pDoc = pModelObj->GetDocument();
90 // Check the value at BXX1 (2000th column).
91 CPPUNIT_ASSERT_EQUAL(-5.0, pDoc->GetValue(1999, 0, 0));
92 // Check the formula referencing the value.
93 CPPUNIT_ASSERT_EQUAL(u"=BXX1"_ustr, pDoc->GetFormula(0, 0, 0));
94 // Recalc and check value in the reference.
95 pDoc->CalcAll();
96 CPPUNIT_ASSERT_EQUAL(-5.0, pDoc->GetValue(0, 0, 0));
99 saveAndReload(OUString::createFromAscii(format));
101 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
102 CPPUNIT_ASSERT(pModelObj);
104 ScDocument* pDoc = pModelObj->GetDocument();
105 // Check again.
106 CPPUNIT_ASSERT_EQUAL(-5.0, pDoc->GetValue(1999, 0, 0));
107 CPPUNIT_ASSERT_EQUAL(u"=BXX1"_ustr, pDoc->GetFormula(0, 0, 0));
108 pDoc->CalcAll();
109 CPPUNIT_ASSERT_EQUAL(-5.0, pDoc->GetValue(0, 0, 0));
113 void ScJumboSheetsTest::testRoundtripColumnRangeOds()
115 loadFromFile(u"ods/sum-whole-column-row.ods");
117 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
118 CPPUNIT_ASSERT(pModelObj);
119 ScDocument* pDoc = pModelObj->GetDocument();
120 // Check the formula referencing the whole-row range.
121 CPPUNIT_ASSERT_EQUAL(u"=SUM(2:2)"_ustr, pDoc->GetFormula(0, 0, 0));
122 // Check the formula referencing the whole-column range.
123 CPPUNIT_ASSERT_EQUAL(u"=SUM(C:C)"_ustr, pDoc->GetFormula(1, 0, 0));
126 saveAndReload(u"calc8"_ustr);
128 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
129 CPPUNIT_ASSERT(pModelObj);
131 ScDocument* pDoc = pModelObj->GetDocument();
132 CPPUNIT_ASSERT_EQUAL(u"=SUM(2:2)"_ustr, pDoc->GetFormula(0, 0, 0));
133 CPPUNIT_ASSERT_EQUAL(u"=SUM(C:C)"_ustr, pDoc->GetFormula(1, 0, 0));
134 xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
135 CPPUNIT_ASSERT(pXmlDoc);
136 assertXPath(pXmlDoc,
137 "/office:document-content/office:body/office:spreadsheet/table:table/"
138 "table:table-row[1]/table:table-cell[1]"_ostr,
139 "formula"_ostr, u"of:=SUM([.2:.2])"_ustr);
140 assertXPath(pXmlDoc,
141 "/office:document-content/office:body/office:spreadsheet/table:table/"
142 "table:table-row[1]/table:table-cell[2]"_ostr,
143 "formula"_ostr, u"of:=SUM([.C:.C])"_ustr);
147 void ScJumboSheetsTest::testRoundtripColumnRangeXlsx()
149 loadFromFile(u"ods/sum-whole-column-row.ods");
150 saveAndReload(u"Calc Office Open XML"_ustr);
152 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
153 CPPUNIT_ASSERT(pModelObj);
155 ScDocument* pDoc = pModelObj->GetDocument();
156 CPPUNIT_ASSERT_EQUAL(u"=SUM(2:2)"_ustr, pDoc->GetFormula(0, 0, 0));
157 CPPUNIT_ASSERT_EQUAL(u"=SUM(C:C)"_ustr, pDoc->GetFormula(1, 0, 0));
158 xmlDocUniquePtr pXmlDoc = parseExport(u"xl/worksheets/sheet1.xml"_ustr);
159 CPPUNIT_ASSERT(pXmlDoc);
160 assertXPathContent(pXmlDoc, "/x:worksheet/x:sheetData/x:row[1]/x:c[1]/x:f"_ostr,
161 u"SUM(2:2)"_ustr);
162 assertXPathContent(pXmlDoc, "/x:worksheet/x:sheetData/x:row[1]/x:c[2]/x:f"_ostr,
163 u"SUM(C:C)"_ustr);
167 void ScJumboSheetsTest::testRoundtripNamedRanges(std::u16string_view name, const char* format)
169 loadFromFile(name);
171 std::pair<OUString, OUString> ranges[] = { { "CELLBXX1", "$Sheet1.$BXX$1" },
172 { "CELLSA4_AMJ4", "$Sheet1.$A$4:$AMJ$4" },
173 { "CELLSBXX1_BXX10", "$Sheet1.$BXX$1:$BXX$10" },
174 { "CELLSBXX1_BXX10_RELATIVE", "$Sheet1.BXX1:BXX10" },
175 { "CELLSE1_E1024", "$Sheet1.$E$1:$E$1024" },
176 { "CELLSE1_E2000000", "$Sheet1.$E$1:$E$2000000" },
177 { "COLUMN_E", "$Sheet1.$E:$E" },
178 { "ROW_4", "$Sheet1.$4:$4" } };
180 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
181 CPPUNIT_ASSERT(pModelObj);
182 ScDocument* pDoc = pModelObj->GetDocument();
183 for (const auto& range : ranges)
185 ScRangeData* rangeData = pDoc->GetRangeName()->findByUpperName(range.first);
186 CPPUNIT_ASSERT(rangeData);
187 CPPUNIT_ASSERT_EQUAL(range.second, rangeData->GetSymbol());
191 saveAndReload(OUString::createFromAscii(format));
193 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
194 CPPUNIT_ASSERT(pModelObj);
195 ScDocument* pDoc = pModelObj->GetDocument();
196 for (const auto& range : ranges)
198 ScRangeData* rangeData = pDoc->GetRangeName()->findByUpperName(range.first);
199 CPPUNIT_ASSERT(rangeData);
200 CPPUNIT_ASSERT_EQUAL(range.second, rangeData->GetSymbol());
205 void ScJumboSheetsTest::testRoundtripNamedRangesOds()
207 testRoundtripNamedRanges(u"ods/ranges-column-2000.ods", "calc8");
210 void ScJumboSheetsTest::testRoundtripNamedRangesXlsx()
212 testRoundtripNamedRanges(u"ods/ranges-column-2000.ods", "Calc Office Open XML");
215 void ScJumboSheetsTest::testNamedRangeNameConflict()
217 // The document contains named ranges named 'num1' and 'num2', that should be still treated
218 // as named references even though with 16k columns those are normally NUM1 and NUM2 cells.
219 loadFromFile(u"ods/named-range-conflict.ods");
221 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
222 CPPUNIT_ASSERT(pModelObj);
223 ScDocument* pDoc = pModelObj->GetDocument();
224 pDoc->CalcAll();
225 CPPUNIT_ASSERT_EQUAL(0.0, pDoc->GetValue(10022, 0, 0)); // NUM1
226 CPPUNIT_ASSERT_EQUAL(0.0, pDoc->GetValue(10022, 1, 0)); // NUM2
227 CPPUNIT_ASSERT_EQUAL(2.0, pDoc->GetValue(0, 0, 0)); // = num1
228 CPPUNIT_ASSERT_EQUAL(3.0, pDoc->GetValue(0, 1, 0)); // = sheet2.num2
229 CPPUNIT_ASSERT_EQUAL(0.0, pDoc->GetValue(0, 2, 0)); // = SUM(NUM1:NUM2) (not named ranges)
230 pDoc->SetValue(10022, 0, 0, 100); // NUM1
231 pDoc->SetValue(10022, 1, 0, 200); // NUM2
232 pDoc->CalcAll();
233 // First two are the same, the sum changes.
234 CPPUNIT_ASSERT_EQUAL(2.0, pDoc->GetValue(0, 0, 0));
235 CPPUNIT_ASSERT_EQUAL(3.0, pDoc->GetValue(0, 1, 0));
236 CPPUNIT_ASSERT_EQUAL(300.0, pDoc->GetValue(0, 2, 0));
239 void ScJumboSheetsTest::testTdf134553()
241 loadFromFile(u"xlsx/tdf134553.xlsx");
243 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
244 CPPUNIT_ASSERT(pModelObj);
245 ScDocument* pDoc = pModelObj->GetDocument();
247 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
248 const SdrPage* pPage = pDrawLayer->GetPage(0);
249 const SdrObject* pOleObj = pPage->GetObj(0);
251 // Without the fix in place, this test would have failed here
252 CPPUNIT_ASSERT(pOleObj);
254 // Sorry, the charts so severely suffer from DPI dependency, that I can't find motivation
255 // to add huge tolerances (around 350!) here to make it pass on non-default DPI, with no
256 // guarantee that the test would have any value after that. So just skip it.
257 // FIXME: the DPI check should be removed when either (1) the test is fixed to work with
258 // non-default DPI; or (2) unit tests on Windows are made to use svp VCL plugin.
259 if (!IsDefaultDPI())
260 return;
262 CPPUNIT_ASSERT_EQUAL(tools::Long(12741), pOleObj->GetLogicRect().getOpenWidth());
263 CPPUNIT_ASSERT_EQUAL(tools::Long(7620), pOleObj->GetLogicRect().getOpenHeight());
264 CPPUNIT_ASSERT_EQUAL(tools::Long(4574), pOleObj->GetLogicRect().getX());
265 CPPUNIT_ASSERT_EQUAL(tools::Long(437), pOleObj->GetLogicRect().getY());
267 ScViewData* pViewData = ScDocShell::GetViewData();
268 CPPUNIT_ASSERT(pViewData);
269 ScTabViewShell* pViewShell = pViewData->GetViewShell();
270 pViewShell->SelectObject(u"Diagram 1");
272 dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
274 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pPage->GetObjCount());
276 dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
278 pOleObj = pPage->GetObj(0);
279 CPPUNIT_ASSERT(pOleObj);
281 CPPUNIT_ASSERT_EQUAL(tools::Long(12741), pOleObj->GetLogicRect().getOpenWidth());
282 CPPUNIT_ASSERT_EQUAL(tools::Long(7620), pOleObj->GetLogicRect().getOpenHeight());
283 CPPUNIT_ASSERT_EQUAL(tools::Long(1700), pOleObj->GetLogicRect().getX());
284 // tdf#147458: Without the fix in place, this test would have failed with
285 // - Expected: 2117
286 // - Actual : -7421
287 CPPUNIT_ASSERT_EQUAL(tools::Long(2117), pOleObj->GetLogicRect().getY());
290 void ScJumboSheetsTest::testTdf134392()
292 // Without the fix in place, the file would have crashed
293 loadFromFile(u"xlsx/tdf134392.xlsx");
295 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
296 CPPUNIT_ASSERT(pModelObj);
297 ScDocument* pDoc = pModelObj->GetDocument();
298 pDoc->CalcAll(); // perform hard re-calculation.
301 void ScJumboSheetsTest::testTdf147509()
303 mxComponent = loadFromDesktop(u"private:factory/scalc"_ustr);
304 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
305 CPPUNIT_ASSERT(pModelObj);
307 ScDocument* pDoc = pModelObj->GetDocument();
309 pDoc->SetString(0, 0, 0, u"A"_ustr);
310 pDoc->SetString(1, 0, 0, u"B"_ustr);
312 ScViewData* pViewData = ScDocShell::GetViewData();
313 CPPUNIT_ASSERT(pViewData);
314 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), pViewData->GetCurX());
315 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pViewData->GetCurY());
317 dispatchCommand(mxComponent, u".uno:SelectColumn"_ustr, {});
319 dispatchCommand(mxComponent, u".uno:InsertColumnsAfter"_ustr, {});
321 CPPUNIT_ASSERT_EQUAL(u"A"_ustr, pDoc->GetString(ScAddress(0, 0, 0)));
323 // Without the fix in place, this test would have failed with
324 // - Expected:
325 // - Actual : B
326 CPPUNIT_ASSERT_EQUAL(u""_ustr, pDoc->GetString(ScAddress(1, 0, 0)));
327 CPPUNIT_ASSERT_EQUAL(u"B"_ustr, pDoc->GetString(ScAddress(2, 0, 0)));
330 void ScJumboSheetsTest::testTdf133033()
332 mxComponent = loadFromDesktop(u"private:factory/scalc"_ustr);
333 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
334 CPPUNIT_ASSERT(pModelObj);
336 pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_DOWN | KEY_MOD1);
337 Scheduler::ProcessEventsToIdle();
339 ScViewData* pViewData = ScDocShell::GetViewData();
340 CPPUNIT_ASSERT(pViewData);
341 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), pViewData->GetCurX());
342 CPPUNIT_ASSERT_EQUAL(sal_Int32(16777215), pViewData->GetCurY());
345 void ScJumboSheetsTest::testTdf109061()
347 // Without the fix in place, the file would have crashed
348 loadFromFile(u"xlsx/tdf109061.xlsx");
350 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
351 CPPUNIT_ASSERT(pModelObj);
352 ScDocument* pDoc = pModelObj->GetDocument();
353 pDoc->CalcAll(); // perform hard re-calculation.
355 CPPUNIT_ASSERT_EQUAL(6.0, pDoc->GetValue(1, 3, 0));
358 ScJumboSheetsTest::ScJumboSheetsTest()
359 : UnoApiXmlTest(u"/sc/qa/unit/data/"_ustr)
363 void ScJumboSheetsTest::setUp()
365 UnoApiXmlTest::setUp();
367 //Init before GetDefaultsOptions
368 ScDLL::Init();
370 ScDefaultsOptions aDefaultsOption = SC_MOD()->GetDefaultsOptions();
371 aDefaultsOption.SetInitJumboSheets(true);
372 SC_MOD()->SetDefaultsOptions(aDefaultsOption);
375 void ScJumboSheetsTest::tearDown()
377 ScDefaultsOptions aDefaultsOption = SC_MOD()->GetDefaultsOptions();
378 aDefaultsOption.SetInitJumboSheets(false);
379 SC_MOD()->SetDefaultsOptions(aDefaultsOption);
381 UnoApiXmlTest::tearDown();
384 CPPUNIT_TEST_SUITE_REGISTRATION(ScJumboSheetsTest);
386 CPPUNIT_PLUGIN_IMPLEMENT();
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */