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/.
13 #include <colorscale.hxx>
14 #include <conditio.hxx>
15 #include <document.hxx>
16 #include <formulacell.hxx>
17 #include "qahelper.hxx"
18 #include <formula/errorcodes.hxx>
20 struct FindCondFormatByEnclosingRange
22 explicit FindCondFormatByEnclosingRange(const ScRange
& rRange
):
25 bool operator()(const std::unique_ptr
<ScConditionalFormat
>& pFormat
)
27 if (pFormat
->GetRange().Combine() == mrRange
)
34 const ScRange
& mrRange
;
40 ScColorScaleEntryType eLowerLimitType
;
41 ScColorScaleEntryType eUpperLimitType
;
42 databar::ScAxisPosition eAxisPosition
;
45 DataBarData
const aData
[] = {
46 { ScRange(1,2,0,1,5,0), COLORSCALE_AUTO
, COLORSCALE_AUTO
, databar::AUTOMATIC
},
47 { ScRange(3,2,0,3,5,0), COLORSCALE_MIN
, COLORSCALE_MAX
, databar::AUTOMATIC
},
48 { ScRange(5,2,0,5,5,0), COLORSCALE_PERCENTILE
, COLORSCALE_PERCENT
, databar::AUTOMATIC
},
49 { ScRange(7,2,0,7,5,0), COLORSCALE_VALUE
, COLORSCALE_FORMULA
, databar::AUTOMATIC
},
50 { ScRange(1,9,0,1,12,0), COLORSCALE_AUTO
, COLORSCALE_AUTO
, databar::MIDDLE
}
53 void testDataBar_Impl(const ScDocument
& rDoc
)
55 ScConditionalFormatList
* pList
= rDoc
.GetCondFormList(0);
56 CPPUNIT_ASSERT(pList
);
58 for(size_t i
= 0; i
< std::size(aData
); ++i
)
60 ScConditionalFormatList::const_iterator itr
= std::find_if(pList
->begin(),
61 pList
->end(), FindCondFormatByEnclosingRange(aData
[i
].aRange
));
62 CPPUNIT_ASSERT(itr
!= pList
->end());
63 CPPUNIT_ASSERT_EQUAL(size_t(1), (*itr
)->size());
65 const ScFormatEntry
* pFormatEntry
= (*itr
)->GetEntry(0);
66 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Databar
, pFormatEntry
->GetType());
67 const ScDataBarFormat
* pDataBar
= static_cast<const ScDataBarFormat
*>(pFormatEntry
);
68 CPPUNIT_ASSERT(pDataBar
);
69 const ScDataBarFormatData
* pDataBarData
= pDataBar
->GetDataBarData();
70 CPPUNIT_ASSERT_EQUAL(aData
[i
].eLowerLimitType
, pDataBarData
->mpLowerLimit
->GetType());
71 CPPUNIT_ASSERT_EQUAL(aData
[i
].eUpperLimitType
, pDataBarData
->mpUpperLimit
->GetType());
73 CPPUNIT_ASSERT_EQUAL(aData
[i
].eAxisPosition
, pDataBarData
->meAxisPosition
);
77 struct ColorScale2EntryData
80 ScColorScaleEntryType eLowerType
;
81 ScColorScaleEntryType eUpperType
;
84 ColorScale2EntryData
const aData2Entry
[] = {
85 { ScRange(1,2,0,1,5,0), COLORSCALE_MIN
, COLORSCALE_MAX
},
86 { ScRange(3,2,0,3,5,0), COLORSCALE_PERCENTILE
, COLORSCALE_PERCENT
},
87 { ScRange(5,2,0,5,5,0), COLORSCALE_VALUE
, COLORSCALE_FORMULA
}
90 void testColorScale2Entry_Impl(const ScDocument
& rDoc
)
92 const ScConditionalFormatList
* pList
= rDoc
.GetCondFormList(0);
93 CPPUNIT_ASSERT(pList
);
95 for(size_t i
= 0; i
< std::size(aData2Entry
); ++i
)
97 ScConditionalFormatList::const_iterator itr
= std::find_if(pList
->begin(),
98 pList
->end(), FindCondFormatByEnclosingRange(aData2Entry
[i
].aRange
));
99 CPPUNIT_ASSERT(itr
!= pList
->end());
100 CPPUNIT_ASSERT_EQUAL(size_t(1), (*itr
)->size());
102 const ScFormatEntry
* pFormatEntry
= (*itr
)->GetEntry(0);
103 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Colorscale
, pFormatEntry
->GetType());
104 const ScColorScaleFormat
* pColFormat
= static_cast<const ScColorScaleFormat
*>(pFormatEntry
);
105 CPPUNIT_ASSERT_EQUAL(size_t(2), pColFormat
->size());
107 ScColorScaleEntries::const_iterator format_itr
= pColFormat
->begin();
108 CPPUNIT_ASSERT_EQUAL(aData2Entry
[i
].eLowerType
, (*format_itr
)->GetType());
110 CPPUNIT_ASSERT(format_itr
!= pColFormat
->end());
111 CPPUNIT_ASSERT_EQUAL(aData2Entry
[i
].eUpperType
, (*format_itr
)->GetType());
115 struct ColorScale3EntryData
118 ScColorScaleEntryType eLowerType
;
119 ScColorScaleEntryType eMiddleType
;
120 ScColorScaleEntryType eUpperType
;
123 ColorScale3EntryData
const aData3Entry
[] = {
124 { ScRange(1,1,1,1,6,1), COLORSCALE_MIN
, COLORSCALE_PERCENTILE
, COLORSCALE_MAX
},
125 { ScRange(3,1,1,3,6,1), COLORSCALE_PERCENTILE
, COLORSCALE_VALUE
, COLORSCALE_PERCENT
},
126 { ScRange(5,1,1,5,6,1), COLORSCALE_VALUE
, COLORSCALE_VALUE
, COLORSCALE_FORMULA
}
129 void testColorScale3Entry_Impl(const ScDocument
& rDoc
)
131 ScConditionalFormatList
* pList
= rDoc
.GetCondFormList(1);
132 CPPUNIT_ASSERT(pList
);
134 for(size_t i
= 0; i
< std::size(aData3Entry
); ++i
)
136 ScConditionalFormatList::const_iterator itr
= std::find_if(pList
->begin(),
137 pList
->end(), FindCondFormatByEnclosingRange(aData3Entry
[i
].aRange
));
138 CPPUNIT_ASSERT(itr
!= pList
->end());
139 CPPUNIT_ASSERT_EQUAL(size_t(1), (*itr
)->size());
141 const ScFormatEntry
* pFormatEntry
= (*itr
)->GetEntry(0);
142 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Colorscale
, pFormatEntry
->GetType());
143 const ScColorScaleFormat
* pColFormat
= static_cast<const ScColorScaleFormat
*>(pFormatEntry
);
144 CPPUNIT_ASSERT_EQUAL(size_t(3), pColFormat
->size());
146 ScColorScaleEntries::const_iterator format_itr
= pColFormat
->begin();
147 CPPUNIT_ASSERT_EQUAL(aData3Entry
[i
].eLowerType
, (*format_itr
)->GetType());
149 CPPUNIT_ASSERT(format_itr
!= pColFormat
->end());
150 CPPUNIT_ASSERT_EQUAL(aData3Entry
[i
].eMiddleType
, (*format_itr
)->GetType());
152 CPPUNIT_ASSERT(format_itr
!= pColFormat
->end());
153 CPPUNIT_ASSERT_EQUAL(aData3Entry
[i
].eUpperType
, (*format_itr
)->GetType());
157 bool isFormulaWithoutError(ScDocument
& rDoc
, const ScAddress
& rPos
)
159 ScFormulaCell
* pFC
= rDoc
.GetFormulaCell(rPos
);
163 return pFC
->GetErrCode() == FormulaError::NONE
;
166 void testFunctionsExcel2010_Impl( ScDocument
& rDoc
)
168 // Original test case document is functions-excel-2010.xlsx
169 // Which test rows to evaluate, 1-based as in UI to ease maintenance.
175 { 2, false }, // name=[ AGGREGATE ], result=0, expected=1
218 { 45, false }, // name=[ NETWORKDAYS.INTL ], result=18, expected=19
252 { 79, false }, // name=[ WORKDAY.INTL ], result=41755 , expected=41754
256 for (size_t i
=0; i
< std::size(aTests
); ++i
)
258 if (aTests
[i
].bEvaluate
)
260 // Column 0 is description, 1 is formula, 2 is Excel result, 3 is
262 SCROW nRow
= aTests
[i
].nRow
- 1; // 0-based
264 OString aStr
= OString::number( aTests
[i
].nRow
) +
265 ", function name=[ " +
266 OUStringToOString( rDoc
.GetString( ScAddress( 0, nRow
, 0)), RTL_TEXTENCODING_UTF8
) +
268 OString::number( rDoc
.GetValue( ScAddress( 1, nRow
, 0)) ) +
270 OString::number( rDoc
.GetValue( ScAddress( 2, nRow
, 0)) );
272 ScFormulaCell
* pFC
= rDoc
.GetFormulaCell( ScAddress( 1, nRow
, 0) );
273 if ( pFC
&& pFC
->GetErrCode() != FormulaError::NONE
)
274 aStr
+= ", error code =" + OString::number( static_cast<int>(pFC
->GetErrCode()) );
276 CPPUNIT_ASSERT_MESSAGE( OString( "Expected a formula cell without error at row " +
277 aStr
).getStr(), isFormulaWithoutError( rDoc
, ScAddress( 1, nRow
, 0)));
278 CPPUNIT_ASSERT_MESSAGE( OString( "Expected a TRUE value at row " +
279 aStr
).getStr(), 0 != rDoc
.GetValue( ScAddress( 3, nRow
, 0)));
285 void testCeilingFloor_Impl( ScDocument
& rDoc
)
287 // Original test case document is ceiling-floor.xlsx
288 // Sheet1.K1 has =AND(K3:K81) to evaluate all results.
289 static constexpr OUString pORef
= u
"Sheet1.K1"_ustr
;
291 aPos
.Parse(pORef
, rDoc
);
292 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula.", u
"=AND(K3:K81)"_ustr
, rDoc
.GetFormula(aPos
.Col(), aPos
.Row(), aPos
.Tab()));
293 CPPUNIT_ASSERT_MESSAGE( OUString( pORef
+ " result is error.").toUtf8().getStr(),
294 isFormulaWithoutError( rDoc
, aPos
));
295 CPPUNIT_ASSERT_EQUAL(1.0, rDoc
.GetValue(aPos
));
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */