[Libreoffice-commits] core.git: 3 commits - sc/qa
Kohei Yoshida
kohei.yoshida at collabora.com
Wed May 14 19:54:32 PDT 2014
sc/qa/unit/helper/qahelper.cxx | 12 ++++
sc/qa/unit/helper/qahelper.hxx | 4 +
sc/qa/unit/ucalc.hxx | 6 ++
sc/qa/unit/ucalc_formula.cxx | 120 +++++++++++++++++++++++++++++++++++++++--
4 files changed, 139 insertions(+), 3 deletions(-)
New commits:
commit 45c89d62b527abec07072074484bd596ab1aa04a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed May 14 22:52:50 2014 -0400
Add test for CHOOSE function.
This function is also a jump function requiring a special RPN reordering.
Change-Id: I34f68875febeb4fb8c78527d763d4a6352f50b03
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 6726d9b..35d57ce 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -154,6 +154,7 @@ public:
void testFuncDATEDIF();
void testFuncINDIRECT();
void testFuncIF();
+ void testFuncCHOOSE();
void testFuncIFERROR();
void testFuncSHEET();
void testFuncNOW();
@@ -416,6 +417,7 @@ public:
CPPUNIT_TEST(testFuncDATEDIF);
CPPUNIT_TEST(testFuncINDIRECT);
CPPUNIT_TEST(testFuncIF);
+ CPPUNIT_TEST(testFuncCHOOSE);
CPPUNIT_TEST(testFuncIFERROR);
CPPUNIT_TEST(testFuncGETPIVOTDATA);
CPPUNIT_TEST(testFuncGETPIVOTDATALeafAccess);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index efd1d8c..7720881 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -2809,6 +2809,28 @@ void Test::testFuncIF()
m_pDoc->DeleteTab(0);
}
+void Test::testFuncCHOOSE()
+{
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
+
+ m_pDoc->InsertTab(0, "Formula");
+
+ m_pDoc->SetString(ScAddress(0,0,0), "=CHOOSE(B1;\"one\";\"two\";\"three\")");
+ sal_uInt16 nError = m_pDoc->GetErrCode(ScAddress(0,0,0));
+ CPPUNIT_ASSERT_MESSAGE("Formula result should be an error since B1 is still empty.", nError);
+ m_pDoc->SetValue(ScAddress(1,0,0), 1.0);
+ CPPUNIT_ASSERT_EQUAL(OUString("one"), m_pDoc->GetString(ScAddress(0,0,0)));
+ m_pDoc->SetValue(ScAddress(1,0,0), 2.0);
+ CPPUNIT_ASSERT_EQUAL(OUString("two"), m_pDoc->GetString(ScAddress(0,0,0)));
+ m_pDoc->SetValue(ScAddress(1,0,0), 3.0);
+ CPPUNIT_ASSERT_EQUAL(OUString("three"), m_pDoc->GetString(ScAddress(0,0,0)));
+ m_pDoc->SetValue(ScAddress(1,0,0), 4.0);
+ nError = m_pDoc->GetErrCode(ScAddress(0,0,0));
+ CPPUNIT_ASSERT_MESSAGE("Formula result should be an error due to out-of-bound input..", nError);
+
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testFuncIFERROR()
{
// IFERROR/IFNA (fdo#56124)
commit 3e377f86d8c8d15c80879f8d6f1228abe2afba28
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed May 14 22:12:19 2014 -0400
Add unit test for IF function.
Change-Id: I2265458883fb05582c54157714b88345362efa0d
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 6291fd9..6726d9b 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -153,6 +153,7 @@ public:
void testFuncCELL();
void testFuncDATEDIF();
void testFuncINDIRECT();
+ void testFuncIF();
void testFuncIFERROR();
void testFuncSHEET();
void testFuncNOW();
@@ -414,6 +415,7 @@ public:
CPPUNIT_TEST(testFuncCELL);
CPPUNIT_TEST(testFuncDATEDIF);
CPPUNIT_TEST(testFuncINDIRECT);
+ CPPUNIT_TEST(testFuncIF);
CPPUNIT_TEST(testFuncIFERROR);
CPPUNIT_TEST(testFuncGETPIVOTDATA);
CPPUNIT_TEST(testFuncGETPIVOTDATALeafAccess);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 3b374d7..efd1d8c 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -2793,6 +2793,22 @@ void Test::testFuncCOUNTIF()
m_pDoc->DeleteTab(0);
}
+void Test::testFuncIF()
+{
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
+
+ m_pDoc->InsertTab(0, "Formula");
+
+ m_pDoc->SetString(ScAddress(0,0,0), "=IF(B1=2;\"two\";\"not two\")");
+ CPPUNIT_ASSERT_EQUAL(OUString("not two"), m_pDoc->GetString(ScAddress(0,0,0)));
+ m_pDoc->SetValue(ScAddress(1,0,0), 2.0);
+ CPPUNIT_ASSERT_EQUAL(OUString("two"), m_pDoc->GetString(ScAddress(0,0,0)));
+ m_pDoc->SetValue(ScAddress(1,0,0), 3.0);
+ CPPUNIT_ASSERT_EQUAL(OUString("not two"), m_pDoc->GetString(ScAddress(0,0,0)));
+
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testFuncIFERROR()
{
// IFERROR/IFNA (fdo#56124)
commit 12383c8d7465d7057b49844695b3fc34b51186ca
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Wed May 14 21:05:56 2014 -0400
Write test for RPN token generation with and without jump command reordering.
Change-Id: I45d83448be04e0983f39ca28392671cf84ae928c
diff --git a/sc/qa/unit/helper/qahelper.cxx b/sc/qa/unit/helper/qahelper.cxx
index 951cd61..91b4a12 100644
--- a/sc/qa/unit/helper/qahelper.cxx
+++ b/sc/qa/unit/helper/qahelper.cxx
@@ -473,6 +473,18 @@ bool checkFormulaPositions(
return true;
}
+ScTokenArray* compileFormula(
+ ScDocument* pDoc, const OUString& rFormula, const ScAddress* pPos,
+ formula::FormulaGrammar::Grammar eGram )
+{
+ ScAddress aPos(0,0,0);
+ if (pPos)
+ aPos = *pPos;
+ ScCompiler aComp(pDoc, aPos);
+ aComp.SetGrammar(eGram);
+ return aComp.CompileString(rFormula);
+}
+
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 915d167..805c6d2 100644
--- a/sc/qa/unit/helper/qahelper.hxx
+++ b/sc/qa/unit/helper/qahelper.hxx
@@ -125,6 +125,10 @@ SCQAHELPER_DLLPUBLIC bool checkFormulaPosition(ScDocument& rDoc, const ScAddress
SCQAHELPER_DLLPUBLIC bool checkFormulaPositions(
ScDocument& rDoc, SCTAB nTab, SCCOL nCol, const SCROW* pRows, size_t nRowCount);
+SCQAHELPER_DLLPUBLIC ScTokenArray* compileFormula(
+ ScDocument* pDoc, const OUString& rFormula, const ScAddress* pPos = NULL,
+ formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_NATIVE );
+
template<size_t _Size>
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 ec32e23..6291fd9 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -123,6 +123,7 @@ public:
void testFormulaTokenEquality();
void testFormulaRefData();
void testFormulaCompiler();
+ void testFormulaCompilerJumpReordering();
void testFormulaRefUpdate();
void testFormulaRefUpdateRange();
void testFormulaRefUpdateSheets();
@@ -383,6 +384,7 @@ public:
CPPUNIT_TEST(testFormulaTokenEquality);
CPPUNIT_TEST(testFormulaRefData);
CPPUNIT_TEST(testFormulaCompiler);
+ CPPUNIT_TEST(testFormulaCompilerJumpReordering);
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 4d4d0c2..3b374d7 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -781,9 +781,7 @@ void Test::testFormulaCompiler()
{
boost::scoped_ptr<ScTokenArray> pArray;
{
- ScCompiler aComp(m_pDoc, ScAddress());
- aComp.SetGrammar(aTests[i].eInputGram);
- pArray.reset(aComp.CompileString(OUString::createFromAscii(aTests[i].pInput)));
+ pArray.reset(compileFormula(m_pDoc, OUString::createFromAscii(aTests[i].pInput), NULL, aTests[i].eInputGram));
CPPUNIT_ASSERT_MESSAGE("Token array shouldn't be NULL!", pArray.get());
}
@@ -792,6 +790,84 @@ void Test::testFormulaCompiler()
}
}
+void Test::testFormulaCompilerJumpReordering()
+{
+ struct TokenCheck
+ {
+ OpCode meOp;
+ StackVar meType;
+ };
+
+ // Set separators first.
+ ScFormulaOptions aOptions;
+ aOptions.SetFormulaSepArg(";");
+ aOptions.SetFormulaSepArrayCol(";");
+ aOptions.SetFormulaSepArrayRow("|");
+ getDocShell().SetFormulaOptions(aOptions);
+
+ {
+ OUString aInput("=IF(B1;12;\"text\")");
+
+ // Compile formula string first.
+ boost::scoped_ptr<ScTokenArray> pCode(compileFormula(m_pDoc, aInput));
+ CPPUNIT_ASSERT(pCode.get());
+
+ // Then generate RPN tokens.
+ ScCompiler aCompRPN(m_pDoc, ScAddress(), *pCode);
+ aCompRPN.SetGrammar(FormulaGrammar::GRAM_NATIVE);
+ aCompRPN.CompileTokenArray();
+
+ // RPN tokens should be ordered: B1, ocIf, C1, ocSep, D1, ocClose.
+ TokenCheck aCheckRPN[] =
+ {
+ { ocPush, svSingleRef },
+ { ocIf, 0 },
+ { ocPush, svDouble },
+ { ocSep, 0 },
+ { ocPush, svString },
+ { ocClose, 0 },
+ };
+
+ sal_uInt16 nLen = pCode->GetCodeLen();
+ CPPUNIT_ASSERT_MESSAGE("Wrong RPN token count.", nLen == SAL_N_ELEMENTS(aCheckRPN));
+
+ FormulaToken** ppTokens = pCode->GetCode();
+ for (sal_uInt16 i = 0; i < nLen; ++i)
+ {
+ const FormulaToken* p = ppTokens[i];
+ CPPUNIT_ASSERT_EQUAL(aCheckRPN[i].meOp, p->GetOpCode());
+ if (aCheckRPN[i].meOp == ocPush)
+ CPPUNIT_ASSERT_EQUAL(static_cast<int>(aCheckRPN[i].meType), static_cast<int>(p->GetType()));
+ }
+
+ // Generate RPN tokens again, but this time no jump command reordering.
+ pCode->DelRPN();
+ ScCompiler aCompRPN2(m_pDoc, ScAddress(), *pCode);
+ aCompRPN2.SetGrammar(FormulaGrammar::GRAM_NATIVE);
+ aCompRPN2.EnableJumpCommandReorder(false);
+ aCompRPN2.CompileTokenArray();
+
+ TokenCheck aCheckRPN2[] =
+ {
+ { ocPush, svSingleRef },
+ { ocPush, svDouble },
+ { ocPush, svString },
+ { ocIf, 0 },
+ };
+
+ nLen = pCode->GetCodeLen();
+ CPPUNIT_ASSERT_MESSAGE("Wrong RPN token count.", nLen == SAL_N_ELEMENTS(aCheckRPN2));
+ ppTokens = pCode->GetCode();
+ for (sal_uInt16 i = 0; i < nLen; ++i)
+ {
+ const FormulaToken* p = ppTokens[i];
+ CPPUNIT_ASSERT_EQUAL(aCheckRPN2[i].meOp, p->GetOpCode());
+ if (aCheckRPN[i].meOp == ocPush)
+ CPPUNIT_ASSERT_EQUAL(static_cast<int>(aCheckRPN2[i].meType), static_cast<int>(p->GetType()));
+ }
+ }
+}
+
void Test::testFormulaRefUpdate()
{
m_pDoc->InsertTab(0, "Formula");
More information about the Libreoffice-commits
mailing list