sc/inc/calcmacros.hxx | 6 ++ sc/inc/token.hxx | 11 ++++ sc/inc/tokenarray.hxx | 5 ++ sc/qa/unit/ucalc.hxx | 2 sc/qa/unit/ucalc_formula.cxx | 99 ++++++++++++++++++++++++++++++++++++---- sc/source/core/data/column2.cxx | 7 -- sc/source/core/tool/token.cxx | 42 ++++++++++++++++ 7 files changed, 156 insertions(+), 16 deletions(-)
New commits: commit e2372a14ea88a4a2cb939d62d6f028b53a2a89a3 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Wed Jul 17 14:17:45 2013 -0400 Add test for reference update in formula cells. Change-Id: I79b1a23d269f59df24f8b50f484713441a11deff diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 7582e63..440230c 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -86,6 +86,7 @@ public: void testFormulaHashAndTag(); void testFormulaRefData(); void testFormulaCompiler(); + void testFormulaRefUpdate(); void testFuncSUM(); void testFuncPRODUCT(); void testFuncN(); @@ -272,6 +273,7 @@ public: CPPUNIT_TEST(testFormulaHashAndTag); CPPUNIT_TEST(testFormulaRefData); CPPUNIT_TEST(testFormulaCompiler); + CPPUNIT_TEST(testFormulaRefUpdate); CPPUNIT_TEST(testFuncSUM); CPPUNIT_TEST(testFuncPRODUCT); CPPUNIT_TEST(testFuncN); diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index 352259f..4954d88 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -14,6 +14,8 @@ #include "compiler.hxx" #include "tokenarray.hxx" #include "refdata.hxx" +#include "scopetools.hxx" +#include "formulacell.hxx" #include <boost/scoped_ptr.hpp> @@ -129,6 +131,48 @@ void Test::testFormulaRefData() ASSERT_EQUAL_TYPE(SCTAB, 1, aRefData.GetTab()); } +namespace { + +OUString toString( + ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rArray, FormulaGrammar::Grammar eGram = FormulaGrammar::GRAM_NATIVE) +{ + ScCompiler aComp(&rDoc, rPos, rArray); + aComp.SetGrammar(eGram); + OUStringBuffer aBuf; + aComp.CreateStringFromTokenArray(aBuf); + return aBuf.makeStringAndClear(); +} + +ScTokenArray* getTokens(ScDocument& rDoc, const ScAddress& rPos) +{ + ScFormulaCell* pCell = rDoc.GetFormulaCell(rPos); + if (!pCell) + return NULL; + + return pCell->GetCode(); +} + +bool checkFormula(ScDocument& rDoc, const ScAddress& rPos, const char* pExpected) +{ + ScTokenArray* pCode = getTokens(rDoc, rPos); + if (!pCode) + { + cerr << "Empty token array." << endl; + return false; + } + + OUString aFormula = toString(rDoc, rPos, *pCode); + if (aFormula != OUString::createFromAscii(pExpected)) + { + cerr << "Formula '" << pExpected << "' expected, but '" << aFormula << "' found" << endl; + return false; + } + + return true; +} + +} + void Test::testFormulaCompiler() { struct { @@ -151,17 +195,56 @@ void Test::testFormulaCompiler() CPPUNIT_ASSERT_MESSAGE("Token array shouldn't be NULL!", pArray.get()); } - { - ScCompiler aComp(m_pDoc, ScAddress(), *pArray); - aComp.SetGrammar(aTests[i].eOutputGram); - OUStringBuffer aBuf; - aComp.CreateStringFromTokenArray(aBuf); - OUString aFormula = aBuf.makeStringAndClear(); - CPPUNIT_ASSERT_EQUAL(OUString::createFromAscii(aTests[i].pOutput), aFormula); - } + OUString aFormula = toString(*m_pDoc, ScAddress(), *pArray, aTests[i].eOutputGram); + CPPUNIT_ASSERT_EQUAL(OUString::createFromAscii(aTests[i].pOutput), aFormula); } } +void Test::testFormulaRefUpdate() +{ + m_pDoc->InsertTab(0, "Formula"); + + sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on. + + m_pDoc->SetValue(ScAddress(0,0,0), 2.0); + m_pDoc->SetString(ScAddress(2,2,0), "=A1"); // C3 + m_pDoc->SetString(ScAddress(2,3,0), "=$A$1"); // C4 + + ScAddress aPos(2,2,0); + if (!checkFormula(*m_pDoc, aPos, "A1")) + CPPUNIT_FAIL("Wrong formula in C3."); + + aPos = ScAddress(2,3,0); + if (!checkFormula(*m_pDoc, aPos, "$A$1")) + CPPUNIT_FAIL("Wrong formula in C4."); + + // Delete row 2 to push formula cells up (to C2:C3). + m_pDoc->DeleteRow(ScRange(0,1,0,MAXCOL,1,0)); + + aPos = ScAddress(2,1,0); + if (!checkFormula(*m_pDoc, aPos, "A1")) + CPPUNIT_FAIL("Wrong formula in C2."); + + aPos = ScAddress(2,2,0); + if (!checkFormula(*m_pDoc, aPos, "$A$1")) + CPPUNIT_FAIL("Wrong formula in C3."); + + // Insert one row at row 2 to move them back. + m_pDoc->InsertRow(ScRange(0,1,0,MAXCOL,1,0)); + + aPos = ScAddress(2,2,0); + if (!checkFormula(*m_pDoc, aPos, "A1")) + CPPUNIT_FAIL("Wrong formula in C3."); + + aPos = ScAddress(2,3,0); + if (!checkFormula(*m_pDoc, aPos, "$A$1")) + CPPUNIT_FAIL("Wrong formula in C4."); + + m_pDoc->DeleteTab(0); + + CPPUNIT_ASSERT_MESSAGE("All looks good!", false); +} + void Test::testFuncSUM() { OUString aTabName("foo"); commit a25bd498a3eb833e17dbb505a27920fbee39dcc6 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Wed Jul 17 11:06:15 2013 -0400 Add dumping capability for ScTokenArray (for debugging). Change-Id: Ib3f6a87936a6c00b503f5d72b16b3e4712d7d762 diff --git a/sc/inc/calcmacros.hxx b/sc/inc/calcmacros.hxx index 03ca590..21a51fb 100644 --- a/sc/inc/calcmacros.hxx +++ b/sc/inc/calcmacros.hxx @@ -12,11 +12,15 @@ #define DEBUG_COLUMN_STORAGE 0 #define DEBUG_PIVOT_TABLE 0 +#define DEBUG_FORMULA_COMPILER 1 -#if DEBUG_PIVOT_TABLE +#if DEBUG_PIVOT_TABLE || DEBUG_COLUMN_STORAGE || DEBUG_FORMULA_COMPILER #include <iostream> #include <string> #include <cstdio> +using std::cout; +using std::cerr; +using std::endl; #endif #endif diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx index b10cbe4..e9ddc88 100644 --- a/sc/inc/token.hxx +++ b/sc/inc/token.hxx @@ -31,6 +31,7 @@ #include "formula/IFunctionDescription.hxx" #include "formula/token.hxx" #include "scmatrix.hxx" +#include "calcmacros.hxx" class ScJumpMatrix; @@ -83,6 +84,10 @@ public: virtual bool TextEqual( const formula::FormulaToken& rToken ) const; virtual bool Is3DRef() const; // reference with 3D flag set +#if DEBUG_FORMULA_COMPILER + virtual void Dump() const; +#endif + /** If rTok1 and rTok2 both are SingleRef or DoubleRef tokens, extend/merge ranges as needed for ocRange. @param rPos @@ -123,6 +128,9 @@ public: virtual bool operator==( const formula::FormulaToken& rToken ) const; virtual FormulaToken* Clone() const { return new ScSingleRefToken(*this); } +#if DEBUG_FORMULA_COMPILER + virtual void Dump() const; +#endif DECL_FIXEDMEMPOOL_NEWDEL( ScSingleRefToken ); }; @@ -151,6 +159,9 @@ public: virtual bool operator==( const formula::FormulaToken& rToken ) const; virtual FormulaToken* Clone() const { return new ScDoubleRefToken(*this); } +#if DEBUG_FORMULA_COMPILER + virtual void Dump() const; +#endif DECL_FIXEDMEMPOOL_NEWDEL( ScDoubleRefToken ); }; diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index 726dac6..9f0c463 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -24,6 +24,7 @@ #include <tools/solar.h> #include "scdllapi.h" #include "types.hxx" +#include "calcmacros.hxx" #include <formula/tokenarray.hxx> struct ScRawToken; @@ -111,6 +112,10 @@ public: * @param bCheckCopyArea should references pointing into the copy area be adjusted independently from being absolute, should be true only for copy&paste between documents */ void AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bRangeName = false, bool bCheckCopyArea = false ); + +#if DEBUG_FORMULA_COMPILER + void Dump() const; +#endif }; #endif // SC_TOKENARRAY_HXX diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 8695581..4d6c3fe6 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -66,13 +66,6 @@ #include <boost/scoped_ptr.hpp> -#if DEBUG_COLUMN_STORAGE -#include "columniterator.hxx" -#include <iostream> -using std::cout; -using std::endl; -#endif - // ----------------------------------------------------------------------- // factor from font size to optimal cell height (text width) diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 07da54e..3447432 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -527,6 +527,13 @@ bool ScToken::Is3DRef() const return false; } +#if DEBUG_FORMULA_COMPILER +void ScToken::Dump() const +{ + cout << "-- ScToken (base class)" << endl; +} +#endif + FormulaTokenRef ScToken::ExtendRangeReference( FormulaToken & rTok1, FormulaToken & rTok2, const ScAddress & rPos, bool bReuseDoubleRef ) { @@ -746,6 +753,15 @@ bool ScSingleRefToken::operator==( const FormulaToken& r ) const return FormulaToken::operator==( r ) && aSingleRef == static_cast<const ScToken&>(r).GetSingleRef(); } +#if DEBUG_FORMULA_COMPILER +void ScSingleRefToken::Dump() const +{ + cout << "-- ScSingleRefToken" << endl; + cout << " relative column: " << aSingleRef.IsColRel() << " row : " << aSingleRef.IsRowRel() << " sheet: " << aSingleRef.IsTabRel() << endl; + cout << " absolute column: " << aSingleRef.nCol << " row: " << aSingleRef.nRow << " sheet: " << aSingleRef.nTab << endl; + cout << " relative column: " << aSingleRef.nRelCol << " row: " << aSingleRef.nRelRow << " sheet: " << aSingleRef.nRelTab << endl; +} +#endif const ScSingleRefData& ScDoubleRefToken::GetSingleRef() const { return aDoubleRef.Ref1; } ScSingleRefData& ScDoubleRefToken::GetSingleRef() { return aDoubleRef.Ref1; } @@ -760,6 +776,21 @@ bool ScDoubleRefToken::operator==( const FormulaToken& r ) const return FormulaToken::operator==( r ) && aDoubleRef == static_cast<const ScToken&>(r).GetDoubleRef(); } +#if DEBUG_FORMULA_COMPILER +void ScDoubleRefToken::Dump() const +{ + cout << "-- ScDoubleRefToken" << endl; + cout << " ref 1" << endl; + cout << " relative column: " << aDoubleRef.Ref1.IsColRel() << " row: " << aDoubleRef.Ref1.IsRowRel() << " sheet: " << aDoubleRef.Ref1.IsTabRel() << endl; + cout << " absolute column: " << aDoubleRef.Ref1.nCol << " row: " << aDoubleRef.Ref1.nRow << " sheet: " << aDoubleRef.Ref1.nTab << endl; + cout << " relative column: " << aDoubleRef.Ref1.nRelCol << " row: " << aDoubleRef.Ref1.nRelRow << " sheet: " << aDoubleRef.Ref1.nRelTab << endl; + + cout << " ref 2" << endl; + cout << " relative column: " << aDoubleRef.Ref2.IsColRel() << " row: " << aDoubleRef.Ref2.IsRowRel() << " sheet: " << aDoubleRef.Ref2.IsTabRel() << endl; + cout << " absolute column: " << aDoubleRef.Ref2.nCol << " row: " << aDoubleRef.Ref2.nRow << " sheet: " << aDoubleRef.Ref2.nTab << endl; + cout << " relative column: " << aDoubleRef.Ref2.nRelCol << " row: " << aDoubleRef.Ref2.nRelRow << " sheet: " << aDoubleRef.Ref2.nRelTab << endl; +} +#endif const ScRefList* ScRefListToken::GetRefList() const { return &aRefList; } ScRefList* ScRefListToken::GetRefList() { return &aRefList; } @@ -2185,5 +2216,16 @@ void ScTokenArray::AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddres } } +#if DEBUG_FORMULA_COMPILER +void ScTokenArray::Dump() const +{ + for (sal_uInt16 i = 0; i < nLen; ++i) + { + const ScToken* p = static_cast<const ScToken*>(pCode[i]); + p->Dump(); + } +} +#endif + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits