From 3a572975704a0d01e458191e8d66ff20ef60e4a8 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 12 Apr 2017 21:32:56 -0400 Subject: tdf#92650: add a unit test for this. Also add a modern C++11 version of checkOutput(), which should be used instead of the older variant that is a template function. Change-Id: I64706baf531c557c3631c998122515e40d555cf6 Reviewed-on: https://gerrit.libreoffice.org/36497 Tested-by: Jenkins Reviewed-by: Kohei Yoshida --- sc/qa/unit/helper/qahelper.cxx | 38 +++++++++++++++++++++++++ sc/qa/unit/helper/qahelper.hxx | 4 +++ sc/qa/unit/ucalc.hxx | 2 ++ sc/qa/unit/ucalc_formula.cxx | 63 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/sc/qa/unit/helper/qahelper.cxx b/sc/qa/unit/helper/qahelper.cxx index 3c4a42c3f919..f3cb007f0e9d 100644 --- a/sc/qa/unit/helper/qahelper.cxx +++ b/sc/qa/unit/helper/qahelper.cxx @@ -490,6 +490,44 @@ ScTokenArray* compileFormula( return aComp.CompileString(rFormula); } +bool checkOutput( + ScDocument* pDoc, const ScRange& aOutRange, + const std::vector>& aCheck, const char* pCaption ) +{ + bool bResult = true; + const ScAddress& s = aOutRange.aStart; + const ScAddress& e = aOutRange.aEnd; + svl::GridPrinter printer(e.Row() - s.Row() + 1, e.Col() - s.Col() + 1, CALC_DEBUG_OUTPUT != 0); + SCROW nOutRowSize = e.Row() - s.Row() + 1; + SCCOL nOutColSize = e.Col() - s.Col() + 1; + for (SCROW nRow = 0; nRow < nOutRowSize; ++nRow) + { + for (SCCOL nCol = 0; nCol < nOutColSize; ++nCol) + { + OUString aVal = pDoc->GetString(nCol + s.Col(), nRow + s.Row(), s.Tab()); + printer.set(nRow, nCol, aVal); + const char* p = aCheck[nRow][nCol]; + if (p) + { + OUString aCheckVal = OUString::createFromAscii(p); + bool bEqual = aCheckVal.equals(aVal); + if (!bEqual) + { + std::cout << "Expected: " << aCheckVal << " Actual: " << aVal << std::endl; + bResult = false; + } + } + else if (!aVal.isEmpty()) + { + std::cout << "Empty cell expected" << std::endl; + bResult = false; + } + } + } + printer.print(pCaption); + return bResult; +} + void clearFormulaCellChangedFlag( ScDocument& rDoc, const ScRange& rRange ) { const ScAddress& s = rRange.aStart; diff --git a/sc/qa/unit/helper/qahelper.hxx b/sc/qa/unit/helper/qahelper.hxx index 8ffcb047919c..cc4f5d40adc3 100644 --- a/sc/qa/unit/helper/qahelper.hxx +++ b/sc/qa/unit/helper/qahelper.hxx @@ -140,6 +140,10 @@ SCQAHELPER_DLLPUBLIC ScTokenArray* compileFormula( ScDocument* pDoc, const OUString& rFormula, const ScAddress* pPos = nullptr, formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_NATIVE ); +SCQAHELPER_DLLPUBLIC bool checkOutput( + ScDocument* pDoc, const ScRange& aOutRange, + const std::vector>& aCheck, const char* pCaption ); + template bool checkOutput(ScDocument* pDoc, const ScRange& aOutRange, const char* aOutputCheck[][Size], const char* pCaption) { diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 8a05d9653508..486bb1064e89 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -151,6 +151,7 @@ public: void testFormulaRefUpdateInsertColumns(); void testFormulaRefUpdateMove(); void testFormulaRefUpdateMoveUndo(); + void testFormulaRefUpdateMoveUndo2(); void testFormulaRefUpdateMoveToSheet(); void testFormulaRefUpdateDeleteContent(); void testFormulaRefUpdateDeleteAndShiftLeft(); @@ -554,6 +555,7 @@ public: CPPUNIT_TEST(testFormulaRefUpdateInsertColumns); CPPUNIT_TEST(testFormulaRefUpdateMove); CPPUNIT_TEST(testFormulaRefUpdateMoveUndo); + CPPUNIT_TEST(testFormulaRefUpdateMoveUndo2); CPPUNIT_TEST(testFormulaRefUpdateMoveToSheet); CPPUNIT_TEST(testFormulaRefUpdateDeleteContent); CPPUNIT_TEST(testFormulaRefUpdateDeleteAndShiftLeft); diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index 045e6976b9d8..9240320fac2a 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -2263,6 +2263,69 @@ void Test::testFormulaRefUpdateMoveUndo() m_pDoc->DeleteTab(0); } +void Test::testFormulaRefUpdateMoveUndo2() +{ + m_pDoc->InsertTab(0, "Test"); + + sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on. + + std::vector> aData = { + { "1", "2", "=A2*10", "=SUM(A1:B1)" }, + { "3", "4", "=SUM(A2:B2)", "=SUM(A2:B2)" }, + { "=SUM(A1:B1)" }, + }; + + ScRange aOutRange = insertRangeData(m_pDoc, ScAddress(0,0,0), aData); + + std::vector> aCheckInitial = { + { "1", "2", "30", "3" }, + { "3", "4", "7", "7" }, + { "3", nullptr, nullptr, nullptr }, + }; + + bool bGood = checkOutput(m_pDoc, aOutRange, aCheckInitial, "initial data"); + CPPUNIT_ASSERT(bGood); + + // D1:D2 should be grouped. + const ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(3,0,0)); + CPPUNIT_ASSERT(pFC); + CPPUNIT_ASSERT_EQUAL(SCROW(2), pFC->GetSharedLength()); + + // Drag A1:B1 into A2:B2 thereby overwriting the old A2:B2 content. + ScDocFunc& rFunc = getDocShell().GetDocFunc(); + rFunc.MoveBlock(ScRange(0,0,0,1,0,0), ScAddress(0,1,0), true, true, false, true); + + std::vector> aCheckAfter = { + { nullptr, nullptr, "10", "3" }, + { "1", "2", "3", "3" }, + { "3", nullptr, nullptr, nullptr }, + }; + + bGood = checkOutput(m_pDoc, aOutRange, aCheckAfter, "A1:B1 moved to A2:B2"); + CPPUNIT_ASSERT(bGood); + + // Undo the move. + SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager(); + CPPUNIT_ASSERT(pUndoMgr); + pUndoMgr->Undo(); + + bGood = checkOutput(m_pDoc, aOutRange, aCheckInitial, "after undo"); + CPPUNIT_ASSERT(bGood); + + // D1:D2 should be grouped. + pFC = m_pDoc->GetFormulaCell(ScAddress(3,0,0)); + CPPUNIT_ASSERT(pFC); + CPPUNIT_ASSERT_EQUAL(SCROW(2), pFC->GetSharedLength()); + + // Redo and check. + pUndoMgr->Redo(); + + bGood = checkOutput(m_pDoc, aOutRange, aCheckAfter, "after redo"); + CPPUNIT_ASSERT(bGood); + + m_pDoc->DeleteTab(0); +} + void Test::testFormulaRefUpdateMoveToSheet() { sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on. -- cgit v1.2.3