summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXisco Fauli <xiscofauli@libreoffice.org>2022-11-16 14:05:28 +0100
committerXisco Fauli <xiscofauli@libreoffice.org>2022-11-16 15:56:28 +0100
commit6eb9529abef9d7588899f9b241f31baa0b2beee2 (patch)
treeacb081bd35124611dfd90b36fc463324ee46d94e
parentd6ed1e058975f94aa0b79428f4d735095a68c74a (diff)
sc: move filter tests where they belong. (part 2)
Change-Id: I548d81dd7a7aa276d6936ab8d7bcc53a6cc91483 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142772 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r--sc/qa/unit/filters-test.cxx481
-rw-r--r--sc/qa/unit/subsequent_filters_test.cxx450
2 files changed, 451 insertions, 480 deletions
diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx
index 854f689b1a6f..31d8a9a1ef58 100644
--- a/sc/qa/unit/filters-test.cxx
+++ b/sc/qa/unit/filters-test.cxx
@@ -20,18 +20,13 @@
#include <drwlayer.hxx>
#include <userdat.hxx>
#include <formulacell.hxx>
-#include <tabprotection.hxx>
#include <testlotus.hxx>
-#include <dbdocfun.hxx>
-#include <globalnames.hxx>
#include <dbdata.hxx>
#include <sortparam.hxx>
#include <scerrors.hxx>
#include <scopetools.hxx>
-#include <scmod.hxx>
#include <undomanager.hxx>
-#include <svx/svdocapt.hxx>
#include <svx/svdpage.hxx>
#include <tools/stream.hxx>
@@ -47,9 +42,6 @@ class ScFiltersTest
public:
ScFiltersTest();
- virtual void setUp() override;
- virtual void tearDown() override;
-
virtual bool load( const OUString &rFilter, const OUString &rURL,
const OUString &rUserData, SfxFilterFlags nFilterFlags,
SotClipboardFormatId nClipboardID, unsigned int nFilterVersion) override;
@@ -58,45 +50,16 @@ public:
*/
void testCVEs();
- //ods, xls, xlsx filter tests
void testContentofz9704();
- void testSharedFormulaXLS();
- void testSharedFormulaXLSX();
- void testSharedFormulaRefUpdateXLSX();
- void testSheetNamesXLSX();
- void testTdf150599();
- void testCommentSize();
- void testEnhancedProtectionXLS();
- void testEnhancedProtectionXLSX();
- void testSortWithSharedFormulasODS();
- void testSortWithSheetExternalReferencesODS();
- void testSortWithSheetExternalReferencesODS_Impl( ScDocShellRef const & xDocShRef, SCROW nRow1, SCROW nRow2,
- bool bCheckRelativeInSheet );
- void testSortWithFormattingXLS();
void testTooManyColsRows();
- void testForcepoint107();
+
CPPUNIT_TEST_SUITE(ScFiltersTest);
CPPUNIT_TEST(testCVEs);
CPPUNIT_TEST(testContentofz9704);
- CPPUNIT_TEST(testSharedFormulaXLS);
- CPPUNIT_TEST(testSharedFormulaXLSX);
- CPPUNIT_TEST(testSharedFormulaRefUpdateXLSX);
- CPPUNIT_TEST(testSheetNamesXLSX);
- CPPUNIT_TEST(testTdf150599);
- CPPUNIT_TEST(testCommentSize);
- CPPUNIT_TEST(testEnhancedProtectionXLS);
- CPPUNIT_TEST(testEnhancedProtectionXLSX);
- CPPUNIT_TEST(testSortWithSharedFormulasODS);
- CPPUNIT_TEST(testSortWithSheetExternalReferencesODS);
- CPPUNIT_TEST(testSortWithFormattingXLS);
CPPUNIT_TEST(testTooManyColsRows);
- CPPUNIT_TEST(testForcepoint107);
CPPUNIT_TEST_SUITE_END();
-
-private:
- bool mbUpdateReferenceOnSort; ///< Remember the configuration option so that we can set it back.
};
bool ScFiltersTest::load(const OUString &rFilter, const OUString &rURL,
@@ -142,7 +105,6 @@ void ScFiltersTest::testCVEs()
#endif
}
-
void ScFiltersTest::testContentofz9704()
{
OUString aFileName;
@@ -151,416 +113,6 @@ void ScFiltersTest::testContentofz9704()
TestImportWKS(aFileStream);
}
-void ScFiltersTest::testSharedFormulaXLS()
-{
- ScDocShellRef xDocSh = loadDoc(u"shared-formula/basic.", FORMAT_XLS);
- ScDocument& rDoc = xDocSh->GetDocument();
- xDocSh->DoHardRecalc();
- // Check the results of formula cells in the shared formula range.
- for (SCROW i = 1; i <= 18; ++i)
- {
- double fVal = rDoc.GetValue(ScAddress(1,i,0));
- double fCheck = i*10.0;
- CPPUNIT_ASSERT_EQUAL(fCheck, fVal);
- }
-
- ScFormulaCell* pCell = rDoc.GetFormulaCell(ScAddress(1,18,0));
- CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pCell);
- ScFormulaCellGroupRef xGroup = pCell->GetCellGroup();
- CPPUNIT_ASSERT_MESSAGE("This cell should be a part of a cell group.", xGroup);
- CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect group geometry.", SCROW(1), xGroup->mpTopCell->aPos.Row());
- CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect group geometry.", SCROW(18), xGroup->mnLength);
-
- xDocSh->DoClose();
-
- // The following file contains shared formula whose range is inaccurate.
- // Excel can easily mess up shared formula ranges, so we need to be able
- // to handle these wrong ranges that Excel stores.
-
- xDocSh = loadDoc(u"shared-formula/gap.", FORMAT_XLS);
- ScDocument& rDoc2 = xDocSh->GetDocument();
- rDoc2.CalcAll();
-
- ASSERT_FORMULA_EQUAL(rDoc2, ScAddress(1,0,0), "A1*20", "Wrong formula.");
- ASSERT_FORMULA_EQUAL(rDoc2, ScAddress(1,1,0), "A2*20", "Wrong formula.");
- ASSERT_FORMULA_EQUAL(rDoc2, ScAddress(1,2,0), "A3*20", "Wrong formula.");
-
- // There is an intentional gap at row 4.
-
- ASSERT_FORMULA_EQUAL(rDoc2, ScAddress(1,4,0), "A5*20", "Wrong formula.");
- ASSERT_FORMULA_EQUAL(rDoc2, ScAddress(1,5,0), "A6*20", "Wrong formula.");
- ASSERT_FORMULA_EQUAL(rDoc2, ScAddress(1,6,0), "A7*20", "Wrong formula.");
- ASSERT_FORMULA_EQUAL(rDoc2, ScAddress(1,7,0), "A8*20", "Wrong formula.");
-
- // We re-group formula cells on load. Let's check that as well.
-
- ScFormulaCell* pFC = rDoc2.GetFormulaCell(ScAddress(1,0,0));
- CPPUNIT_ASSERT_MESSAGE("Failed to fetch formula cell.", pFC);
- CPPUNIT_ASSERT_MESSAGE("This should be the top cell in formula group.", pFC->IsSharedTop());
- CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(3), pFC->GetSharedLength());
-
- pFC = rDoc2.GetFormulaCell(ScAddress(1,4,0));
- CPPUNIT_ASSERT_MESSAGE("Failed to fetch formula cell.", pFC);
- CPPUNIT_ASSERT_MESSAGE("This should be the top cell in formula group.", pFC->IsSharedTop());
- CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
-
- xDocSh->DoClose();
-}
-
-void ScFiltersTest::testSharedFormulaXLSX()
-{
- ScDocShellRef xDocSh = loadDoc(u"shared-formula/basic.", FORMAT_XLSX);
- ScDocument& rDoc = xDocSh->GetDocument();
- xDocSh->DoHardRecalc();
- // Check the results of formula cells in the shared formula range.
- for (SCROW i = 1; i <= 18; ++i)
- {
- double fVal = rDoc.GetValue(ScAddress(1,i,0));
- double fCheck = i*10.0;
- CPPUNIT_ASSERT_EQUAL(fCheck, fVal);
- }
-
- ScFormulaCell* pCell = rDoc.GetFormulaCell(ScAddress(1,18,0));
- CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pCell);
- ScFormulaCellGroupRef xGroup = pCell->GetCellGroup();
- CPPUNIT_ASSERT_MESSAGE("This cell should be a part of a cell group.", xGroup);
- CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect group geometry.", SCROW(1), xGroup->mpTopCell->aPos.Row());
- CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect group geometry.", SCROW(18), xGroup->mnLength);
-
- xDocSh->DoClose();
-}
-
-void ScFiltersTest::testSharedFormulaRefUpdateXLSX()
-{
- ScDocShellRef xDocSh = loadDoc(u"shared-formula/refupdate.", FORMAT_XLSX);
- ScDocument& rDoc = xDocSh->GetDocument();
- sc::AutoCalcSwitch aACSwitch(rDoc, true); // turn auto calc on.
- rDoc.DeleteRow(ScRange(0, 4, 0, rDoc.MaxCol(), 4, 0)); // delete row 5.
-
- struct TestCase {
- ScAddress aPos;
- const char* pExpectedFormula;
- const char* pErrorMsg;
- };
-
- TestCase aCases[4] = {
- { ScAddress(1, 0, 0), "B29+1", "Wrong formula in B1" },
- { ScAddress(2, 0, 0), "C29+1", "Wrong formula in C1" },
- { ScAddress(3, 0, 0), "D29+1", "Wrong formula in D1" },
- { ScAddress(4, 0, 0), "E29+1", "Wrong formula in E1" },
- };
-
- for (size_t nIdx = 0; nIdx < 4; ++nIdx)
- {
- TestCase& rCase = aCases[nIdx];
- ASSERT_FORMULA_EQUAL(rDoc, rCase.aPos, rCase.pExpectedFormula, rCase.pErrorMsg);
- }
-
- xDocSh->DoClose();
-}
-
-void ScFiltersTest::testSheetNamesXLSX()
-{
- ScDocShellRef xDocSh = loadDoc(u"sheet-names.", FORMAT_XLSX);
- ScDocument& rDoc = xDocSh->GetDocument();
-
- std::vector<OUString> aTabNames = rDoc.GetAllTableNames();
- CPPUNIT_ASSERT_EQUAL_MESSAGE("The document should have 5 sheets in total.", size_t(5), aTabNames.size());
- CPPUNIT_ASSERT_EQUAL(OUString("S&P"), aTabNames[0]);
- CPPUNIT_ASSERT_EQUAL(OUString("Sam's Club"), aTabNames[1]);
- CPPUNIT_ASSERT_EQUAL(OUString("\"The Sheet\""), aTabNames[2]);
- CPPUNIT_ASSERT_EQUAL(OUString("A<B"), aTabNames[3]);
- CPPUNIT_ASSERT_EQUAL(OUString("C>D"), aTabNames[4]);
-
- xDocSh->DoClose();
-}
-
-
-void ScFiltersTest::testTdf150599()
-{
- ScDocShellRef xDocSh = loadDoc(u"tdf150599.", FORMAT_DIF);
- ScDocument& rDoc = xDocSh->GetDocument();
-
- // Without the fix in place, this test would have failed with
- // - Expected: 1
- // - Actual : #IND:?
- CPPUNIT_ASSERT_EQUAL(OUString("1"), rDoc.GetString(ScAddress(0, 0, 0)));
- CPPUNIT_ASSERT_EQUAL(OUString("32"), rDoc.GetString(ScAddress(31, 0, 0)));
-
- xDocSh->DoClose();
-}
-
-void ScFiltersTest::testCommentSize()
-{
- ScDocShellRef xDocSh = loadDoc(u"comment.", FORMAT_ODS);
- ScDocument& rDoc = xDocSh->GetDocument();
-
- ScAddress aPos(0,0,0);
- ScPostIt *pNote = rDoc.GetNote(aPos);
- CPPUNIT_ASSERT(pNote);
-
- pNote->ShowCaption(aPos, true);
- CPPUNIT_ASSERT(pNote->IsCaptionShown());
-
- SdrCaptionObj* pCaption = pNote->GetCaption();
- CPPUNIT_ASSERT(pCaption);
-
- const tools::Rectangle& rOldRect = pCaption->GetLogicRect();
- CPPUNIT_ASSERT_EQUAL(tools::Long(2899), rOldRect.getOpenWidth());
- CPPUNIT_ASSERT_EQUAL(tools::Long(939), rOldRect.getOpenHeight());
-
- pNote->SetText(aPos, "first\nsecond\nthird");
-
- const tools::Rectangle& rNewRect = pCaption->GetLogicRect();
- CPPUNIT_ASSERT_EQUAL(rOldRect.getOpenWidth(), rNewRect.getOpenWidth());
- CPPUNIT_ASSERT_EQUAL(tools::Long(1605), rNewRect.getOpenHeight());
-
- rDoc.GetUndoManager()->Undo();
-
- CPPUNIT_ASSERT_EQUAL(rOldRect.getOpenWidth(), pCaption->GetLogicRect().getOpenWidth());
- CPPUNIT_ASSERT_EQUAL(rOldRect.getOpenHeight(), pCaption->GetLogicRect().getOpenHeight());
-
- xDocSh->DoClose();
-}
-
-static void testEnhancedProtectionImpl( const ScDocument& rDoc )
-{
- const ScTableProtection* pProt = rDoc.GetTabProtection(0);
-
- CPPUNIT_ASSERT( pProt);
-
- CPPUNIT_ASSERT( !pProt->isBlockEditable( ScRange( 0, 0, 0, 0, 0, 0))); // locked
- CPPUNIT_ASSERT( pProt->isBlockEditable( ScRange( 0, 1, 0, 0, 1, 0))); // editable without password
- CPPUNIT_ASSERT( pProt->isBlockEditable( ScRange( 0, 2, 0, 0, 2, 0))); // editable without password
- CPPUNIT_ASSERT( !pProt->isBlockEditable( ScRange( 0, 3, 0, 0, 3, 0))); // editable with password "foo"
- CPPUNIT_ASSERT( !pProt->isBlockEditable( ScRange( 0, 4, 0, 0, 4, 0))); // editable with descriptor
- CPPUNIT_ASSERT( !pProt->isBlockEditable( ScRange( 0, 5, 0, 0, 5, 0))); // editable with descriptor and password "foo"
- CPPUNIT_ASSERT( pProt->isBlockEditable( ScRange( 0, 1, 0, 0, 2, 0))); // union of two different editables
- CPPUNIT_ASSERT( !pProt->isBlockEditable( ScRange( 0, 0, 0, 0, 1, 0))); // union of locked and editable
- CPPUNIT_ASSERT( !pProt->isBlockEditable( ScRange( 0, 2, 0, 0, 3, 0))); // union of editable and password editable
-}
-
-void ScFiltersTest::testEnhancedProtectionXLS()
-{
- ScDocShellRef xDocSh = loadDoc(u"enhanced-protection.", FORMAT_XLS);
- ScDocument& rDoc = xDocSh->GetDocument();
-
- testEnhancedProtectionImpl( rDoc);
-
- xDocSh->DoClose();
-}
-
-void ScFiltersTest::testEnhancedProtectionXLSX()
-{
- ScDocShellRef xDocSh = loadDoc(u"enhanced-protection.", FORMAT_XLSX);
- ScDocument& rDoc = xDocSh->GetDocument();
-
- testEnhancedProtectionImpl( rDoc);
-
- xDocSh->DoClose();
-}
-
-void ScFiltersTest::testSortWithSharedFormulasODS()
-{
- ScDocShellRef xDocSh = loadDoc(u"shared-formula/sort-crash.", FORMAT_ODS, true);
- ScDocument& rDoc = xDocSh->GetDocument();
-
- // E2:E10 should be shared.
- const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(4,1,0));
- CPPUNIT_ASSERT(pFC);
- CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
- CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(9), pFC->GetSharedLength());
-
- // E12:E17 should be shared.
- pFC = rDoc.GetFormulaCell(ScAddress(4,11,0));
- CPPUNIT_ASSERT(pFC);
- CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(11), pFC->GetSharedTopRow());
- CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(6), pFC->GetSharedLength());
-
- // Set A1:E17 as an anonymous database range to sheet, or else Calc would
- // refuse to sort the range.
- std::unique_ptr<ScDBData> pDBData(new ScDBData(STR_DB_LOCAL_NONAME, 0, 0, 0, 4, 16, true, true));
- rDoc.SetAnonymousDBData(0, std::move(pDBData));
-
- // Sort ascending by Column E.
-
- ScSortParam aSortData;
- aSortData.nCol1 = 0;
- aSortData.nCol2 = 4;
- aSortData.nRow1 = 0;
- aSortData.nRow2 = 16;
- aSortData.bHasHeader = true;
- aSortData.maKeyState[0].bDoSort = true;
- aSortData.maKeyState[0].nField = 4;
- aSortData.maKeyState[0].bAscending = true;
-
- // Do the sorting. This should not crash.
- ScDBDocFunc aFunc(*xDocSh);
- bool bSorted = aFunc.Sort(0, aSortData, true, true, true);
- CPPUNIT_ASSERT(bSorted);
-
- // After the sort, E2:E16 should be shared.
- pFC = rDoc.GetFormulaCell(ScAddress(4,1,0));
- CPPUNIT_ASSERT(pFC);
- CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
- CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(15), pFC->GetSharedLength());
-
- xDocSh->DoClose();
-}
-
-// https://bugs.freedesktop.org/attachment.cgi?id=100089 from fdo#77018
-// mentioned also in fdo#79441
-// Document contains cached external references.
-void ScFiltersTest::testSortWithSheetExternalReferencesODS()
-{
- ScDocShellRef xDocSh = loadDoc(u"sort-with-sheet-external-references.", FORMAT_ODS, true);
- ScDocument& rDoc = xDocSh->GetDocument();
- sc::AutoCalcSwitch aACSwitch(rDoc, true); // turn auto calc on.
- rDoc.CalcAll();
-
- // We reset the SortRefUpdate value back to the original in tearDown().
- ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
-
- // The complete relative test only works with UpdateReferenceOnSort==true,
- // but the internal and external sheet references have to work in both
- // modes.
-
- aInputOption.SetSortRefUpdate(true);
- SC_MOD()->SetInputOptions(aInputOption);
-
- // Sort A15:D20 with relative row references. UpdateReferenceOnSort==true
- // With in-sheet relative references.
- testSortWithSheetExternalReferencesODS_Impl( xDocSh, 14, 19, true);
-
- // Undo sort with relative references to perform same sort.
- rDoc.GetUndoManager()->Undo();
- rDoc.CalcAll();
-
- aInputOption.SetSortRefUpdate(false);
- SC_MOD()->SetInputOptions(aInputOption);
-
- // Sort A15:D20 with relative row references. UpdateReferenceOnSort==false
- // Without in-sheet relative references.
- testSortWithSheetExternalReferencesODS_Impl( xDocSh, 14, 19, false);
-
- // Undo sort with relative references to perform new sort.
- rDoc.GetUndoManager()->Undo();
- rDoc.CalcAll();
-
- // Sort with absolute references has to work in both UpdateReferenceOnSort
- // modes.
-
- aInputOption.SetSortRefUpdate(true);
- SC_MOD()->SetInputOptions(aInputOption);
-
- // Sort A23:D28 with absolute row references. UpdateReferenceOnSort==true
- // With in-sheet relative references.
- testSortWithSheetExternalReferencesODS_Impl( xDocSh, 22, 27, true);
-
- // Undo sort with absolute references to perform same sort.
- rDoc.GetUndoManager()->Undo();
- rDoc.CalcAll();
-
- aInputOption.SetSortRefUpdate(false);
- SC_MOD()->SetInputOptions(aInputOption);
-
- // Sort A23:D28 with absolute row references. UpdateReferenceOnSort==false
- // With in-sheet relative references.
- testSortWithSheetExternalReferencesODS_Impl( xDocSh, 22, 27, true);
-
- xDocSh->DoClose();
-}
-
-void ScFiltersTest::testSortWithSheetExternalReferencesODS_Impl( ScDocShellRef const & xDocSh, SCROW nRow1, SCROW nRow2,
- bool bCheckRelativeInSheet )
-{
- ScDocument& rDoc = xDocSh->GetDocument();
-
- // Check the original data is there.
- for (SCROW nRow=nRow1+1; nRow <= nRow2; ++nRow)
- {
- double const aCheck[] = { 1, 2, 3, 4, 5 };
- CPPUNIT_ASSERT_EQUAL( aCheck[nRow-nRow1-1], rDoc.GetValue( ScAddress(0,nRow,0)));
- }
- for (SCROW nRow=nRow1+1; nRow <= nRow2; ++nRow)
- {
- for (SCCOL nCol=1; nCol <= 3; ++nCol)
- {
- double const aCheck[] = { 1, 12, 123, 1234, 12345 };
- CPPUNIT_ASSERT_EQUAL( aCheck[nRow-nRow1-1], rDoc.GetValue( ScAddress(nCol,nRow,0)));
- }
- }
-
- // Set as an anonymous database range to sort.
- std::unique_ptr<ScDBData> pDBData(new ScDBData(STR_DB_LOCAL_NONAME, 0, 0, nRow1, 3, nRow2, true, true));
- rDoc.SetAnonymousDBData(0, std::move(pDBData));
-
- // Sort descending by Column A.
- ScSortParam aSortData;
- aSortData.nCol1 = 0;
- aSortData.nCol2 = 3;
- aSortData.nRow1 = nRow1;
- aSortData.nRow2 = nRow2;
- aSortData.bHasHeader = true;
- aSortData.maKeyState[0].bDoSort = true;
- aSortData.maKeyState[0].nField = 0;
- aSortData.maKeyState[0].bAscending = false;
-
- // Do the sorting.
- ScDBDocFunc aFunc(*xDocSh);
- bool bSorted = aFunc.Sort(0, aSortData, true, true, true);
- CPPUNIT_ASSERT(bSorted);
- rDoc.CalcAll();
-
- // Check the sort and that all sheet references and external references are
- // adjusted to point to the original location.
- for (SCROW nRow=nRow1+1; nRow <= nRow2; ++nRow)
- {
- double const aCheck[] = { 5, 4, 3, 2, 1 };
- CPPUNIT_ASSERT_EQUAL( aCheck[nRow-nRow1-1], rDoc.GetValue( ScAddress(0,nRow,0)));
- }
- // The last column (D) are in-sheet relative references.
- SCCOL nEndCol = (bCheckRelativeInSheet ? 3 : 2);
- for (SCROW nRow=nRow1+1; nRow <= nRow2; ++nRow)
- {
- for (SCCOL nCol=1; nCol <= nEndCol; ++nCol)
- {
- double const aCheck[] = { 12345, 1234, 123, 12, 1 };
- CPPUNIT_ASSERT_EQUAL( aCheck[nRow-nRow1-1], rDoc.GetValue( ScAddress(nCol,nRow,0)));
- }
- }
-}
-
-void ScFiltersTest::testSortWithFormattingXLS()
-{
- ScDocShellRef xDocSh = loadDoc(u"tdf129127.", FORMAT_XLS, true);
- ScDocument& rDoc = xDocSh->GetDocument();
-
- // Set as an anonymous database range to sort.
- std::unique_ptr<ScDBData> pDBData(
- new ScDBData(STR_DB_LOCAL_NONAME, 0, 0, 0, 4, 9, false, false));
- rDoc.SetAnonymousDBData(0, std::move(pDBData));
-
- // Sort ascending by Row 1
- ScSortParam aSortData;
- aSortData.nCol1 = 0;
- aSortData.nCol2 = 4;
- aSortData.nRow1 = 0;
- aSortData.nRow2 = 9;
- aSortData.bHasHeader = false;
- aSortData.bByRow = false;
- aSortData.maKeyState[0].bDoSort = true;
- aSortData.maKeyState[0].nField = 0;
- aSortData.maKeyState[0].bAscending = true;
-
- // Do the sorting.
- ScDBDocFunc aFunc(*xDocSh);
- // Without the fix, sort would crash.
- bool bSorted = aFunc.Sort(0, aSortData, true, true, true);
- CPPUNIT_ASSERT(bSorted);
- xDocSh->DoClose();
-}
-
void ScFiltersTest::testTooManyColsRows()
{
// The intentionally doc has cells beyond our MAXROW/MAXCOL, so there
@@ -578,42 +130,11 @@ void ScFiltersTest::testTooManyColsRows()
xDocSh->DoClose();
}
-// just needs to not crash on recalc
-void ScFiltersTest::testForcepoint107()
-{
- ScDocShellRef xDocSh = loadDoc(u"forcepoint107.", FORMAT_XLSX, true);
- xDocSh->DoHardRecalc();
-}
-
ScFiltersTest::ScFiltersTest()
: ScBootstrapFixture( "sc/qa/unit/data" )
- , mbUpdateReferenceOnSort(false)
{
}
-void ScFiltersTest::setUp()
-{
- ScBootstrapFixture::setUp();
-
- // one test sets this configuration option; make sure we remember the
- // original value
- ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
- mbUpdateReferenceOnSort = aInputOption.GetSortRefUpdate();
-}
-
-void ScFiltersTest::tearDown()
-{
- // one test sets this configuration option; make sure we return it back
- ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
- if (mbUpdateReferenceOnSort != aInputOption.GetSortRefUpdate())
- {
- aInputOption.SetSortRefUpdate(mbUpdateReferenceOnSort);
- SC_MOD()->SetInputOptions(aInputOption);
- }
-
- ScBootstrapFixture::tearDown();
-}
-
CPPUNIT_TEST_SUITE_REGISTRATION(ScFiltersTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/qa/unit/subsequent_filters_test.cxx b/sc/qa/unit/subsequent_filters_test.cxx
index 6874b7223076..d4f83e008b3b 100644
--- a/sc/qa/unit/subsequent_filters_test.cxx
+++ b/sc/qa/unit/subsequent_filters_test.cxx
@@ -14,6 +14,7 @@
#include <svl/zformat.hxx>
#include <svx/svdpage.hxx>
+#include <svx/svdocapt.hxx>
#include <svx/svdoole2.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/wghtitem.hxx>
@@ -29,8 +30,12 @@
#include <editeng/lineitem.hxx>
#include <editeng/colritem.hxx>
#include <dbdata.hxx>
+#include <dbdocfun.hxx>
+#include <inputopt.hxx>
+#include <globalnames.hxx>
#include <validat.hxx>
#include <userdat.hxx>
+#include <scmod.hxx>
#include <stlsheet.hxx>
#include <docfunc.hxx>
#include <markdata.hxx>
@@ -47,6 +52,7 @@
#include <postit.hxx>
#include <sortparam.hxx>
#include <undomanager.hxx>
+#include <tabprotection.hxx>
#include <orcusfilters.hxx>
#include <filter.hxx>
@@ -189,6 +195,18 @@ public:
void testTdf149484();
void testEscapedUnicodeXLSX();
void testTdf144758_DBDataDefaultOrientation();
+ void testSharedFormulaXLS();
+ void testSharedFormulaXLSX();
+ void testSharedFormulaRefUpdateXLSX();
+ void testSheetNamesXLSX();
+ void testTdf150599();
+ void testCommentSize();
+ void testEnhancedProtectionXLS();
+ void testEnhancedProtectionXLSX();
+ void testSortWithSharedFormulasODS();
+ void testSortWithSheetExternalReferencesODS();
+ void testSortWithFormattingXLS();
+ void testForcepoint107();
CPPUNIT_TEST_SUITE(ScFiltersTest);
CPPUNIT_TEST(testContentODS);
@@ -299,6 +317,18 @@ public:
CPPUNIT_TEST(testTdf149484);
CPPUNIT_TEST(testEscapedUnicodeXLSX);
CPPUNIT_TEST(testTdf144758_DBDataDefaultOrientation);
+ CPPUNIT_TEST(testSharedFormulaXLS);
+ CPPUNIT_TEST(testSharedFormulaXLSX);
+ CPPUNIT_TEST(testSharedFormulaRefUpdateXLSX);
+ CPPUNIT_TEST(testSheetNamesXLSX);
+ CPPUNIT_TEST(testTdf150599);
+ CPPUNIT_TEST(testCommentSize);
+ CPPUNIT_TEST(testEnhancedProtectionXLS);
+ CPPUNIT_TEST(testEnhancedProtectionXLSX);
+ CPPUNIT_TEST(testSortWithSharedFormulasODS);
+ CPPUNIT_TEST(testSortWithSheetExternalReferencesODS);
+ CPPUNIT_TEST(testSortWithFormattingXLS);
+ CPPUNIT_TEST(testForcepoint107);
CPPUNIT_TEST_SUITE_END();
@@ -3126,6 +3156,426 @@ void ScFiltersTest::testTdf144758_DBDataDefaultOrientation()
CPPUNIT_ASSERT(aSortParam.bByRow);
}
+void ScFiltersTest::testSharedFormulaXLS()
+{
+ createScDoc("xls/shared-formula/basic.xls");
+ ScDocument* pDoc = getScDoc();
+ ScDocShell* pDocSh = getScDocShell();
+ pDocSh->DoHardRecalc();
+ // Check the results of formula cells in the shared formula range.
+ for (SCROW i = 1; i <= 18; ++i)
+ {
+ double fVal = pDoc->GetValue(ScAddress(1, i, 0));
+ double fCheck = i * 10.0;
+ CPPUNIT_ASSERT_EQUAL(fCheck, fVal);
+ }
+
+ ScFormulaCell* pCell = pDoc->GetFormulaCell(ScAddress(1, 18, 0));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pCell);
+ ScFormulaCellGroupRef xGroup = pCell->GetCellGroup();
+ CPPUNIT_ASSERT_MESSAGE("This cell should be a part of a cell group.", xGroup);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect group geometry.", SCROW(1),
+ xGroup->mpTopCell->aPos.Row());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect group geometry.", SCROW(18), xGroup->mnLength);
+
+ // The following file contains shared formula whose range is inaccurate.
+ // Excel can easily mess up shared formula ranges, so we need to be able
+ // to handle these wrong ranges that Excel stores.
+
+ createScDoc("xls/shared-formula/gap.xls");
+ pDoc = getScDoc();
+ pDoc->CalcAll();
+
+ ASSERT_FORMULA_EQUAL(*pDoc, ScAddress(1, 0, 0), "A1*20", "Wrong formula.");
+ ASSERT_FORMULA_EQUAL(*pDoc, ScAddress(1, 1, 0), "A2*20", "Wrong formula.");
+ ASSERT_FORMULA_EQUAL(*pDoc, ScAddress(1, 2, 0), "A3*20", "Wrong formula.");
+
+ // There is an intentional gap at row 4.
+
+ ASSERT_FORMULA_EQUAL(*pDoc, ScAddress(1, 4, 0), "A5*20", "Wrong formula.");
+ ASSERT_FORMULA_EQUAL(*pDoc, ScAddress(1, 5, 0), "A6*20", "Wrong formula.");
+ ASSERT_FORMULA_EQUAL(*pDoc, ScAddress(1, 6, 0), "A7*20", "Wrong formula.");
+ ASSERT_FORMULA_EQUAL(*pDoc, ScAddress(1, 7, 0), "A8*20", "Wrong formula.");
+
+ // We re-group formula cells on load. Let's check that as well.
+
+ ScFormulaCell* pFC = pDoc->GetFormulaCell(ScAddress(1, 0, 0));
+ CPPUNIT_ASSERT_MESSAGE("Failed to fetch formula cell.", pFC);
+ CPPUNIT_ASSERT_MESSAGE("This should be the top cell in formula group.", pFC->IsSharedTop());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(3), pFC->GetSharedLength());
+
+ pFC = pDoc->GetFormulaCell(ScAddress(1, 4, 0));
+ CPPUNIT_ASSERT_MESSAGE("Failed to fetch formula cell.", pFC);
+ CPPUNIT_ASSERT_MESSAGE("This should be the top cell in formula group.", pFC->IsSharedTop());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
+}
+
+void ScFiltersTest::testSharedFormulaXLSX()
+{
+ createScDoc("xlsx/shared-formula/basic.xlsx");
+ ScDocument* pDoc = getScDoc();
+ ScDocShell* pDocSh = getScDocShell();
+ pDocSh->DoHardRecalc();
+ // Check the results of formula cells in the shared formula range.
+ for (SCROW i = 1; i <= 18; ++i)
+ {
+ double fVal = pDoc->GetValue(ScAddress(1, i, 0));
+ double fCheck = i * 10.0;
+ CPPUNIT_ASSERT_EQUAL(fCheck, fVal);
+ }
+
+ ScFormulaCell* pCell = pDoc->GetFormulaCell(ScAddress(1, 18, 0));
+ CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pCell);
+ ScFormulaCellGroupRef xGroup = pCell->GetCellGroup();
+ CPPUNIT_ASSERT_MESSAGE("This cell should be a part of a cell group.", xGroup);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect group geometry.", SCROW(1),
+ xGroup->mpTopCell->aPos.Row());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect group geometry.", SCROW(18), xGroup->mnLength);
+}
+
+void ScFiltersTest::testSharedFormulaRefUpdateXLSX()
+{
+ createScDoc("xlsx/shared-formula/refupdate.xlsx");
+ ScDocument* pDoc = getScDoc();
+ sc::AutoCalcSwitch aACSwitch(*pDoc, true); // turn auto calc on.
+ pDoc->DeleteRow(ScRange(0, 4, 0, pDoc->MaxCol(), 4, 0)); // delete row 5.
+
+ struct TestCase
+ {
+ ScAddress aPos;
+ const char* pExpectedFormula;
+ const char* pErrorMsg;
+ };
+
+ TestCase aCases[4] = {
+ { ScAddress(1, 0, 0), "B29+1", "Wrong formula in B1" },
+ { ScAddress(2, 0, 0), "C29+1", "Wrong formula in C1" },
+ { ScAddress(3, 0, 0), "D29+1", "Wrong formula in D1" },
+ { ScAddress(4, 0, 0), "E29+1", "Wrong formula in E1" },
+ };
+
+ for (size_t nIdx = 0; nIdx < 4; ++nIdx)
+ {
+ TestCase& rCase = aCases[nIdx];
+ ASSERT_FORMULA_EQUAL(*pDoc, rCase.aPos, rCase.pExpectedFormula, rCase.pErrorMsg);
+ }
+}
+
+void ScFiltersTest::testSheetNamesXLSX()
+{
+ createScDoc("xlsx/sheet-names.xlsx");
+ ScDocument* pDoc = getScDoc();
+
+ std::vector<OUString> aTabNames = pDoc->GetAllTableNames();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("The document should have 5 sheets in total.", size_t(5),
+ aTabNames.size());
+ CPPUNIT_ASSERT_EQUAL(OUString("S&P"), aTabNames[0]);
+ CPPUNIT_ASSERT_EQUAL(OUString("Sam's Club"), aTabNames[1]);
+ CPPUNIT_ASSERT_EQUAL(OUString("\"The Sheet\""), aTabNames[2]);
+ CPPUNIT_ASSERT_EQUAL(OUString("A<B"), aTabNames[3]);
+ CPPUNIT_ASSERT_EQUAL(OUString("C>D"), aTabNames[4]);
+}
+
+void ScFiltersTest::testTdf150599()
+{
+ createScDoc("dif/tdf150599.dif");
+ ScDocument* pDoc = getScDoc();
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: 1
+ // - Actual : #IND:?
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), pDoc->GetString(ScAddress(0, 0, 0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("32"), pDoc->GetString(ScAddress(31, 0, 0)));
+}
+
+void ScFiltersTest::testCommentSize()
+{
+ createScDoc("ods/comment.ods");
+ ScDocument* pDoc = getScDoc();
+
+ ScAddress aPos(0, 0, 0);
+ ScPostIt* pNote = pDoc->GetNote(aPos);
+ CPPUNIT_ASSERT(pNote);
+
+ pNote->ShowCaption(aPos, true);
+ CPPUNIT_ASSERT(pNote->IsCaptionShown());
+
+ SdrCaptionObj* pCaption = pNote->GetCaption();
+ CPPUNIT_ASSERT(pCaption);
+
+ const tools::Rectangle& rOldRect = pCaption->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(tools::Long(2899), rOldRect.getOpenWidth());
+ CPPUNIT_ASSERT_EQUAL(tools::Long(939), rOldRect.getOpenHeight());
+
+ pNote->SetText(aPos, "first\nsecond\nthird");
+
+ const tools::Rectangle& rNewRect = pCaption->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(rOldRect.getOpenWidth(), rNewRect.getOpenWidth());
+ CPPUNIT_ASSERT_EQUAL(tools::Long(1605), rNewRect.getOpenHeight());
+
+ pDoc->GetUndoManager()->Undo();
+
+ CPPUNIT_ASSERT_EQUAL(rOldRect.getOpenWidth(), pCaption->GetLogicRect().getOpenWidth());
+ CPPUNIT_ASSERT_EQUAL(rOldRect.getOpenHeight(), pCaption->GetLogicRect().getOpenHeight());
+}
+
+static void testEnhancedProtectionImpl(const ScDocument& rDoc)
+{
+ const ScTableProtection* pProt = rDoc.GetTabProtection(0);
+
+ CPPUNIT_ASSERT(pProt);
+
+ CPPUNIT_ASSERT(!pProt->isBlockEditable(ScRange(0, 0, 0, 0, 0, 0))); // locked
+ CPPUNIT_ASSERT(pProt->isBlockEditable(ScRange(0, 1, 0, 0, 1, 0))); // editable without password
+ CPPUNIT_ASSERT(pProt->isBlockEditable(ScRange(0, 2, 0, 0, 2, 0))); // editable without password
+ CPPUNIT_ASSERT(
+ !pProt->isBlockEditable(ScRange(0, 3, 0, 0, 3, 0))); // editable with password "foo"
+ CPPUNIT_ASSERT(!pProt->isBlockEditable(ScRange(0, 4, 0, 0, 4, 0))); // editable with descriptor
+ CPPUNIT_ASSERT(!pProt->isBlockEditable(
+ ScRange(0, 5, 0, 0, 5, 0))); // editable with descriptor and password "foo"
+ CPPUNIT_ASSERT(
+ pProt->isBlockEditable(ScRange(0, 1, 0, 0, 2, 0))); // union of two different editables
+ CPPUNIT_ASSERT(
+ !pProt->isBlockEditable(ScRange(0, 0, 0, 0, 1, 0))); // union of locked and editable
+ CPPUNIT_ASSERT(!pProt->isBlockEditable(
+ ScRange(0, 2, 0, 0, 3, 0))); // union of editable and password editable
+}
+
+void ScFiltersTest::testEnhancedProtectionXLS()
+{
+ createScDoc("xls/enhanced-protection.xls");
+ ScDocument* pDoc = getScDoc();
+
+ testEnhancedProtectionImpl(*pDoc);
+}
+
+void ScFiltersTest::testEnhancedProtectionXLSX()
+{
+ createScDoc("xlsx/enhanced-protection.xlsx");
+ ScDocument* pDoc = getScDoc();
+
+ testEnhancedProtectionImpl(*pDoc);
+}
+
+void ScFiltersTest::testSortWithSharedFormulasODS()
+{
+ createScDoc("ods/shared-formula/sort-crash.ods");
+ ScDocument* pDoc = getScDoc();
+
+ // E2:E10 should be shared.
+ const ScFormulaCell* pFC = pDoc->GetFormulaCell(ScAddress(4, 1, 0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(9), pFC->GetSharedLength());
+
+ // E12:E17 should be shared.
+ pFC = pDoc->GetFormulaCell(ScAddress(4, 11, 0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(11), pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(6), pFC->GetSharedLength());
+
+ // Set A1:E17 as an anonymous database range to sheet, or else Calc would
+ // refuse to sort the range.
+ std::unique_ptr<ScDBData> pDBData(
+ new ScDBData(STR_DB_LOCAL_NONAME, 0, 0, 0, 4, 16, true, true));
+ pDoc->SetAnonymousDBData(0, std::move(pDBData));
+
+ // Sort ascending by Column E.
+
+ ScSortParam aSortData;
+ aSortData.nCol1 = 0;
+ aSortData.nCol2 = 4;
+ aSortData.nRow1 = 0;
+ aSortData.nRow2 = 16;
+ aSortData.bHasHeader = true;
+ aSortData.maKeyState[0].bDoSort = true;
+ aSortData.maKeyState[0].nField = 4;
+ aSortData.maKeyState[0].bAscending = true;
+
+ // Do the sorting. This should not crash.
+ ScDocShell* pDocSh = getScDocShell();
+ ScDBDocFunc aFunc(*pDocSh);
+ bool bSorted = aFunc.Sort(0, aSortData, true, true, true);
+ CPPUNIT_ASSERT(bSorted);
+
+ // After the sort, E2:E16 should be shared.
+ pFC = pDoc->GetFormulaCell(ScAddress(4, 1, 0));
+ CPPUNIT_ASSERT(pFC);
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(15), pFC->GetSharedLength());
+}
+
+namespace
+{
+void testSortWithSheetExternalReferencesODS_Impl(ScDocShell& rDocSh, SCROW nRow1, SCROW nRow2,
+ bool bCheckRelativeInSheet)
+{
+ ScDocument& rDoc = rDocSh.GetDocument();
+
+ // Check the original data is there.
+ for (SCROW nRow = nRow1 + 1; nRow <= nRow2; ++nRow)
+ {
+ double const aCheck[] = { 1, 2, 3, 4, 5 };
+ CPPUNIT_ASSERT_EQUAL(aCheck[nRow - nRow1 - 1], rDoc.GetValue(ScAddress(0, nRow, 0)));
+ }
+ for (SCROW nRow = nRow1 + 1; nRow <= nRow2; ++nRow)
+ {
+ for (SCCOL nCol = 1; nCol <= 3; ++nCol)
+ {
+ double const aCheck[] = { 1, 12, 123, 1234, 12345 };
+ CPPUNIT_ASSERT_EQUAL(aCheck[nRow - nRow1 - 1], rDoc.GetValue(ScAddress(nCol, nRow, 0)));
+ }
+ }
+
+ // Set as an anonymous database range to sort.
+ std::unique_ptr<ScDBData> pDBData(
+ new ScDBData(STR_DB_LOCAL_NONAME, 0, 0, nRow1, 3, nRow2, true, true));
+ rDoc.SetAnonymousDBData(0, std::move(pDBData));
+
+ // Sort descending by Column A.
+ ScSortParam aSortData;
+ aSortData.nCol1 = 0;
+ aSortData.nCol2 = 3;
+ aSortData.nRow1 = nRow1;
+ aSortData.nRow2 = nRow2;
+ aSortData.bHasHeader = true;
+ aSortData.maKeyState[0].bDoSort = true;
+ aSortData.maKeyState[0].nField = 0;
+ aSortData.maKeyState[0].bAscending = false;
+
+ // Do the sorting.
+ ScDBDocFunc aFunc(rDocSh);
+ bool bSorted = aFunc.Sort(0, aSortData, true, true, true);
+ CPPUNIT_ASSERT(bSorted);
+ rDoc.CalcAll();
+
+ // Check the sort and that all sheet references and external references are
+ // adjusted to point to the original location.
+ for (SCROW nRow = nRow1 + 1; nRow <= nRow2; ++nRow)
+ {
+ double const aCheck[] = { 5, 4, 3, 2, 1 };
+ CPPUNIT_ASSERT_EQUAL(aCheck[nRow - nRow1 - 1], rDoc.GetValue(ScAddress(0, nRow, 0)));
+ }
+ // The last column (D) are in-sheet relative references.
+ SCCOL nEndCol = (bCheckRelativeInSheet ? 3 : 2);
+ for (SCROW nRow = nRow1 + 1; nRow <= nRow2; ++nRow)
+ {
+ for (SCCOL nCol = 1; nCol <= nEndCol; ++nCol)
+ {
+ double const aCheck[] = { 12345, 1234, 123, 12, 1 };
+ CPPUNIT_ASSERT_EQUAL(aCheck[nRow - nRow1 - 1], rDoc.GetValue(ScAddress(nCol, nRow, 0)));
+ }
+ }
+}
+}
+
+// https://bugs.freedesktop.org/attachment.cgi?id=100089 from fdo#77018
+// mentioned also in fdo#79441
+// Document contains cached external references.
+void ScFiltersTest::testSortWithSheetExternalReferencesODS()
+{
+ // We reset the SortRefUpdate value back to the original in tearDown().
+ ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
+ bool bUpdateReferenceOnSort = aInputOption.GetSortRefUpdate();
+
+ createScDoc("ods/sort-with-sheet-external-references.ods");
+ ScDocument* pDoc = getScDoc();
+ sc::AutoCalcSwitch aACSwitch(*pDoc, true); // turn auto calc on.
+ pDoc->CalcAll();
+
+ // The complete relative test only works with UpdateReferenceOnSort==true,
+ // but the internal and external sheet references have to work in both
+ // modes.
+
+ aInputOption.SetSortRefUpdate(true);
+ SC_MOD()->SetInputOptions(aInputOption);
+
+ // Sort A15:D20 with relative row references. UpdateReferenceOnSort==true
+ // With in-sheet relative references.
+ ScDocShell* pDocSh = getScDocShell();
+ testSortWithSheetExternalReferencesODS_Impl(*pDocSh, 14, 19, true);
+
+ // Undo sort with relative references to perform same sort.
+ pDoc->GetUndoManager()->Undo();
+ pDoc->CalcAll();
+
+ aInputOption.SetSortRefUpdate(false);
+ SC_MOD()->SetInputOptions(aInputOption);
+
+ // Sort A15:D20 with relative row references. UpdateReferenceOnSort==false
+ // Without in-sheet relative references.
+ testSortWithSheetExternalReferencesODS_Impl(*pDocSh, 14, 19, false);
+
+ // Undo sort with relative references to perform new sort.
+ pDoc->GetUndoManager()->Undo();
+ pDoc->CalcAll();
+
+ // Sort with absolute references has to work in both UpdateReferenceOnSort
+ // modes.
+
+ aInputOption.SetSortRefUpdate(true);
+ SC_MOD()->SetInputOptions(aInputOption);
+
+ // Sort A23:D28 with absolute row references. UpdateReferenceOnSort==true
+ // With in-sheet relative references.
+ testSortWithSheetExternalReferencesODS_Impl(*pDocSh, 22, 27, true);
+
+ // Undo sort with absolute references to perform same sort.
+ pDoc->GetUndoManager()->Undo();
+ pDoc->CalcAll();
+
+ aInputOption.SetSortRefUpdate(false);
+ SC_MOD()->SetInputOptions(aInputOption);
+
+ // Sort A23:D28 with absolute row references. UpdateReferenceOnSort==false
+ // With in-sheet relative references.
+ testSortWithSheetExternalReferencesODS_Impl(*pDocSh, 22, 27, true);
+
+ if (bUpdateReferenceOnSort != aInputOption.GetSortRefUpdate())
+ {
+ aInputOption.SetSortRefUpdate(bUpdateReferenceOnSort);
+ SC_MOD()->SetInputOptions(aInputOption);
+ }
+}
+
+void ScFiltersTest::testSortWithFormattingXLS()
+{
+ createScDoc("xls/tdf129127.xls");
+ ScDocument* pDoc = getScDoc();
+
+ // Set as an anonymous database range to sort.
+ std::unique_ptr<ScDBData> pDBData(
+ new ScDBData(STR_DB_LOCAL_NONAME, 0, 0, 0, 4, 9, false, false));
+ pDoc->SetAnonymousDBData(0, std::move(pDBData));
+
+ // Sort ascending by Row 1
+ ScSortParam aSortData;
+ aSortData.nCol1 = 0;
+ aSortData.nCol2 = 4;
+ aSortData.nRow1 = 0;
+ aSortData.nRow2 = 9;
+ aSortData.bHasHeader = false;
+ aSortData.bByRow = false;
+ aSortData.maKeyState[0].bDoSort = true;
+ aSortData.maKeyState[0].nField = 0;
+ aSortData.maKeyState[0].bAscending = true;
+
+ // Do the sorting.
+ ScDocShell* pDocSh = getScDocShell();
+ ScDBDocFunc aFunc(*pDocSh);
+ // Without the fix, sort would crash.
+ bool bSorted = aFunc.Sort(0, aSortData, true, true, true);
+ CPPUNIT_ASSERT(bSorted);
+}
+
+// just needs to not crash on recalc
+void ScFiltersTest::testForcepoint107()
+{
+ createScDoc("xlsx/forcepoint107.xlsx");
+ ScDocShell* pDocSh = getScDocShell();
+ pDocSh->DoHardRecalc();
+}
+
ScFiltersTest::ScFiltersTest()
: ScModelTestBase("sc/qa/unit/data")
{