sc/qa/unit/ucalc.cxx | 112 ++++++++++++++++++++++++++++++++++++++++ sc/source/core/data/dpcache.cxx | 35 ++++++++++-- 2 files changed, 140 insertions(+), 7 deletions(-)
New commits: commit 87003581c0cf1068172259c8b9949349fe7ff6b5 Author: Kohei Yoshida <[email protected]> Date: Thu Nov 8 16:09:11 2012 -0500 fdo#54898: Test equality by order index (integer) which is more stable. At the point where std::unique is called, we can use order indices to determine whether the two items are equal. This should be more stable than using CaseInsEqual() to assess equality. Change-Id: I88310fc7beede19fb1c629b9b7e3cb9a069b2b23 diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx index d5c5d5f..b5f7424 100644 --- a/sc/source/core/data/dpcache.cxx +++ b/sc/source/core/data/dpcache.cxx @@ -207,11 +207,11 @@ struct LessByDataIndex : std::binary_function<Bucket, Bucket, bool> } }; -struct EqualByValue : std::binary_function<Bucket, Bucket, bool> +struct EqualByOrderIndex : std::binary_function<Bucket, Bucket, bool> { bool operator() (const Bucket& left, const Bucket& right) const { - return left.maValue.IsCaseInsEqual(right.maValue); + return left.mnOrderIndex == right.mnOrderIndex; } }; @@ -287,7 +287,7 @@ void processBuckets(std::vector<Bucket>& aBuckets, ScDPCache::Field& rField) // Unique by value. std::vector<Bucket>::iterator itUniqueEnd = - std::unique(aBuckets.begin(), aBuckets.end(), EqualByValue()); + std::unique(aBuckets.begin(), aBuckets.end(), EqualByOrderIndex()); // Copy the unique values into items. std::vector<Bucket>::iterator itBeg = aBuckets.begin(); commit 4ca546deacda936763b372a202123ce5234086a3 Author: Kohei Yoshida <[email protected]> Date: Thu Nov 8 16:04:39 2012 -0500 New unit test for pivot table's handling of double-precision values. Note: This test passes just fine on master. On the 3-6 branch the test itself also passes fine, *but* when re-creating the same scenario from the UI, it fails only with the 3.6 build. I have no idea why. This test is modeled after fdo#54898. Change-Id: I32eb9b2f2bdc12ef801daf0ccb9a3db2d5efd8d6 diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index ce8ea86..5b48f25 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -178,6 +178,12 @@ public: */ void testPivotTableCaseInsensitiveStrings(); + /** + * Test for pivot table's handling of double-precision numbers that are + * very close together. + */ + void testPivotTableNumStability(); + void testSheetCopy(); void testSheetMove(); void testExternalRef(); @@ -257,6 +263,7 @@ public: CPPUNIT_TEST(testPivotTableEmptyRows); CPPUNIT_TEST(testPivotTableTextNumber); CPPUNIT_TEST(testPivotTableCaseInsensitiveStrings); + CPPUNIT_TEST(testPivotTableNumStability); CPPUNIT_TEST(testSheetCopy); CPPUNIT_TEST(testSheetMove); CPPUNIT_TEST(testExternalRef); @@ -3186,6 +3193,111 @@ void Test::testPivotTableCaseInsensitiveStrings() m_pDoc->DeleteTab(0); } +void Test::testPivotTableNumStability() +{ + FormulaGrammarSwitch aFGSwitch(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1); + + // Raw Data + const char* aData[][4] = { + { "Name", "Time Start", "Time End", "Total" }, + { "Sam", "07:48 AM", "09:00 AM", "=RC[-1]-RC[-2]" }, + { "Sam", "09:00 AM", "10:30 AM", "=RC[-1]-RC[-2]" }, + { "Sam", "10:30 AM", "12:30 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "12:30 PM", "01:00 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "01:00 PM", "01:30 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "01:30 PM", "02:00 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "02:00 PM", "07:15 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "07:47 AM", "09:00 AM", "=RC[-1]-RC[-2]" }, + { "Sam", "09:00 AM", "10:00 AM", "=RC[-1]-RC[-2]" }, + { "Sam", "10:00 AM", "11:00 AM", "=RC[-1]-RC[-2]" }, + { "Sam", "11:00 AM", "11:30 AM", "=RC[-1]-RC[-2]" }, + { "Sam", "11:30 AM", "12:45 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "12:45 PM", "01:15 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "01:15 PM", "02:30 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "02:30 PM", "02:45 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "02:45 PM", "04:30 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "04:30 PM", "06:00 PM", "=RC[-1]-RC[-2]" }, + { "Sam", "06:00 PM", "07:15 PM", "=RC[-1]-RC[-2]" }, + { "Mike", "06:15 AM", "08:30 AM", "=RC[-1]-RC[-2]" }, + { "Mike", "08:30 AM", "10:03 AM", "=RC[-1]-RC[-2]" }, + { "Mike", "10:03 AM", "12:00 PM", "=RC[-1]-RC[-2]" }, + { "Dennis", "11:00 AM", "01:00 PM", "=RC[-1]-RC[-2]" }, + { "Dennis", "01:00 PM", "02:00 PM", "=RC[-1]-RC[-2]" } + }; + + // Dimension definition + DPFieldDef aFields[] = { + { "Name", sheet::DataPilotFieldOrientation_ROW, 0 }, + { "Total", sheet::DataPilotFieldOrientation_DATA, sheet::GeneralFunction_SUM }, + }; + + m_pDoc->InsertTab(0, OUString("Data")); + m_pDoc->InsertTab(1, OUString("Table")); + + size_t nRowCount = SAL_N_ELEMENTS(aData); + ScAddress aPos(1,1,0); + ScRange aDataRange = insertRangeData(m_pDoc, aPos, aData, nRowCount); + + // Insert formulas to manually calculate sums for each name. + m_pDoc->SetString(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+1, aDataRange.aStart.Tab(), "=SUMIF(R[-23]C:R[-1]C;\"Dennis\";R[-23]C[3]:R[-1]C[3])"); + m_pDoc->SetString(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+2, aDataRange.aStart.Tab(), "=SUMIF(R[-24]C:R[-2]C;\"Mike\";R[-24]C[3]:R[-2]C[3])"); + m_pDoc->SetString(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+3, aDataRange.aStart.Tab(), "=SUMIF(R[-25]C:R[-3]C;\"Sam\";R[-25]C[3]:R[-3]C[3])"); + + m_pDoc->CalcAll(); + + // Get correct sum values. + double fDennisTotal = m_pDoc->GetValue(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+1, aDataRange.aStart.Tab()); + double fMikeTotal = m_pDoc->GetValue(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+2, aDataRange.aStart.Tab()); + double fSamTotal = m_pDoc->GetValue(aDataRange.aStart.Col(), aDataRange.aEnd.Row()+3, aDataRange.aStart.Tab()); + + ScDPObject* pDPObj = createDPFromRange( + m_pDoc, aDataRange, aFields, SAL_N_ELEMENTS(aFields), false); + + ScDPCollection* pDPs = m_pDoc->GetDPCollection(); + bool bSuccess = pDPs->InsertNewTable(pDPObj); + + CPPUNIT_ASSERT_MESSAGE("failed to insert a new pivot table object into document.", bSuccess); + CPPUNIT_ASSERT_EQUAL_MESSAGE("there should be only one data pilot table.", + pDPs->GetCount(), static_cast<size_t>(1)); + pDPObj->SetName(pDPs->CreateNewName()); + + ScRange aOutRange = refresh(pDPObj); + + // Manually check the total value for each name. + // + // +--------------+----------------+ + // | Name | | + // +--------------+----------------+ + // | Dennis | <Dennis total> | + // +--------------+----------------+ + // | Mike | <Miks total> | + // +--------------+----------------+ + // | Sam | <Sam total> | + // +--------------+----------------+ + // | Total Result | ... | + // +--------------+----------------+ + + aPos = aOutRange.aStart; + aPos.IncCol(); + aPos.IncRow(); + double fTest = m_pDoc->GetValue(aPos); + CPPUNIT_ASSERT_MESSAGE("Incorrect value for Dennis.", rtl::math::approxEqual(fTest, fDennisTotal)); + aPos.IncRow(); + fTest = m_pDoc->GetValue(aPos); + CPPUNIT_ASSERT_MESSAGE("Incorrect value for Mike.", rtl::math::approxEqual(fTest, fMikeTotal)); + aPos.IncRow(); + fTest = m_pDoc->GetValue(aPos); + CPPUNIT_ASSERT_MESSAGE("Incorrect value for Sam.", rtl::math::approxEqual(fTest, fSamTotal)); + + pDPs->FreeTable(pDPObj); + CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0)); + CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.", + pDPs->GetSheetCaches().size(), static_cast<size_t>(0)); + + m_pDoc->DeleteTab(1); + m_pDoc->DeleteTab(0); +} + void Test::testSheetCopy() { OUString aTabName("TestTab"); commit 5be8ac9731f5e53a7a678033c2fa3face3e63d11 Author: Kohei Yoshida <[email protected]> Date: Thu Nov 8 13:47:49 2012 -0500 Function object for printing bucket content. Used only for debugging. Change-Id: I8090ef9bbcbf335f742c2bb8843dd72a757ef048 diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx index 5e27715..d5c5d5f 100644 --- a/sc/source/core/data/dpcache.cxx +++ b/sc/source/core/data/dpcache.cxx @@ -168,6 +168,21 @@ struct Bucket maValue(rValue), mnOrderIndex(nOrder), mnDataIndex(nData), mnValueSortIndex(0) {} }; +#if DEBUG_PIVOT_TABLE +#include <iostream> +using std::cout; +using std::endl; + +struct PrintBucket : std::unary_function<Bucket, void> +{ + void operator() (const Bucket& v) const + { + cout << "value: " << v.maValue.GetValue() << " order index: " << v.mnOrderIndex << " data index: " << v.mnDataIndex << " value sort index: " << v.mnValueSortIndex << endl; + } +}; + +#endif + struct LessByValue : std::binary_function<Bucket, Bucket, bool> { bool operator() (const Bucket& left, const Bucket& right) const @@ -1100,10 +1115,6 @@ long ScDPCache::GetColumnCount() const #if DEBUG_PIVOT_TABLE -#include <iostream> -using std::cout; -using std::endl; - namespace { std::ostream& operator<< (::std::ostream& os, const rtl::OUString& str) commit 388ce83891a10a12ef2264ac43fa875a5bd35f1e Author: Kohei Yoshida <[email protected]> Date: Thu Nov 8 12:16:48 2012 -0500 Dump source data for each field re-constructd from the index array. Change-Id: I863ec02853042662accc2005fa1cd9340f950740 diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx index 89b409b..5e27715 100644 --- a/sc/source/core/data/dpcache.cxx +++ b/sc/source/core/data/dpcache.cxx @@ -1117,6 +1117,13 @@ void dumpItems(const ScDPCache& rCache, long nDim, const ScDPCache::ItemsType& r cout << " " << (i+nOffset) << ": " << rCache.GetFormattedString(nDim, rItems[i]) << endl; } +void dumpSourceData(const ScDPCache& rCache, long nDim, const ScDPCache::ItemsType& rItems, const ScDPCache::IndexArrayType& rArray) +{ + ScDPCache::IndexArrayType::const_iterator it = rArray.begin(), itEnd = rArray.end(); + for (; it != itEnd; ++it) + cout << " '" << rCache.GetFormattedString(nDim, rItems[*it]) << "'" << endl; +} + } void ScDPCache::Dump() const @@ -1135,6 +1142,9 @@ void ScDPCache::Dump() const cout << " group item count: " << fld.mpGroup->maItems.size() << endl; dumpItems(*this, i, fld.mpGroup->maItems, fld.maItems.size()); } + + cout << " source data (re-constructed):" << endl; + dumpSourceData(*this, i, fld.maItems, fld.maData); } } _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
