sc/qa/unit/ucalc.cxx | 165 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 149 insertions(+), 16 deletions(-)
New commits: commit 1a8b6a61447f1ba7fa7dc626a7563fae57f856d1 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Oct 30 14:27:11 2012 -0400 Intentionally add a formula cell in column 1. Column 1 only consisted of static values prior to this. Inserting a formula cell will break the range-based formula sharing and dependency tracking but it should still continue to work. Change-Id: I5187ccf15ec1dffe4b6b10086f815b18c21e17c1 diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 45d84ff..74c7205 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1199,6 +1199,13 @@ void Test::testFormulaDepTracking() CPPUNIT_ASSERT_MESSAGE("Unexpected formula value.", m_pDoc->GetValue(2, nRow, 0) == val*2.0); } + // Intentionally insert a formula in column 1. This will break column 1's + // uniformity of consisting only of static value cells. + m_pDoc->SetString(0, 4, 0, "=R2C3"); + CPPUNIT_ASSERT_MESSAGE("Unexpected formula value.", m_pDoc->GetValue(0, 4, 0) == 2.0); + CPPUNIT_ASSERT_MESSAGE("Unexpected formula value.", m_pDoc->GetValue(1, 4, 0) == 2.0); + CPPUNIT_ASSERT_MESSAGE("Unexpected formula value.", m_pDoc->GetValue(2, 4, 0) == 4.0); + m_pDoc->DeleteTab(0); } commit 08dee0ce8d5d49b3ff2e993bfa44cf49c0c643e0 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Oct 30 14:21:36 2012 -0400 Another test case for column formula arrays. We will later handle this use case using shared formulas. Change-Id: I6403ae4adddc865d0418290e1549a91ef4eeb318 diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 890c6bf..45d84ff 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -334,6 +334,9 @@ ScRange insertRangeData(ScDocument* pDoc, const ScAddress& rPos, const char* aDa return aRange; } +/** + * Temporarily switch on/off auto calculation mode. + */ class AutoCalcSwitch { ScDocument* mpDoc; @@ -350,6 +353,26 @@ public: } }; +/** + * Temporarily set formula grammar. + */ +class FormulaGrammarSwitch +{ + ScDocument* mpDoc; + formula::FormulaGrammar::Grammar meOldGrammar; +public: + FormulaGrammarSwitch(ScDocument* pDoc, formula::FormulaGrammar::Grammar eGrammar) : + mpDoc(pDoc), meOldGrammar(pDoc->GetGrammar()) + { + mpDoc->SetGrammar(eGrammar); + } + + ~FormulaGrammarSwitch() + { + mpDoc->SetGrammar(meOldGrammar); + } +}; + Test::Test() : m_pDoc(0) { @@ -1147,6 +1170,35 @@ void Test::testFormulaDepTracking() m_pDoc->GetValue(1, 1, 0, val); CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on single value change.", rtl::math::approxEqual(val, 12.0)); + clearRange(m_pDoc, ScRange(0, 0, 0, 10, 10, 0)); + + // Now, column-based dependency tracking. We now switch to the R1C1 + // syntax which is easier to use for repeated relative references. + + FormulaGrammarSwitch aFGSwitch(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1); + + val = 0.0; + for (SCROW nRow = 1; nRow <= 9; ++nRow) + { + // Static value in column 1. + m_pDoc->SetValue(0, nRow, 0, ++val); + + // Formula in column 2 that references cell to the left. + m_pDoc->SetString(1, nRow, 0, "=RC[-1]"); + + // Formula in column 3 that references cell to the left. + m_pDoc->SetString(2, nRow, 0, "=RC[-1]*2"); + } + + // Check formula values. + val = 0.0; + for (SCROW nRow = 1; nRow <= 9; ++nRow) + { + ++val; + CPPUNIT_ASSERT_MESSAGE("Unexpected formula value.", m_pDoc->GetValue(1, nRow, 0) == val); + CPPUNIT_ASSERT_MESSAGE("Unexpected formula value.", m_pDoc->GetValue(2, nRow, 0) == val*2.0); + } + m_pDoc->DeleteTab(0); } commit 8cd13f7e04e920e3d6e1fddf88f61dac08894e06 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Oct 30 12:38:32 2012 -0400 New unit test for formula dependency tracking. Change-Id: I5dad87cd67f8644509087394faa7c4880deb8ee6 diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index a5e3a07..890c6bf 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -118,6 +118,7 @@ public: */ void testSheetsFunc(); void testVolatileFunc(); + void testFormulaDepTracking(); void testFuncParam(); void testNamedRange(); void testCSV(); @@ -235,6 +236,7 @@ public: CPPUNIT_TEST(testCellFunctions); CPPUNIT_TEST(testSheetsFunc); CPPUNIT_TEST(testVolatileFunc); + CPPUNIT_TEST(testFormulaDepTracking); CPPUNIT_TEST(testFuncParam); CPPUNIT_TEST(testNamedRange); CPPUNIT_TEST(testCSV); @@ -332,6 +334,22 @@ ScRange insertRangeData(ScDocument* pDoc, const ScAddress& rPos, const char* aDa return aRange; } +class AutoCalcSwitch +{ + ScDocument* mpDoc; + bool mbOldValue; +public: + AutoCalcSwitch(ScDocument* pDoc, bool bAutoCalc) : mpDoc(pDoc), mbOldValue(pDoc->GetAutoCalc()) + { + mpDoc->SetAutoCalc(bAutoCalc); + } + + ~AutoCalcSwitch() + { + mpDoc->SetAutoCalc(mbOldValue); + } +}; + Test::Test() : m_pDoc(0) { @@ -1060,6 +1078,78 @@ void Test::testVolatileFunc() m_pDoc->DeleteTab(0); } +void Test::testFormulaDepTracking() +{ + CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet", m_pDoc->InsertTab (0, "foo")); + + AutoCalcSwitch aACSwitch(m_pDoc, true); // turn on auto calculation. + + // B2 listens on D2. + m_pDoc->SetString(1, 1, 0, "=D2"); + double val = -999.0; // dummy initial value + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Referencing an empty cell should yield zero.", val == 0.0); + + // Changing the value of D2 should trigger recalculation of B2. + m_pDoc->SetValue(3, 1, 0, 1.1); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on value change.", val == 1.1); + + // And again. + m_pDoc->SetValue(3, 1, 0, 2.2); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on value change.", val == 2.2); + + clearRange(m_pDoc, ScRange(0, 0, 0, 10, 10, 0)); + + // Now, let's test the range dependency tracking. + + // B2 listens on D2:E6. + m_pDoc->SetString(1, 1, 0, "=SUM(D2:E6)"); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Summing an empty range should yield zero.", val == 0.0); + + // Set value to E3. This should trigger recalc on B2. + m_pDoc->SetValue(4, 2, 0, 2.4); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on single value change.", val == 2.4); + + // Set value to D5 to trigger recalc again. Note that this causes an + // addition of 1.2 + 2.4 which is subject to binary floating point + // rounding error. We need to use approxEqual to assess its value. + + m_pDoc->SetValue(3, 4, 0, 1.2); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on single value change.", rtl::math::approxEqual(val, 3.6)); + + // Change the value of D2 (boundary case). + m_pDoc->SetValue(3, 1, 0, 1.0); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on single value change.", rtl::math::approxEqual(val, 4.6)); + + // Change the value of E6 (another boundary case). + m_pDoc->SetValue(4, 5, 0, 2.0); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on single value change.", rtl::math::approxEqual(val, 6.6)); + + // Change the value of D6 (another boundary case). + m_pDoc->SetValue(3, 5, 0, 3.0); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on single value change.", rtl::math::approxEqual(val, 9.6)); + + // Change the value of E2 (another boundary case). + m_pDoc->SetValue(4, 1, 0, 0.4); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on single value change.", rtl::math::approxEqual(val, 10.0)); + + // Change the existing non-empty value cell (E2). + m_pDoc->SetValue(4, 1, 0, 2.4); + m_pDoc->GetValue(1, 1, 0, val); + CPPUNIT_ASSERT_MESSAGE("Failed to recalculate on single value change.", rtl::math::approxEqual(val, 12.0)); + + m_pDoc->DeleteTab(0); +} + void Test::testFuncParam() { rtl::OUString aTabName("foo"); @@ -1540,22 +1630,6 @@ ScRange refreshGroups(ScDPCollection* pDPs, ScDPObject* pDPObj) return refresh(pDPObj); } -class AutoCalcSwitch -{ - ScDocument* mpDoc; - bool mbOldValue; -public: - AutoCalcSwitch(ScDocument* pDoc, bool bAutoCalc) : mpDoc(pDoc), mbOldValue(pDoc->GetAutoCalc()) - { - mpDoc->SetAutoCalc(bAutoCalc); - } - - ~AutoCalcSwitch() - { - mpDoc->SetAutoCalc(mbOldValue); - } -}; - } void Test::testPivotTable() _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits