Avoid potential negative array index access to cached text.
[LibreOffice.git] / sc / qa / unit / ucalc_rangelst.cxx
blob9146227cabc1a7a9fd628de23c78f18ab29378ad
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <sal/config.h>
11 #include "helper/qahelper.hxx"
12 #include <docsh.hxx>
14 #include <rangelst.hxx>
16 class Test : public ScUcalcTestBase
20 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_4Ranges)
22 ScRangeList aList(ScRange(0,0,0,5,5,0));
23 aList.DeleteArea(2,2,0,3,3,0);
25 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), aList.size());
26 for(SCCOL nCol = 0; nCol <= 5; ++nCol)
28 for(SCROW nRow = 0; nRow <= 5; ++nRow)
30 if((nCol == 2 || nCol == 3) && ( nRow == 2 || nRow == 3))
31 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
32 else
33 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
38 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_3Ranges)
40 ScRangeList aList(ScRange(1,1,0,6,6,0));
41 aList.DeleteArea(3,3,0,8,4,0);
43 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aList.size());
44 for(SCCOL nCol = 1; nCol <= 6; ++nCol)
46 for(SCROW nRow = 1; nRow <= 6; ++nRow)
48 if((nRow == 3 || nRow == 4) && (nCol >= 3))
49 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
50 else
51 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
55 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt64>(28), aList.GetCellCount());
58 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_3Ranges_Case2)
60 ScRangeList aList(ScRange(1,1,0,6,6,0));
61 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
62 aList.DeleteArea(0,2,0,2,4,0);
63 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aList.size());
65 // Column 1-2 && Row 2-4 should not be in the range list. The rest should
66 // be in the list.
67 for (SCCOL nCol = 1; nCol <= 6; ++nCol)
69 for (SCROW nRow = 1; nRow <= 6; ++nRow)
71 if ((1 <= nCol && nCol <= 2) && (2 <= nRow && nRow <= 4))
72 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
73 else
74 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
79 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_3Ranges_Case3)
81 ScRangeList aList(ScRange(1,5,0,6,11,0));
82 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
83 aList.DeleteArea(3,2,0,4,8,0);
84 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aList.size());
86 // Column 3-4 && Row 5-8 should not be in the range list.
87 for (SCCOL nCol = 1; nCol <= 6; ++nCol)
89 for (SCROW nRow = 5; nRow <= 11; ++nRow)
91 if ((3 <= nCol && nCol <= 4) && (5 <= nRow && nRow <= 8))
92 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
93 else
94 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
99 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_3Ranges_Case4)
101 ScRangeList aList(ScRange(1,5,0,6,11,0));
102 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
103 aList.DeleteArea(3,5,0,4,5,0);
104 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aList.size());
106 // Column 3-4 && Row 5 should not be in the range list.
107 for (SCCOL nCol = 1; nCol <= 6; ++nCol)
109 for (SCROW nRow = 5; nRow <= 11; ++nRow)
111 if ((3 <= nCol && nCol <= 4) && 5 == nRow )
112 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
113 else
114 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
119 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_3Ranges_Case5)
121 ScRangeList aList(ScRange(1,5,0,6,11,0));
122 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
123 aList.DeleteArea(6,7,0,6,9,0);
124 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aList.size());
126 // Column 6 && Row 7-9 should not be in the range list.
127 for (SCCOL nCol = 1; nCol <= 6; ++nCol)
129 for (SCROW nRow = 5; nRow <= 11; ++nRow)
131 if ( nCol == 6 && (7 <= nRow && nRow <= 9))
132 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
133 else
134 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
139 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_2Ranges)
141 ScRangeList aList(ScRange(0,0,0,5,5,5));
142 ScRangeList aList2(aList);
144 aList.DeleteArea(4,4,0,6,7,0);
145 aList2.DeleteArea(4,4,0,6,7,0);
146 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
147 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList2.size());
149 for(SCCOL nCol = 0; nCol <= 5; ++nCol)
151 for(SCROW nRow = 0; nRow <= 5; ++nRow)
153 if(nCol>=4 && nRow >= 4)
154 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
155 else
156 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
161 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_2Ranges_Case2)
163 ScRangeList aList(ScRange(1,1,0,1,5,0));
164 aList.DeleteArea(0,3,0,ScSheetLimits::CreateDefault().MaxCol(),3,0);
166 for(SCROW nRow = 1; nRow <= 5; ++nRow)
168 if(nRow == 3)
169 CPPUNIT_ASSERT(!aList.Contains(ScRange(1,3,0)));
170 else
171 CPPUNIT_ASSERT(aList.Contains(ScRange(1,nRow,0)));
173 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt64>(4), aList.GetCellCount());
176 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_2Ranges_Case3)
178 ScRangeList aList(ScRange(0,5,0,2,10,0));
179 aList.DeleteArea(2,3,0,3,7,0);
180 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
182 // Column 2 Row 5-7 shouldn't be in the list.
183 for (SCCOL nCol = 0; nCol <= 2; ++nCol)
185 for (SCROW nRow = 5; nRow <= 10; ++nRow)
187 if (nCol == 2 && (5 <= nRow && nRow <= 7))
188 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol,nRow,0)));
189 else
190 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol,nRow,0)));
195 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_2Ranges_Case4)
197 ScRangeList aList(ScRange(2,3,0,4,7,0));
198 aList.DeleteArea(0,1,0,2,5,0);
199 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
201 // Column 2 Row 3-5 shouldn't be in the list.
202 for (SCCOL nCol = 2; nCol <= 4; ++nCol)
204 for (SCROW nRow = 3; nRow <= 7; ++nRow)
206 if (nCol == 2 && (3 <= nRow && nRow <= 5))
207 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol,nRow,0)));
208 else
209 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol,nRow,0)));
214 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_2Ranges_Case5)
216 ScRangeList aList(ScRange(2,2,0,5,5,0));
217 aList.DeleteArea(4,5,0,5,5,0);
218 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
220 // Column 4 and 5 Row 5 shouldn't be in the list.
221 for(SCCOL nCol = 2; nCol <= 5; ++nCol)
223 for(SCROW nRow = 2; nRow <= 5; ++nRow)
225 if(nRow == 5 && 4 <= nCol)
226 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
227 else
228 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
233 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_2Ranges_Case6)
235 ScRangeList aList(ScRange(2,2,0,5,5,0));
236 aList.DeleteArea(4,2,0,5,2,0);
237 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
239 // Column 4 and 5 Row 2 shouldn't be in the list.
240 for(SCCOL nCol = 2; nCol <= 5; ++nCol)
242 for(SCROW nRow = 2; nRow <= 5; ++nRow)
244 if(nRow == 2 && 4 <= nCol)
245 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
246 else
247 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
252 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_2Ranges_Case7)
254 ScRangeList aList(ScRange(2,2,0,5,5,0));
255 aList.DeleteArea(2,5,0,2,5,0);
256 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
258 // Column 2 Row 5 shouldn't be in the list.
259 for(SCCOL nCol = 2; nCol <= 5; ++nCol)
261 for(SCROW nRow = 2; nRow <= 5; ++nRow)
263 if(nRow == 5 && nCol == 2)
264 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
265 else
266 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
271 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_2Ranges_Case8)
273 ScRangeList aList(ScRange(2,2,0,5,5,0));
274 aList.DeleteArea(2,2,0,3,2,0);
275 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
277 // Column 2 & 3 Row 2 shouldn't be in the list.
278 for(SCCOL nCol = 2; nCol <= 5; ++nCol)
280 for(SCROW nRow = 2; nRow <= 5; ++nRow)
282 if(nRow == 2 && nCol <= 3)
283 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, nRow, 0)));
284 else
285 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
290 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_1Range)
292 ScRangeList aList(ScRange(1,1,0,3,3,0));
293 aList.DeleteArea(1,1,0,2,3,0);
295 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
297 for(SCROW nRow = 1; nRow <= 3; ++nRow)
299 CPPUNIT_ASSERT(aList.Contains(ScRange(3,nRow,0)));
301 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt64>(3), aList.GetCellCount());
304 CPPUNIT_TEST_FIXTURE(Test, testDeleteArea_0Ranges)
306 ScRangeList aList(ScRange(1,1,0,3,3,0));
307 aList.DeleteArea(1,1,0,3,3,0);
309 CPPUNIT_ASSERT(aList.empty());
311 ScRangeList aList2(ScRange(1,1,0,3,3,0));
312 aList2.DeleteArea(0,0,0,4,4,0);
314 CPPUNIT_ASSERT(aList.empty());
317 CPPUNIT_TEST_FIXTURE(Test, testJoin_Case1)
319 ScRangeList aList;
320 aList.push_back(ScRange(1,1,0,3,3,0));
321 aList.Join(ScRange(4,1,0,6,3,0));
323 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
324 CPPUNIT_ASSERT_EQUAL( ScRange(1,1,0,6,3,0), aList[0]);
327 CPPUNIT_TEST_FIXTURE(Test, testJoin_Case2)
329 ScRangeList aList;
330 aList.push_back(ScRange(1,1,0,3,3,0));
331 aList.push_back(ScRange(4,1,0,6,3,0));
332 aList.push_back(ScRange(7,1,0,9,3,0));
334 aList.Join(aList[2], true);
336 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
337 CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,9,3,0), aList[0]);
340 CPPUNIT_TEST_FIXTURE(Test, testJoin_Case3)
342 ScRangeList aList;
343 aList.Join(ScRange(1,1,0,6,6,0));
344 aList.Join(ScRange(3,3,0,4,4,0));
346 // The second one should have been swallowed by the first one
347 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
348 CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,6,6,0), aList[0]);
350 // Add a disjoint one
351 aList.Join(ScRange(8,8,0,9,9,0));
353 // Should be two ones now
354 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
355 // The first one should still be as is
356 CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,6,6,0), aList[0]);
357 // Ditto for the second one
358 CPPUNIT_ASSERT_EQUAL(ScRange(8,8,0,9,9,0), aList[1]);
361 CPPUNIT_TEST_FIXTURE(Test, testJoin_Case4)
363 ScRangeList aList;
364 aList.Join(ScRange(1,1,0,2,6,0));
365 // Join a range that overlaps it and extends it vertically
366 aList.Join(ScRange(1,4,0,2,8,0));
368 // The one range in the list should have been extended
369 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
370 CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,2,8,0), aList[0]);
372 // Join a range that overlaps it and extends it horizontally
373 aList.Join(ScRange(2,1,0,4,8,0));
375 // Again, should have just been extended
376 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
377 CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,4,8,0), aList[0]);
379 // And then the same but on top / to the left of existing range
380 ScRangeList aList2;
381 aList2.Join(ScRange(4,4,0,8,8,0));
382 aList2.Join(ScRange(4,1,0,8,6,0));
384 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList2.size());
385 CPPUNIT_ASSERT_EQUAL(ScRange(4,1,0,8,8,0), aList2[0]);
387 aList2.Join(ScRange(1,1,0,6,8,0));
389 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList2.size());
390 CPPUNIT_ASSERT_EQUAL(ScRange(1,1,0,8,8,0), aList2[0]);
393 CPPUNIT_TEST_FIXTURE(Test, testJoin_Case5)
395 ScRangeList aList;
396 aList.Join(ScRange(0,0,0,4,4,0));
397 aList.Join(ScRange(8,0,0,10,4,0));
399 // Nothing special so far, two disjoint ranges
400 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aList.size());
401 CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,4,4,0), aList[0]);
402 CPPUNIT_ASSERT_EQUAL(ScRange(8,0,0,10,4,0), aList[1]);
404 // This should join the two ranges into one
405 aList.Join(ScRange(5,0,0,9,4,0));
407 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aList.size());
408 CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,10,4,0), aList[0]);
411 CPPUNIT_TEST_FIXTURE(Test, testUpdateReference_DeleteRow)
413 ScRangeList aList(ScRange(1,1,0,4,4,0));
414 bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,3,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0);
415 CPPUNIT_ASSERT(bUpdated);
417 for(SCCOL nCol = 1; nCol <= 4; ++nCol)
419 for(SCROW nRow = 1; nRow <= 3; ++nRow)
421 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
423 CPPUNIT_ASSERT(!aList.Contains(ScRange(nCol, 4, 0)));
425 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt64>(12), aList.GetCellCount());
427 ScRangeList aList2(ScRange(2,2,0,2,2,0));
428 aList2.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,3,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0);
429 CPPUNIT_ASSERT(aList2.empty());
431 ScRangeList aList3;
432 aList3.push_back(ScRange(2,2,0,2,8,0));
433 aList3.push_back(ScRange(4,2,0,4,8,0));
434 aList3.UpdateReference(URM_INSDEL, m_pDoc, ScRange(2,5,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), 0, -1, 0);
435 // Verify all ranges in the list have been updated properly.
436 CPPUNIT_ASSERT_EQUAL(size_t(2), aList3.size());
437 CPPUNIT_ASSERT_EQUAL(ScRange(2,2,0,2,7,0), aList3[0]);
438 CPPUNIT_ASSERT_EQUAL(ScRange(4,2,0,4,7,0), aList3[1]);
440 ScRangeList aList4(ScRange(0,0,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0));
441 ScRangeList aList4Copy = aList4;
442 aList4.UpdateReference(URM_INSDEL, m_pDoc, ScRange(14,3,0,m_pDoc->MaxCol(),7,0), 0, -2, 0);
443 CPPUNIT_ASSERT_EQUAL(aList4Copy, aList4);
446 CPPUNIT_TEST_FIXTURE(Test, testUpdateReference_DeleteLastRow)
448 ScRangeList aList(ScRange(1,1,0,4,4,0));
449 bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(0,4,0,m_pDoc->MaxCol(),4,0), 0, -1, 0);
450 CPPUNIT_ASSERT(bUpdated);
453 CPPUNIT_TEST_FIXTURE(Test, testUpdateReference_DeleteCol)
455 ScRangeList aList(ScRange(1,1,0,4,4,0));
456 bool bUpdated = aList.UpdateReference(URM_INSDEL, m_pDoc, ScRange(3,0,0,m_pDoc->MaxCol(),m_pDoc->MaxRow(),0), -1, 0, 0);
457 CPPUNIT_ASSERT(bUpdated);
459 for(SCROW nRow = 1; nRow <= 4; ++nRow)
461 for(SCCOL nCol = 1; nCol <= 3; ++nCol)
463 CPPUNIT_ASSERT(aList.Contains(ScRange(nCol, nRow, 0)));
465 CPPUNIT_ASSERT(!aList.Contains(ScRange(4, nRow, 0)));
467 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt64>(12), aList.GetCellCount());
470 CPPUNIT_TEST_FIXTURE(Test, testGetIntersectedRange)
472 ScRangeList aList(ScRange(2, 2, 0, 5, 5, 0));
473 ScRangeList aIntersecting = aList.GetIntersectedRange(ScRange(0, 0, 0, 3, 3, 0));
474 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(2,2,0,3,3,0)), aIntersecting);
477 CPPUNIT_TEST_FIXTURE(Test, testInsertRow)
479 ScRangeList aList(ScRange(1,1,0,4,4,0));
480 aList.InsertRow(0, 0, m_pDoc->MaxCol(), 5, 2);
481 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(1,1,0,4,6,0)), aList);
484 CPPUNIT_TEST_FIXTURE(Test, testInsertCol)
486 ScRangeList aList(ScRange(1,1,0,4,4,0));
487 aList.InsertCol(0, 0, m_pDoc->MaxRow(), 5, 2);
488 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(1,1,0,6,4,0)), aList);
491 CPPUNIT_PLUGIN_IMPLEMENT();
492 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */