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.yosh...@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.yosh...@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.yosh...@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"); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits