diff options
author | Dennis Francis <dennis.francis@collabora.co.uk> | 2018-02-07 12:00:47 +0530 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2018-04-28 13:33:55 +0200 |
commit | 67b1c26c27590678ece7bcef763433aedd0b164d (patch) | |
tree | efed6b3c2c2a6db724d0aa60dcde735d5d10ac4a /sc/qa | |
parent | 212807f77b78c69263f8aae51dcdc73e8017c53a (diff) |
tdf#114479: compute implicit sum ranges for ocSumIf,ocAverageIf...
and update the sum-range token in RPN array while creation of
the RPN array itself.
+ Adds unit tests.
+ In ScParallelismTest unit test, enable threading in its setUp()
method and restore the original setting in tearDown().
Change-Id: Iee9b7759210a82950181a418eb92766a6cf891fc
Reviewed-on: https://gerrit.libreoffice.org/49465
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sc/qa')
-rw-r--r-- | sc/qa/unit/parallelism.cxx | 79 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.hxx | 2 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_formula.cxx | 126 |
3 files changed, 207 insertions, 0 deletions
diff --git a/sc/qa/unit/parallelism.cxx b/sc/qa/unit/parallelism.cxx index ca6dce5c9f2f..c5c196154123 100644 --- a/sc/qa/unit/parallelism.cxx +++ b/sc/qa/unit/parallelism.cxx @@ -27,9 +27,12 @@ #include <userdat.hxx> #include <formulacell.hxx> #include <formulagroup.hxx> +#include <scopetools.hxx> #include <svx/svdpage.hxx> +#include <officecfg/Office/Calc.hxx> + using namespace css; using namespace css::uno; @@ -39,6 +42,7 @@ public: ScParallelismTest(); virtual void setUp() override; + virtual void tearDown() override; void getNewDocShell(ScDocShellRef& rDocShellRef); @@ -47,6 +51,7 @@ public: void testVLOOKUP(); void testVLOOKUPSUM(); void testSingleRef(); + void testSUMIFImplicitRange(); CPPUNIT_TEST_SUITE(ScParallelismTest); CPPUNIT_TEST(testSUMIFS); @@ -54,12 +59,18 @@ public: CPPUNIT_TEST(testVLOOKUP); CPPUNIT_TEST(testVLOOKUPSUM); CPPUNIT_TEST(testSingleRef); + CPPUNIT_TEST(testSUMIFImplicitRange); CPPUNIT_TEST_SUITE_END(); private: + + bool getThreadingFlag(); + void setThreadingFlag(bool bSet); + ScDocument *m_pDoc; ScDocShellRef m_xDocShell; + bool m_bThreadingFlagCfg; }; ScParallelismTest::ScParallelismTest() @@ -67,6 +78,18 @@ ScParallelismTest::ScParallelismTest() { } +bool ScParallelismTest::getThreadingFlag() +{ + return officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get(); +} + +void ScParallelismTest::setThreadingFlag( bool bSet ) +{ + std::shared_ptr<comphelper::ConfigurationChanges> xBatch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::set(bSet, xBatch); + xBatch->commit(); +} + void ScParallelismTest::setUp() { test::BootstrapFixture::setUp(); @@ -77,6 +100,19 @@ void ScParallelismTest::setUp() m_pDoc = &m_xDocShell->GetDocument(); sc::FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly(); + + m_bThreadingFlagCfg = getThreadingFlag(); + if (!m_bThreadingFlagCfg) + setThreadingFlag(true); +} + +void ScParallelismTest::tearDown() +{ + // Restore threading flag + if (!m_bThreadingFlagCfg) + setThreadingFlag(false); + + test::BootstrapFixture::tearDown(); } void ScParallelismTest::getNewDocShell( ScDocShellRef& rDocShellRef ) @@ -317,6 +353,49 @@ void ScParallelismTest::testSingleRef() m_pDoc->DeleteTab(0); } +// Common test setup steps for testSUMIFImplicitRange*() +void lcl_setupCommon(ScDocument* pDoc, size_t nNumRows, size_t nConstCellValue) +{ + pDoc->SetValue(3, 0, 0, static_cast<double>(nConstCellValue)); // D1 + for (size_t i = 0; i <= (nNumRows*2); ++i) + { + pDoc->SetValue(0, i, 0, static_cast<double>(i)); + pDoc->SetFormula(ScAddress(1, i, 0), + "=A" + OUString::number(i+1), + formula::FormulaGrammar::GRAM_NATIVE_UI); + } +} + +void ScParallelismTest::testSUMIFImplicitRange() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); + m_pDoc->InsertTab(0, "1"); + + const size_t nNumRows = 1048; + const size_t nConstCellValue = 20; + lcl_setupCommon(m_pDoc, nNumRows, nConstCellValue); + OUString aSrcRange = "$A$1:$A$" + OUString::number(nNumRows); + OUString aFormula; + for (size_t i = 0; i < nNumRows; ++i) + { + aFormula = "=SUMIF(" + aSrcRange + ";$D$1;$B$1)"; + m_pDoc->SetFormula(ScAddress(2, i, 0), + aFormula, + formula::FormulaGrammar::GRAM_NATIVE_UI); + } + + ScFormulaCell* pCell = m_pDoc->GetFormulaCell(ScAddress(2, 0, 0)); + sc::AutoCalcSwitch aACSwitch2(*m_pDoc, true); + pCell->InterpretFormulaGroup(); // Start calculation on the F.G at C1 + + for (size_t i = 0; i < nNumRows; ++i) + { + OString aMsg = "At row " + OString::number(i); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), nConstCellValue, static_cast<size_t>(m_pDoc->GetValue(2, i, 0))); + } + m_pDoc->DeleteTab(0); +} + CPPUNIT_TEST_SUITE_REGISTRATION(ScParallelismTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 6718e10a4248..f1d6acb476eb 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -143,6 +143,7 @@ public: void testFormulaRefData(); void testFormulaCompiler(); void testFormulaCompilerJumpReordering(); + void testFormulaCompilerImplicitIntersection(); void testFormulaRefUpdate(); void testFormulaRefUpdateRange(); void testFormulaRefUpdateSheets(); @@ -567,6 +568,7 @@ public: CPPUNIT_TEST(testFormulaRefData); CPPUNIT_TEST(testFormulaCompiler); CPPUNIT_TEST(testFormulaCompilerJumpReordering); + CPPUNIT_TEST(testFormulaCompilerImplicitIntersection); CPPUNIT_TEST(testFormulaRefUpdate); CPPUNIT_TEST(testFormulaRefUpdateRange); CPPUNIT_TEST(testFormulaRefUpdateSheets); diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index 0b375db0dd21..126bed6c9289 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -1105,6 +1105,132 @@ void Test::testFormulaCompilerJumpReordering() } } +void Test::testFormulaCompilerImplicitIntersection() +{ + struct TestCaseFormula + { + OUString aFormula; + ScAddress aCellAddress; + ScRange aSumRange; + bool bStartColRel; // SumRange-StartCol + bool bEndColRel; // SumRange-EndCol + }; + + m_pDoc->InsertTab(0, "Formula"); + sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on. + + { + TestCaseFormula aTestCases[] = + { + // Formula, FormulaCellAddress, SumRange with Implicit Intersection + + // Sumrange is single cell, address is abs + { + OUString("=SUMIF($B$2:$B$10;F2;$D$5)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + false, + false + }, + + // Sumrange is single cell, address is relative + { + OUString("=SUMIF($B$2:$B$10;F2;D5)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + true, + true + }, + + // Baserange(abs,abs), Sumrange(abs,abs) + { + OUString("=SUMIF($B$2:$B$10;F2;$D$5:$D$10)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + false, + false + }, + + // Baserange(abs,rel), Sumrange(abs,abs) + { + OUString("=SUMIF($B$2:B10;F2;$D$5:$D$10)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + false, + false + }, + + // Baserange(rel,abs), Sumrange(abs,abs) + { + OUString("=SUMIF(B2:$B$10;F2;$D$5:$D$10)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + false, + false + }, + + // Baserange(rel,rel), Sumrange(abs,abs) + { + OUString("=SUMIF(B2:B10;F2;$D$5:$D$10)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + false, + false + }, + + // Baserange(abs,abs), Sumrange(abs,rel) + { + OUString("=SUMIF($B$2:$B$10;F2;$D$5:D10)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + false, + true + }, + + // Baserange(abs,abs), Sumrange(rel,abs) + { + OUString("=SUMIF($B$2:$B$10;F2;D5:$D$10)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + true, + false + }, + + // Baserange(abs,abs), Sumrange(rel,rel) + { + OUString("=SUMIF($B$2:$B$10;F2;D5:D10)"), + ScAddress(7, 5, 0), + ScRange( ScAddress(3, 4, 0), ScAddress(3, 12, 0) ), + true, + true + } + }; + + for (auto& rCase : aTestCases) + { + m_pDoc->SetString(rCase.aCellAddress, rCase.aFormula); + const ScFormulaCell* pCell = m_pDoc->GetFormulaCell(rCase.aCellAddress); + const ScTokenArray* pCode = pCell->GetCode(); + CPPUNIT_ASSERT(pCode); + + sal_uInt16 nLen = pCode->GetCodeLen(); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong RPN token count.", static_cast<sal_uInt16>(4), nLen); + + FormulaToken** ppTokens = pCode->GetCode(); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong type of token(first argument to SUMIF)", svDoubleRef, ppTokens[0]->GetType()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong type of token(third argument to SUMIF)", svDoubleRef, ppTokens[2]->GetType()); + + ScComplexRefData aSumRangeData = *ppTokens[2]->GetDoubleRef(); + ScRange aSumRange = aSumRangeData.toAbs(rCase.aCellAddress); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong sum-range in RPN array", rCase.aSumRange, aSumRange); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong IsRel type for start column address in sum-range", rCase.bStartColRel, aSumRangeData.Ref1.IsColRel()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong IsRel type for end column address in sum-range", rCase.bEndColRel, aSumRangeData.Ref2.IsColRel()); + } + } +} + void Test::testFormulaRefUpdate() { m_pDoc->InsertTab(0, "Formula"); |