summaryrefslogtreecommitdiff
path: root/sc/qa
diff options
context:
space:
mode:
authorDennis Francis <dennis.francis@collabora.co.uk>2018-02-07 12:00:47 +0530
committerEike Rathke <erack@redhat.com>2018-04-28 13:33:55 +0200
commit67b1c26c27590678ece7bcef763433aedd0b164d (patch)
treeefed6b3c2c2a6db724d0aa60dcde735d5d10ac4a /sc/qa
parent212807f77b78c69263f8aae51dcdc73e8017c53a (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.cxx79
-rw-r--r--sc/qa/unit/ucalc.hxx2
-rw-r--r--sc/qa/unit/ucalc_formula.cxx126
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");