[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