1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <test/sheet/xdatapilottable2.hxx>
11 #include <com/sun/star/sheet/XDataPilotTable2.hpp>
12 #include <com/sun/star/sheet/DataPilotTableResultData.hpp>
13 #include <com/sun/star/sheet/XDataPilotDescriptor.hpp>
14 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
15 #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
16 #include <com/sun/star/sheet/DataPilotOutputRangeType.hpp>
17 #include <com/sun/star/sheet/XSpreadsheets.hpp>
18 #include <com/sun/star/sheet/XCellAddressable.hpp>
19 #include <com/sun/star/table/XCellCursor.hpp>
20 #include <com/sun/star/sheet/XCellRangeData.hpp>
21 #include <com/sun/star/sheet/DataResult.hpp>
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <cppunit/TestAssert.h>
27 using namespace css::uno
;
31 XDataPilotTable2::~XDataPilotTable2()
35 void XDataPilotTable2::testGetPositionData()
37 uno::Reference
< sheet::XDataPilotTable2
> xDPTable(initDP2(), UNO_QUERY_THROW
);
38 getOutputRanges(xDPTable
);
39 table::CellAddress aAddr
;
41 aAddr
.Sheet
= maRangeTable
.Sheet
;
42 for (sal_Int32 x
= maRangeTable
.StartColumn
; x
<= maRangeTable
.EndColumn
; ++x
)
44 for (sal_Int32 y
= maRangeTable
.StartRow
; y
<= maRangeTable
.EndRow
; ++y
)
49 sheet::DataPilotTablePositionData aPosData
= xDPTable
->getPositionData(aAddr
);
50 if (aPosData
.PositionType
== sheet::DataPilotTablePositionType::NOT_IN_TABLE
)
52 CPPUNIT_ASSERT(false);
58 void XDataPilotTable2::testGetDrillDownData()
60 uno::Reference
< sheet::XDataPilotTable2
> xDPTable(initDP2(), UNO_QUERY_THROW
);
62 getOutputRanges(xDPTable
);
63 buildDataFields(xDPTable
);
64 buildResultCells(xDPTable
);
66 for (const auto& rResultCell
: maResultCells
)
68 sheet::DataPilotTablePositionData aPosData
= xDPTable
->getPositionData(rResultCell
);
69 Any aTempAny
= aPosData
.PositionData
;
70 sheet::DataPilotTableResultData aResData
;
71 CPPUNIT_ASSERT(aTempAny
>>= aResData
);
72 sal_Int32 nDim
= maDataFieldDims
[aResData
.DataFieldIndex
];
73 sheet::DataResult aRes
= aResData
.Result
;
74 double nVal
= aRes
.Value
;
76 Sequence
< Sequence
<Any
> > aData
= xDPTable
->getDrillDownData(rResultCell
);
79 if( aData
.getLength() > 1 )
81 sum
= std::accumulate(std::next(aData
.begin()), aData
.end(), double(0),
82 [nDim
](double res
, const Sequence
<Any
>& rSeq
) {
84 if (rSeq
[nDim
] >>= nValue
)
90 CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal
, sum
, 1E-12);
96 void XDataPilotTable2::testGetOutputRangeByType()
98 uno::Reference
< sheet::XDataPilotTable2
> xDPTable(initDP2(), UNO_QUERY_THROW
);
99 getOutputRanges(xDPTable
);
101 // check for wrong arguments
102 bool bCaught
= false;
105 xDPTable
->getOutputRangeByType(-1);
107 catch ( const lang::IllegalArgumentException
& )
111 CPPUNIT_ASSERT(bCaught
);
116 xDPTable
->getOutputRangeByType(100);
118 catch ( const lang::IllegalArgumentException
& )
122 CPPUNIT_ASSERT(bCaught
);
124 // make sure the whole range is not empty
125 CPPUNIT_ASSERT( maRangeWhole
.EndColumn
- maRangeWhole
.StartColumn
> 0);
126 CPPUNIT_ASSERT( maRangeWhole
.EndRow
- maRangeWhole
.StartRow
> 0);
128 //table range must be of equal width with the whole range, and the same bottom
129 CPPUNIT_ASSERT_EQUAL( maRangeWhole
.Sheet
, maRangeTable
.Sheet
);
130 CPPUNIT_ASSERT_EQUAL( maRangeWhole
.EndRow
, maRangeTable
.EndRow
);
131 CPPUNIT_ASSERT_EQUAL( maRangeWhole
.StartColumn
, maRangeTable
.StartColumn
);
132 CPPUNIT_ASSERT_EQUAL( maRangeWhole
.EndColumn
, maRangeTable
.EndColumn
);
134 //result range must be smaller than the table range, and must share the same lower-right corner
135 CPPUNIT_ASSERT_EQUAL( maRangeTable
.Sheet
, maRangeResult
.Sheet
);
136 CPPUNIT_ASSERT( maRangeResult
.StartColumn
>= maRangeTable
.StartColumn
);
137 CPPUNIT_ASSERT( maRangeResult
.StartRow
>= maRangeTable
.StartRow
);
138 CPPUNIT_ASSERT_EQUAL( maRangeTable
.EndRow
, maRangeResult
.EndRow
);
139 CPPUNIT_ASSERT_EQUAL( maRangeTable
.EndColumn
, maRangeResult
.EndColumn
);
143 void XDataPilotTable2::testInsertDrillDownSheet()
145 uno::Reference
< sheet::XDataPilotTable2
> xDPTable(initDP2(), UNO_QUERY_THROW
);
146 sal_Int32 nCellCount
= maResultCells
.size();
148 uno::Reference
< sheet::XSpreadsheets
> xSheets(getSheets(), UNO_QUERY_THROW
);
149 uno::Reference
< container::XIndexAccess
> xIA(xSheets
, UNO_QUERY_THROW
);
150 sal_Int32 nSheetCount
= xIA
->getCount();
152 for (sal_Int32 i
= 0; i
< nCellCount
; ++i
)
154 table::CellAddress aAddr
= maResultCells
[i
];
155 uno::Sequence
< uno::Sequence
< Any
> > aData
= xDPTable
->getDrillDownData(aAddr
);
156 xDPTable
->insertDrillDownSheet(aAddr
);
158 sal_Int32 nNewSheetCount
= xIA
->getCount();
159 if (nNewSheetCount
== nSheetCount
+ 1)
161 CPPUNIT_ASSERT(aData
.getLength() >= 2);
162 uno::Reference
< sheet::XSpreadsheet
> xSheet(xIA
->getByIndex(aAddr
.Sheet
),UNO_QUERY_THROW
);
164 checkDrillDownSheetContent(xSheet
, aData
);
166 uno::Reference
< container::XNamed
> xNamed(xSheet
, UNO_QUERY_THROW
);
167 OUString aName
= xNamed
->getName();
168 xSheets
->removeByName(aName
);
170 else if (nNewSheetCount
== nSheetCount
)
172 if (aData
.getLength() > 1)
174 CPPUNIT_ASSERT(false);
179 CPPUNIT_ASSERT(false);
185 void XDataPilotTable2::buildResultCells( uno::Reference
< sheet::XDataPilotTable2
> const & xDPTable
)
187 getOutputRanges(xDPTable
);
188 maResultCells
.clear();
190 for ( sal_Int32 x
= maRangeResult
.StartColumn
; x
< maRangeResult
.EndColumn
; ++x
)
192 for( sal_Int32 y
= maRangeResult
.StartRow
; y
< maRangeResult
.EndRow
; ++y
)
194 table::CellAddress aAddr
;
195 aAddr
.Sheet
= maRangeResult
.Sheet
;
198 sheet::DataPilotTablePositionData aPosData
= xDPTable
->getPositionData(aAddr
);
199 if (aPosData
.PositionType
!= sheet::DataPilotTablePositionType::RESULT
)
201 CPPUNIT_ASSERT(false);
203 maResultCells
.push_back(aAddr
);
208 void XDataPilotTable2::getOutputRanges( uno::Reference
< sheet::XDataPilotTable2
> const & xDPTable
)
210 maRangeWhole
= xDPTable
->getOutputRangeByType(sheet::DataPilotOutputRangeType::WHOLE
);
211 maRangeTable
= xDPTable
->getOutputRangeByType(sheet::DataPilotOutputRangeType::TABLE
);
212 maRangeResult
= xDPTable
->getOutputRangeByType(sheet::DataPilotOutputRangeType::RESULT
);
215 void XDataPilotTable2::buildDataFields( uno::Reference
< sheet::XDataPilotTable2
> const & xDPTable
)
217 uno::Reference
< sheet::XDataPilotDescriptor
> xDesc(xDPTable
, UNO_QUERY_THROW
);
218 uno::Reference
< container::XIndexAccess
> xIndex(xDesc
->getDataPilotFields(), UNO_SET_THROW
);
220 sal_Int32 nFieldCount
= xIndex
->getCount();
221 for( sal_Int32 i
= 0; i
< nFieldCount
; ++i
)
223 uno::Reference
< beans::XPropertySet
> xPropSet(xIndex
->getByIndex(i
), UNO_QUERY_THROW
);
224 Any aAny
= xPropSet
->getPropertyValue("Orientation");
225 sheet::DataPilotFieldOrientation aOrientation
;
226 CPPUNIT_ASSERT( aAny
>>= aOrientation
);
228 if ( aOrientation
== sheet::DataPilotFieldOrientation_DATA
)
230 maDataFieldDims
.push_back( i
);
237 table::CellAddress
getLastUsedCellAddress( uno::Reference
< sheet::XSpreadsheet
> const & xSheet
, sal_Int32 nCol
, sal_Int32 nRow
)
239 uno::Reference
< sheet::XSheetCellRange
> xSheetRange( xSheet
->getCellRangeByPosition(nCol
, nRow
, nCol
, nRow
), UNO_QUERY_THROW
);
240 uno::Reference
< sheet::XSheetCellCursor
> xCursor
= xSheet
->createCursorByRange(xSheetRange
);
241 uno::Reference
< table::XCellCursor
> xCellCursor(xCursor
, UNO_QUERY_THROW
);
242 xCellCursor
->gotoEnd();
244 uno::Reference
< sheet::XCellAddressable
> xCellAddr(xCursor
->getCellByPosition(0, 0), UNO_QUERY_THROW
);
245 return xCellAddr
->getCellAddress();
250 void XDataPilotTable2::checkDrillDownSheetContent(uno::Reference
< sheet::XSpreadsheet
> const & xSheet
, const uno::Sequence
< uno::Sequence
< Any
> >& aData
)
252 table::CellAddress aLastCell
= getLastUsedCellAddress(xSheet
, 0, 0);
253 CPPUNIT_ASSERT(aData
.hasElements());
254 CPPUNIT_ASSERT(aLastCell
.Row
);
255 CPPUNIT_ASSERT(aLastCell
.Column
);
257 CPPUNIT_ASSERT_EQUAL(aData
.getLength(), aLastCell
.Row
+ 1);
258 CPPUNIT_ASSERT_EQUAL(aData
[0].getLength(), aLastCell
.Column
+ 1);
260 uno::Reference
< table::XCellRange
> xCellRange
= xSheet
->getCellRangeByPosition(0, 0, aLastCell
.Column
, aLastCell
.Row
);
261 uno::Reference
< sheet::XCellRangeData
> xCellRangeData(xCellRange
, UNO_QUERY_THROW
);
263 uno::Sequence
< uno::Sequence
< Any
> > aSheetData
= xCellRangeData
->getDataArray();
264 for (sal_Int32 x
= 0; x
< aSheetData
.getLength(); ++x
)
266 for(sal_Int32 y
= 0; y
< aSheetData
[x
].getLength(); ++y
)
268 Any
& aCell1
= aSheetData
[x
][y
];
269 const Any
& aCell2
= aData
[x
][y
];
270 CPPUNIT_ASSERT_EQUAL(aCell2
, aCell1
);
276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */