diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sc/qa/unit/mark_test.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/qa/unit/mark_test.cxx')
-rw-r--r-- | sc/qa/unit/mark_test.cxx | 1015 |
1 files changed, 1015 insertions, 0 deletions
diff --git a/sc/qa/unit/mark_test.cxx b/sc/qa/unit/mark_test.cxx new file mode 100644 index 000000000..bca735aae --- /dev/null +++ b/sc/qa/unit/mark_test.cxx @@ -0,0 +1,1015 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <sal/config.h> +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestAssert.h> +#include <cppunit/plugin/TestPlugIn.h> + +#include <markdata.hxx> +#include <sheetlimits.hxx> +#if defined __GNUC__ && !defined __clang__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsubobject-linkage" + // automatically suppressed in the main .cxx, but not in this included one +#endif +#include "../../source/core/data/segmenttree.cxx" +#if defined __GNUC__ && !defined __clang__ +#pragma GCC diagnostic push +#endif + +#include <utility> + +namespace { + +struct MarkTestData // To represent a single rectangle part of a multiselection +{ + ScRange aRange; + bool bMark; + + // Cumulative Test data follows + std::vector<ScAddress> aInsideAddresses; + std::vector<ScAddress> aOutsideAddresses; + + std::vector<SCCOL> aColumnsWithFullMarks; + std::vector<SCCOL> aColumnsWithoutFullMarks; + + std::vector<SCROW> aRowsWithFullMarks; + std::vector<SCROW> aRowsWithoutFullMarks; + + std::vector<ScRange> aRangesWithFullMarks; + std::vector<ScRange> aRangesWithoutFullMarks; + + // To test ScMarkData::GetNextMarked() + // Encoding : EndRow is the next marked row in the column = StartCol after StartRow. + // EndCol = 0 means search up, 1 means to search down + std::vector<ScRange> aNextMarked; + + std::vector<SCCOL> aColumnsWithAtLeastOneMark; + std::vector<SCCOL> aColumnsWithoutAnyMarks; + +}; + +struct MarkArrayTestData +{ + SCCOL nCol; + std::vector<std::pair<SCROW,SCROW>> aMarkedRowSegs; +}; + +struct MultiMarkTestData +{ + std::vector<MarkTestData> aMarks; + ScRange aSelectionCover; + ScRangeList aLeftEnvelope; + ScRangeList aRightEnvelope; + ScRangeList aTopEnvelope; + ScRangeList aBottomEnvelope; + std::vector<MarkArrayTestData> aMarkArrays; + + // To test ScMultiSel::HasOneMark() + // Encoding : StartCol is the column to test, StartRow is the beginning of the one mark, + // EndRow is the end of the one mark, EndCol is not used + std::vector<ScRange> aColsWithOneMark; + std::vector<SCCOL> aColsWithoutOneMark; + + // To test ScMultiSel::IsAllMarked() + // Encoding StartCol is the column to be queried, [StartRow,EndRow] is the range to test. + std::vector<ScRange> aColsAllMarked; + std::vector<ScRange> aColsNotAllMarked; + + // To test ScMultiSel::HasEqualRowsMarked() + std::vector<std::pair<SCCOL,SCCOL>> aColsWithEqualMarksList; + std::vector<std::pair<SCCOL,SCCOL>> aColsWithUnequalMarksList; +}; + +} + +class Test : public CppUnit::TestFixture +{ +public: + void testSimpleMark( const ScRange& rRange, const ScRange& rSelectionCover, + const ScRangeList& rLeftEnvelope, const ScRangeList& rRightEnvelope, + const ScRangeList& rTopEnvelope, const ScRangeList& rBottomEnvelope, + const ScSheetLimits& rLimits ); + void testSimpleMark_Simple(); + void testSimpleMark_Column(); + void testSimpleMark_Row(); + + void testMultiMark( const MultiMarkTestData& rData ); + void testMultiMark_FourRanges(); + void testMultiMark_NegativeMarking(); + + void testInsertTabBeforeSelected(); + void testInsertTabAfterSelected(); + void testDeleteTabBeforeSelected(); + void testDeleteTabAfterSelected(); + + void testScMarkArraySearch(); + + void testIsAllMarked(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testSimpleMark_Simple); + CPPUNIT_TEST(testSimpleMark_Column); + CPPUNIT_TEST(testSimpleMark_Row); + CPPUNIT_TEST(testMultiMark_FourRanges); + CPPUNIT_TEST(testMultiMark_NegativeMarking); + CPPUNIT_TEST(testInsertTabBeforeSelected); + CPPUNIT_TEST(testInsertTabAfterSelected); + CPPUNIT_TEST(testDeleteTabBeforeSelected); + CPPUNIT_TEST(testDeleteTabAfterSelected); + CPPUNIT_TEST(testScMarkArraySearch); + CPPUNIT_TEST(testIsAllMarked); + CPPUNIT_TEST_SUITE_END(); + +private: + void testScMarkArraySearch_check(const ScMarkArray & ar, SCROW nRow, bool expectStatus, SCSIZE nIndexExpect); +}; + +static void lcl_GetSortedRanges( const ScRangeList& rRangeList, ScRangeList& rRangeListOut ) +{ + rRangeListOut.RemoveAll(); + std::vector<ScRange> aRanges; + size_t nSize = rRangeList.size(); + aRanges.reserve( nSize ); + for ( size_t nIdx = 0; nIdx < nSize; ++nIdx ) + aRanges.push_back( rRangeList[nIdx] ); + std::sort( aRanges.begin(), aRanges.end() ); + for ( size_t nIdx = 0; nIdx < nSize; ++nIdx ) + rRangeListOut.push_back( aRanges[nIdx] ); +} + +void Test::testSimpleMark( const ScRange& rRange, const ScRange& rSelectionCover, + const ScRangeList& rLeftEnvelope, const ScRangeList& rRightEnvelope, + const ScRangeList& rTopEnvelope, const ScRangeList& rBottomEnvelope, + const ScSheetLimits& rLimits ) +{ + ScMarkData aMark(rLimits); + CPPUNIT_ASSERT( !aMark.IsMarked() ); + CPPUNIT_ASSERT( !aMark.IsMultiMarked() ); + + aMark.SetMarkArea( rRange ); + CPPUNIT_ASSERT( aMark.IsMarked() ); + CPPUNIT_ASSERT( !aMark.IsMultiMarked() ); + + CPPUNIT_ASSERT_EQUAL( rRange, aMark.GetMarkArea() ); + + SCROW nMidRow = ( rRange.aStart.Row() + rRange.aEnd.Row() ) / 2; + SCCOL nMidCol = ( rRange.aStart.Col() + rRange.aEnd.Col() ) / 2; + SCROW nOutRow1 = rRange.aEnd.Row() + 1; + SCCOL nOutCol1 = rRange.aEnd.Col() + 1; + SCROW nOutRow2 = rRange.aStart.Row() - 1; + SCCOL nOutCol2 = rRange.aStart.Col() - 1; + + CPPUNIT_ASSERT( aMark.IsCellMarked( nMidCol, nMidRow ) ); + if ( ValidCol( nOutCol1, rLimits.MaxCol() ) && ValidRow( nOutRow1, rLimits.MaxRow() ) ) + CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol1, nOutRow1 ) ); + + if ( ValidCol( nOutCol2, rLimits.MaxCol() ) && ValidRow( nOutRow2, rLimits.MaxRow() ) ) + CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol2, nOutRow2 ) ); + + if ( ValidRow( nOutRow1, rLimits.MaxRow() ) ) + CPPUNIT_ASSERT( !aMark.IsCellMarked( nMidCol, nOutRow1 ) ); + + if ( ValidCol( nOutCol1, rLimits.MaxCol() ) ) + CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol1, nMidRow ) ); + + if ( ValidRow( nOutRow2, rLimits.MaxRow() ) ) + CPPUNIT_ASSERT( !aMark.IsCellMarked( nMidCol, nOutRow2 ) ); + + if ( ValidCol( nOutCol2, rLimits.MaxCol() ) ) + CPPUNIT_ASSERT( !aMark.IsCellMarked( nOutCol2, nMidRow ) ); + + if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == rLimits.MaxRow() ) + CPPUNIT_ASSERT( aMark.IsColumnMarked( nMidCol ) ); + else + CPPUNIT_ASSERT( !aMark.IsColumnMarked( nMidCol ) ); + if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == rLimits.MaxCol() ) + CPPUNIT_ASSERT( aMark.IsRowMarked( nMidRow ) ); + else + CPPUNIT_ASSERT( !aMark.IsRowMarked( nMidRow ) ); + + ScRange aSelectionCoverOutput; + aMark.GetSelectionCover( aSelectionCoverOutput ); + CPPUNIT_ASSERT_EQUAL( rSelectionCover, aSelectionCoverOutput ); + CPPUNIT_ASSERT_EQUAL( rLeftEnvelope, aMark.GetLeftEnvelope() ); + CPPUNIT_ASSERT_EQUAL( rRightEnvelope, aMark.GetRightEnvelope() ); + CPPUNIT_ASSERT_EQUAL( rTopEnvelope, aMark.GetTopEnvelope() ); + CPPUNIT_ASSERT_EQUAL( rBottomEnvelope, aMark.GetBottomEnvelope() ); +} + +void Test::testSimpleMark_Simple() +{ + ScSheetLimits limits( ScSheetLimits::CreateDefault()); + testSimpleMark( ScRange( 10, 15, 0, 20, 30, 0 ), // Simple range + ScRange( 9, 14, 0, 21, 31, 0 ), // Cover + ScRangeList( ScRange( 9, 15, 0, 9, 30, 0 ) ), // Left envelope + ScRangeList( ScRange( 21, 15, 0, 21, 30, 0 ) ), // Right envelope + ScRangeList( ScRange( 10, 14, 0, 20, 14, 0 ) ), // Top envelope + ScRangeList( ScRange( 10, 31, 0, 20, 31, 0 ) ), // Bottom envelope + limits ); +} + +void Test::testSimpleMark_Column() +{ + ScSheetLimits limits( ScSheetLimits::CreateDefault()); + // Column 10, rows from 15 to 30 + testSimpleMark( ScRange( 10, 15, 0, 10, 30, 0 ), // Simple range + ScRange( 9, 14, 0, 11, 31, 0 ), // Cover + ScRangeList( ScRange( 9, 15, 0, 9, 30, 0 ) ), // Left envelope + ScRangeList( ScRange( 11, 15, 0, 11, 30, 0 ) ), // Right envelope + ScRangeList( ScRange( 10, 14, 0, 10, 14, 0 ) ), // Top envelope + ScRangeList( ScRange( 10, 31, 0, 10, 31, 0 ) ), // Bottom envelope + limits ); + + // Full Column 10 + testSimpleMark( ScRange( 10, 0, 0, 10, limits.MaxRow(), 0 ), // Simple range + ScRange( 9, 0, 0, 11, limits.MaxRow(), 0 ), // Cover + ScRangeList( ScRange( 9, 0, 0, 9, limits.MaxRow(), 0 ) ), // Left envelope + ScRangeList( ScRange( 11, 0, 0, 11, limits.MaxRow(), 0 ) ), // Right envelope + ScRangeList(), // Top envelope + ScRangeList(), // Bottom envelope + limits ); +} + +void Test::testSimpleMark_Row() +{ + ScSheetLimits limits( ScSheetLimits::CreateDefault()); + // Row 15, cols from 10 to 20 + testSimpleMark( ScRange( 10, 15, 0, 20, 15, 0 ), // Simple range + ScRange( 9, 14, 0, 21, 16, 0 ), // Cover + ScRangeList( ScRange( 9, 15, 0, 9, 15, 0 ) ), // Left envelope + ScRangeList( ScRange( 21, 15, 0, 21, 15, 0 ) ), // Right envelope + ScRangeList( ScRange( 10, 14, 0, 20, 14, 0 ) ), // Top envelope + ScRangeList( ScRange( 10, 16, 0, 20, 16, 0 ) ), // Bottom envelope + limits ); + + // Full Row 15 + testSimpleMark( ScRange( 0, 15, 0, limits.MaxCol(), 15, 0 ), // Simple range + ScRange( 0, 14, 0, limits.MaxCol(), 16, 0 ), // Cover + ScRangeList(), // Left envelope + ScRangeList(), // Right envelope + ScRangeList( ScRange( 0, 14, 0, limits.MaxCol(), 14, 0 ) ), // Top envelope + ScRangeList( ScRange( 0, 16, 0, limits.MaxCol(), 16, 0 ) ), // Bottom envelope + limits ); +} + +void Test::testMultiMark( const MultiMarkTestData& rMarksData ) +{ + ScSheetLimits limits( ScSheetLimits::CreateDefault()); + ScMarkData aMark(limits); + ScMultiSel aMultiSel(limits); + CPPUNIT_ASSERT( !aMark.IsMarked() ); + CPPUNIT_ASSERT( !aMark.IsMultiMarked() ); + CPPUNIT_ASSERT_EQUAL( SCCOL(0), aMultiSel.GetMultiSelectionCount() ); + CPPUNIT_ASSERT( !aMultiSel.HasAnyMarks() ); + + for ( const auto& rAreaTestData : rMarksData.aMarks ) + { + aMultiSel.SetMarkArea( rAreaTestData.aRange.aStart.Col(), rAreaTestData.aRange.aEnd.Col(), + rAreaTestData.aRange.aStart.Row(), rAreaTestData.aRange.aEnd.Row(), + rAreaTestData.bMark ); + aMark.SetMultiMarkArea( rAreaTestData.aRange, rAreaTestData.bMark ); + CPPUNIT_ASSERT( aMark.IsMultiMarked() ); + + for ( const auto& rMarkedAddress : rAreaTestData.aInsideAddresses ) + { + CPPUNIT_ASSERT( aMultiSel.GetMark( rMarkedAddress.Col(), rMarkedAddress.Row() ) ); + CPPUNIT_ASSERT( aMark.IsCellMarked( rMarkedAddress.Col(), rMarkedAddress.Row() ) ); + } + + for ( const auto& rUnMarkedAddress : rAreaTestData.aOutsideAddresses ) + { + CPPUNIT_ASSERT( !aMark.IsCellMarked( rUnMarkedAddress.Col(), rUnMarkedAddress.Row() ) ); + CPPUNIT_ASSERT( !aMark.IsCellMarked( rUnMarkedAddress.Col(), rUnMarkedAddress.Row() ) ); + } + + for ( const auto& rCol : rAreaTestData.aColumnsWithFullMarks ) + { + CPPUNIT_ASSERT( aMark.IsColumnMarked( rCol ) ); + CPPUNIT_ASSERT( aMultiSel.IsAllMarked( rCol, 0, limits.MaxRow() ) ); + } + + for ( const auto& rCol : rAreaTestData.aColumnsWithoutFullMarks ) + { + CPPUNIT_ASSERT( !aMark.IsColumnMarked( rCol ) ); + CPPUNIT_ASSERT( !aMultiSel.IsAllMarked( rCol, 0, limits.MaxRow() ) ); + } + + for ( const auto& rRow : rAreaTestData.aRowsWithFullMarks ) + { + CPPUNIT_ASSERT( aMark.IsRowMarked( rRow ) ); + CPPUNIT_ASSERT( aMultiSel.IsRowMarked( rRow ) ); + } + + for ( const auto& rRow : rAreaTestData.aRowsWithoutFullMarks ) + { + CPPUNIT_ASSERT( !aMark.IsRowMarked( rRow ) ); + CPPUNIT_ASSERT( !aMultiSel.IsRowMarked( rRow ) ); + } + + for ( const auto& rRange : rAreaTestData.aRangesWithFullMarks ) + { + CPPUNIT_ASSERT( aMark.IsAllMarked( rRange ) ); + SCROW nRow1 = rRange.aStart.Row(), nRow2 = rRange.aEnd.Row(); + SCCOL nCol1 = rRange.aStart.Col(), nCol2 = rRange.aEnd.Col(); + for ( SCCOL nColIter = nCol1; nColIter <= nCol2; ++nColIter ) + CPPUNIT_ASSERT( aMultiSel.IsAllMarked( nColIter, nRow1, nRow2 ) ); + } + + for ( const auto& rRange : rAreaTestData.aRangesWithoutFullMarks ) + CPPUNIT_ASSERT( !aMark.IsAllMarked( rRange ) ); + + for ( const auto& rRange : rAreaTestData.aNextMarked ) + { + SCROW nNextRow1 = aMark.GetNextMarked( rRange.aStart.Col(), rRange.aStart.Row(), !static_cast<bool>(rRange.aEnd.Col()) ); + CPPUNIT_ASSERT_EQUAL( rRange.aEnd.Row(), nNextRow1 ); + SCROW nNextRow2 = aMultiSel.GetNextMarked( rRange.aStart.Col(), rRange.aStart.Row(), !static_cast<bool>(rRange.aEnd.Col()) ); + CPPUNIT_ASSERT_EQUAL( rRange.aEnd.Row(), nNextRow2 ); + } + + for ( const auto& rCol : rAreaTestData.aColumnsWithAtLeastOneMark ) + { + CPPUNIT_ASSERT( aMark.HasMultiMarks( rCol ) ); + CPPUNIT_ASSERT( aMultiSel.HasMarks( rCol ) ); + } + + for ( const auto& rCol : rAreaTestData.aColumnsWithoutAnyMarks ) + { + CPPUNIT_ASSERT( !aMark.HasMultiMarks( rCol ) ); + CPPUNIT_ASSERT( !aMultiSel.HasMarks( rCol ) ); + } + + } + + ScRange aSelectionCoverOutput; + aMark.GetSelectionCover( aSelectionCoverOutput ); + CPPUNIT_ASSERT_EQUAL( rMarksData.aSelectionCover, aSelectionCoverOutput ); + + ScRangeList aRangesExpected, aRangesActual; + lcl_GetSortedRanges( rMarksData.aLeftEnvelope, aRangesExpected ); + lcl_GetSortedRanges( aMark.GetLeftEnvelope(), aRangesActual ); + CPPUNIT_ASSERT_EQUAL( aRangesExpected, aRangesActual ); + lcl_GetSortedRanges( rMarksData.aRightEnvelope, aRangesExpected ); + lcl_GetSortedRanges( aMark.GetRightEnvelope(), aRangesActual ); + CPPUNIT_ASSERT_EQUAL( aRangesExpected, aRangesActual ); + lcl_GetSortedRanges( rMarksData.aTopEnvelope, aRangesExpected ); + lcl_GetSortedRanges( aMark.GetTopEnvelope(), aRangesActual ); + CPPUNIT_ASSERT_EQUAL( aRangesExpected, aRangesActual ); + lcl_GetSortedRanges( rMarksData.aBottomEnvelope, aRangesExpected ); + lcl_GetSortedRanges( aMark.GetBottomEnvelope(), aRangesActual ); + CPPUNIT_ASSERT_EQUAL( aRangesExpected, aRangesActual ); + + for ( const auto& rMarkArrayTestData : rMarksData.aMarkArrays ) + { + ScMarkArray aArray( aMark.GetMarkArray( rMarkArrayTestData.nCol ) ); + std::vector<std::pair<SCROW, SCROW>> aMarkedRowSegs; + ScMarkArrayIter aIter( &aArray ); + SCROW nStart, nEnd; + while ( aIter.Next( nStart, nEnd ) ) + aMarkedRowSegs.emplace_back( nStart, nEnd ); + + CPPUNIT_ASSERT_EQUAL( rMarkArrayTestData.aMarkedRowSegs.size(), aMarkedRowSegs.size() ); + size_t nIdx = 0; + for ( const auto& rPair : rMarkArrayTestData.aMarkedRowSegs ) + { + CPPUNIT_ASSERT_EQUAL( rPair.first, aMarkedRowSegs[nIdx].first ); + CPPUNIT_ASSERT_EQUAL( rPair.second, aMarkedRowSegs[nIdx].second ); + ++nIdx; + } + } + + for ( const auto& rColWithOneMark : rMarksData.aColsWithOneMark ) + { + SCROW nRow1 = -1, nRow2 = -1; + CPPUNIT_ASSERT( aMultiSel.HasOneMark( rColWithOneMark.aStart.Col(), nRow1, nRow2 ) ); + CPPUNIT_ASSERT_EQUAL( rColWithOneMark.aStart.Row(), nRow1 ); + CPPUNIT_ASSERT_EQUAL( rColWithOneMark.aEnd.Row(), nRow2 ); + } + + { + SCROW nRow1 = -1, nRow2 = -1; + for ( const SCCOL& rCol : rMarksData.aColsWithoutOneMark ) + CPPUNIT_ASSERT( !aMultiSel.HasOneMark( rCol, nRow1, nRow2 ) ); + } + + for ( const auto& rColAllMarked : rMarksData.aColsAllMarked ) + CPPUNIT_ASSERT( aMultiSel.IsAllMarked( rColAllMarked.aStart.Col(), + rColAllMarked.aStart.Row(), + rColAllMarked.aEnd.Row() ) ); + + for ( const auto& rColNotAllMarked : rMarksData.aColsNotAllMarked ) + CPPUNIT_ASSERT( !aMultiSel.IsAllMarked( rColNotAllMarked.aStart.Col(), + rColNotAllMarked.aStart.Row(), + rColNotAllMarked.aEnd.Row() ) ); + + for ( const auto& rColsWithEqualMarks : rMarksData.aColsWithEqualMarksList ) + CPPUNIT_ASSERT( aMultiSel.HasEqualRowsMarked( rColsWithEqualMarks.first, rColsWithEqualMarks.second ) ); + + for ( const auto& rColsWithUnequalMarks : rMarksData.aColsWithUnequalMarksList ) + CPPUNIT_ASSERT( !aMultiSel.HasEqualRowsMarked( rColsWithUnequalMarks.first, rColsWithUnequalMarks.second ) ); + + aMultiSel.Clear(); + CPPUNIT_ASSERT_EQUAL( SCCOL(0), aMultiSel.GetMultiSelectionCount() ); + CPPUNIT_ASSERT( !aMultiSel.HasAnyMarks() ); +} + +void Test::testMultiMark_FourRanges() +{ + ScSheetLimits limits( ScSheetLimits::CreateDefault()); + MultiMarkTestData aData; + MarkTestData aSingle1; + + // Create rectangle ( 10, 5, 20, 10 ) + aSingle1.aRange = ScRange( 10, 5, 0, 20, 10, 0 ); + aSingle1.bMark = true; + + aSingle1.aInsideAddresses.emplace_back( 15, 6, 0 ); + aSingle1.aInsideAddresses.emplace_back( 10, 5, 0 ); + aSingle1.aInsideAddresses.emplace_back( 20, 5, 0 ); + aSingle1.aInsideAddresses.emplace_back( 10, 10, 0 ); + aSingle1.aInsideAddresses.emplace_back( 20, 10, 0 ); + + aSingle1.aOutsideAddresses.emplace_back( 15, 4, 0 ); + aSingle1.aOutsideAddresses.emplace_back( 15, 11, 0 ); + aSingle1.aOutsideAddresses.emplace_back( 9, 6, 0 ); + aSingle1.aOutsideAddresses.emplace_back( 21, 6, 0 ); + aSingle1.aOutsideAddresses.emplace_back( 26, 10, 0 ); + + aSingle1.aColumnsWithoutFullMarks.push_back( 16 ); + aSingle1.aColumnsWithoutFullMarks.push_back( 21 ); + + aSingle1.aRowsWithoutFullMarks.push_back( 7 ); + aSingle1.aRowsWithoutFullMarks.push_back( 11 ); + + aSingle1.aRangesWithFullMarks.emplace_back( 10, 5, 0, 20, 10, 0 ); + aSingle1.aRangesWithFullMarks.emplace_back( 11, 6, 0, 19, 8, 0 ); + + aSingle1.aRangesWithoutFullMarks.emplace_back( 9, 4, 0, 21, 11, 0 ); + aSingle1.aRangesWithoutFullMarks.emplace_back( 25, 7, 0, 30, 15, 0 ); + + aSingle1.aNextMarked.emplace_back( 15, 1, 0, 1, 5, 0 ); // Search down + aSingle1.aNextMarked.emplace_back( 15, 15, 0, 0, 10, 0 ); // Search up + + aSingle1.aNextMarked.emplace_back( 15, 15, 0, 1, limits.GetMaxRowCount(), 0 ); // Search down fail + aSingle1.aNextMarked.emplace_back( 15, 4, 0, 0, -1, 0 ); // Search up fail + + aSingle1.aColumnsWithAtLeastOneMark.push_back( 10 ); + aSingle1.aColumnsWithAtLeastOneMark.push_back( 15 ); + aSingle1.aColumnsWithAtLeastOneMark.push_back( 20 ); + + aSingle1.aColumnsWithoutAnyMarks.push_back( 21 ); + aSingle1.aColumnsWithoutAnyMarks.push_back( 9 ); + + // Create rectangle ( 25, 7, 30, 15 ) + MarkTestData aSingle2; + aSingle2.aRange = ScRange( 25, 7, 0, 30, 15, 0 ); + aSingle2.bMark = true; + + aSingle2.aInsideAddresses = aSingle1.aInsideAddresses; + aSingle2.aInsideAddresses.emplace_back( 27, 10, 0 ); + aSingle2.aInsideAddresses.emplace_back( 25, 7, 0 ); + aSingle2.aInsideAddresses.emplace_back( 30, 7, 0 ); + aSingle2.aInsideAddresses.emplace_back( 25, 15, 0 ); + aSingle2.aInsideAddresses.emplace_back( 30, 15, 0 ); + + aSingle2.aOutsideAddresses.emplace_back( 15, 4, 0 ); + aSingle2.aOutsideAddresses.emplace_back( 15, 11, 0 ); + aSingle2.aOutsideAddresses.emplace_back( 9, 6, 0 ); + aSingle2.aOutsideAddresses.emplace_back( 21, 6, 0 ); + aSingle2.aOutsideAddresses.emplace_back( 26, 6, 0 ); + aSingle2.aOutsideAddresses.emplace_back( 26, 16, 0 ); + aSingle2.aOutsideAddresses.emplace_back( 24, 8, 0 ); + aSingle2.aOutsideAddresses.emplace_back( 31, 11, 0 ); + + aSingle2.aColumnsWithoutFullMarks = aSingle1.aColumnsWithoutAnyMarks; + + aSingle2.aRowsWithoutFullMarks = aSingle1.aRowsWithoutFullMarks; + + aSingle2.aRangesWithFullMarks = aSingle1.aRangesWithFullMarks; + aSingle2.aRangesWithFullMarks.emplace_back( 25, 7, 0, 30, 15, 0 ); + aSingle2.aRangesWithFullMarks.emplace_back( 26, 8, 0, 29, 14, 0 ); + + aSingle2.aRangesWithoutFullMarks.emplace_back( 9, 4, 0, 21, 11, 0 ); + aSingle2.aRangesWithoutFullMarks.emplace_back( 24, 6, 0, 31, 16, 0 ); + aSingle2.aRangesWithoutFullMarks.emplace_back( 10, 5, 0, 30, 15, 0 ); + + aSingle2.aNextMarked.emplace_back( 27, 16, 0, 0, 15, 0 ); // up ok + aSingle2.aNextMarked.emplace_back( 27, 4, 0, 1, 7, 0 ); // down ok + aSingle2.aNextMarked.emplace_back( 27, 4, 0, 0, -1, 0 ); // up fail + aSingle2.aNextMarked.emplace_back( 27, 16, 0, 1, limits.GetMaxRowCount(), 0 ); // down fail + + aSingle2.aColumnsWithAtLeastOneMark = aSingle1.aColumnsWithAtLeastOneMark; + aSingle2.aColumnsWithAtLeastOneMark.push_back( 25 ); + aSingle2.aColumnsWithAtLeastOneMark.push_back( 27 ); + aSingle2.aColumnsWithAtLeastOneMark.push_back( 30 ); + + aSingle2.aColumnsWithoutAnyMarks.push_back( 9 ); + aSingle2.aColumnsWithoutAnyMarks.push_back( 21 ); + aSingle2.aColumnsWithoutAnyMarks.push_back( 24 ); + aSingle2.aColumnsWithoutAnyMarks.push_back( 31 ); + + // Full row = 20 + MarkTestData aSingle3; + + aSingle3.aRange = ScRange( 0, 20, 0, limits.MaxCol(), 20, 0 ); + aSingle3.bMark = true; + + aSingle3.aInsideAddresses = aSingle2.aInsideAddresses; + aSingle3.aInsideAddresses.emplace_back( 5, 20, 0 ); + aSingle3.aInsideAddresses.emplace_back( 100, 20, 0 ); + + aSingle3.aOutsideAddresses.emplace_back( 0, 21, 0 ); + aSingle3.aOutsideAddresses.emplace_back( 27, 19, 0 ); + + aSingle3.aColumnsWithoutFullMarks = aSingle2.aColumnsWithoutAnyMarks; + + aSingle3.aRowsWithFullMarks.push_back( 20 ); + + aSingle3.aRangesWithFullMarks = aSingle2.aRangesWithFullMarks; + aSingle3.aRangesWithFullMarks.emplace_back( 0, 20, 0, limits.MaxCol(), 20, 0 ); + aSingle3.aRangesWithFullMarks.emplace_back( 15, 20, 0, 55, 20, 0 ); + + aSingle3.aNextMarked.emplace_back( 15, 16, 0, 0, 10, 0 ); // up ok + aSingle3.aNextMarked.emplace_back( 15, 16, 0, 1, 20, 0 ); // down ok + aSingle3.aNextMarked.emplace_back( 22, 15, 0, 0, -1, 0 ); // up fail + aSingle3.aNextMarked.emplace_back( 22, 25, 0, 1, limits.GetMaxRowCount(), 0 ); // down fail + + aSingle3.aColumnsWithAtLeastOneMark = aSingle2.aColumnsWithAtLeastOneMark; + aSingle3.aColumnsWithAtLeastOneMark.push_back( 39 ); + + // Full col = 35 + MarkTestData aSingle4; + + aSingle4.aRange = ScRange( 35, 0, 0, 35, limits.MaxRow(), 0 ); + aSingle4.bMark = true; + + aSingle4.aInsideAddresses = aSingle3.aInsideAddresses; + aSingle4.aInsideAddresses.emplace_back( 35, 10, 0 ); + aSingle4.aInsideAddresses.emplace_back( 35, 25, 0 ); + + aSingle4.aOutsideAddresses.emplace_back( 33, 10, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 39, 10, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 33, 25, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 39, 25, 0 ); + + aSingle4.aColumnsWithFullMarks.push_back( 35 ); + + aSingle4.aRowsWithFullMarks.push_back( 20 ); + + aSingle4.aRangesWithFullMarks = aSingle3.aRangesWithFullMarks; + aSingle4.aRangesWithFullMarks.emplace_back( 35, 0, 0, 35, limits.MaxRow(), 0 ); + aSingle4.aRangesWithFullMarks.emplace_back( 35, 10, 0, 35, 25, 0 ); + + // Add the rectangle data to aData + aData.aMarks.push_back( aSingle1 ); + aData.aMarks.push_back( aSingle2 ); + aData.aMarks.push_back( aSingle3 ); + aData.aMarks.push_back( aSingle4 ); + + aData.aSelectionCover = ScRange( 0, 0, 0, limits.MaxCol(), limits.MaxRow(), 0 ); + aData.aLeftEnvelope.push_back( ScRange( 9, 5, 0, 9, 10, 0 ) ); + aData.aLeftEnvelope.push_back( ScRange( 24, 7, 0, 24, 15, 0 ) ); + aData.aLeftEnvelope.push_back( ScRange( 34, 0, 0, 34, 19, 0 ) ); + aData.aLeftEnvelope.push_back( ScRange( 34, 21, 0, 34, limits.MaxRow(), 0 ) ); + + aData.aRightEnvelope.push_back( ScRange( 21, 5, 0, 21, 10, 0 ) ); + aData.aRightEnvelope.push_back( ScRange( 31, 7, 0, 31, 15, 0 ) ); + aData.aRightEnvelope.push_back( ScRange( 36, 0, 0, 36, 19, 0 ) ); + aData.aRightEnvelope.push_back( ScRange( 36, 21, 0, 36, limits.MaxRow(), 0 ) ); + + aData.aTopEnvelope.push_back( ScRange( 10, 4, 0, 20, 4, 0 ) ); + aData.aTopEnvelope.push_back( ScRange( 25, 6, 0, 30, 6, 0 ) ); + aData.aTopEnvelope.push_back( ScRange( 0, 19, 0, 34, 19, 0 ) ); + aData.aTopEnvelope.push_back( ScRange( 36, 19, 0, limits.MaxCol(), 19, 0 ) ); + + aData.aBottomEnvelope.push_back( ScRange( 10, 11, 0, 20, 11, 0 ) ); + aData.aBottomEnvelope.push_back( ScRange( 25, 16, 0, 30, 16, 0 ) ); + aData.aBottomEnvelope.push_back( ScRange( 0, 21, 0, 34, 21, 0 ) ); + aData.aBottomEnvelope.push_back( ScRange( 36, 21, 0, limits.MaxCol(), 21, 0 ) ); + + MarkArrayTestData aMarkArrayTestData1; + aMarkArrayTestData1.nCol = 5; + aMarkArrayTestData1.aMarkedRowSegs.emplace_back( 20, 20 ); + + MarkArrayTestData aMarkArrayTestData2; + aMarkArrayTestData2.nCol = 15; + aMarkArrayTestData2.aMarkedRowSegs.emplace_back( 5, 10 ); + aMarkArrayTestData2.aMarkedRowSegs.emplace_back( 20, 20 ); + + MarkArrayTestData aMarkArrayTestData3; + aMarkArrayTestData3.nCol = 22; + aMarkArrayTestData3.aMarkedRowSegs.emplace_back( 20, 20 ); + + MarkArrayTestData aMarkArrayTestData4; + aMarkArrayTestData4.nCol = 27; + aMarkArrayTestData4.aMarkedRowSegs.emplace_back( 7, 15 ); + aMarkArrayTestData4.aMarkedRowSegs.emplace_back( 20, 20 ); + + MarkArrayTestData aMarkArrayTestData5; + aMarkArrayTestData5.nCol = 33; + aMarkArrayTestData5.aMarkedRowSegs.emplace_back( 20, 20 ); + + MarkArrayTestData aMarkArrayTestData6; + aMarkArrayTestData6.nCol = 35; + aMarkArrayTestData6.aMarkedRowSegs.emplace_back( 0, limits.MaxRow() ); + + MarkArrayTestData aMarkArrayTestData7; + aMarkArrayTestData7.nCol = 40; + aMarkArrayTestData7.aMarkedRowSegs.emplace_back( 20, 20 ); + + aData.aMarkArrays.push_back( aMarkArrayTestData1 ); + aData.aMarkArrays.push_back( aMarkArrayTestData2 ); + aData.aMarkArrays.push_back( aMarkArrayTestData3 ); + aData.aMarkArrays.push_back( aMarkArrayTestData4 ); + aData.aMarkArrays.push_back( aMarkArrayTestData5 ); + aData.aMarkArrays.push_back( aMarkArrayTestData6 ); + aData.aMarkArrays.push_back( aMarkArrayTestData7 ); + + aData.aColsWithOneMark.emplace_back( 5, 20, 0, 0, 20, 0 ); + aData.aColsWithOneMark.emplace_back( 22, 20, 0, 0, 20, 0 ); + aData.aColsWithOneMark.emplace_back( 32, 20, 0, 0, 20, 0 ); + aData.aColsWithOneMark.emplace_back( 35, 0, 0, 0, limits.MaxRow(), 0 ); + aData.aColsWithOneMark.emplace_back( 50, 20, 0, 0, 20, 0 ); + + aData.aColsWithoutOneMark.push_back( 10 ); + aData.aColsWithoutOneMark.push_back( 15 ); + aData.aColsWithoutOneMark.push_back( 20 ); + aData.aColsWithoutOneMark.push_back( 25 ); + aData.aColsWithoutOneMark.push_back( 30 ); + + aData.aColsAllMarked.emplace_back( 10, 5, 0, 0, 10, 0 ); + aData.aColsAllMarked.emplace_back( 15, 5, 0, 0, 10, 0 ); + aData.aColsAllMarked.emplace_back( 5, 20, 0, 0, 20, 0 ); + aData.aColsAllMarked.emplace_back( 10, 20, 0, 0, 20, 0 ); + aData.aColsAllMarked.emplace_back( 25, 7, 0, 0, 15, 0 ); + aData.aColsAllMarked.emplace_back( 30, 7, 0, 0, 15, 0 ); + aData.aColsAllMarked.emplace_back( 35, 0, 0, 0, limits.MaxRow(), 0 ); + aData.aColsAllMarked.emplace_back( 100, 20, 0, 0, 20, 0 ); + + aData.aColsNotAllMarked.emplace_back( 5, 5, 0, 0, 25, 0 ); + aData.aColsNotAllMarked.emplace_back( 15, 5, 0, 0, 25, 0 ); + aData.aColsNotAllMarked.emplace_back( 22, 15, 0, 0, 25, 0 ); + aData.aColsNotAllMarked.emplace_back( 27, 7, 0, 0, 20, 0 ); + aData.aColsNotAllMarked.emplace_back( 100, 19, 0, 0, 21, 0 ); + + aData.aColsWithEqualMarksList.emplace_back( 0, 9 ); + aData.aColsWithEqualMarksList.emplace_back( 10, 20 ); + aData.aColsWithEqualMarksList.emplace_back( 21, 24 ); + aData.aColsWithEqualMarksList.emplace_back( 25, 30 ); + aData.aColsWithEqualMarksList.emplace_back( 31, 34 ); + aData.aColsWithEqualMarksList.emplace_back( 36, 100 ); + aData.aColsWithEqualMarksList.emplace_back( 0, 22 ); + aData.aColsWithEqualMarksList.emplace_back( 0, 34 ); + + aData.aColsWithUnequalMarksList.emplace_back( 0, 10 ); + aData.aColsWithUnequalMarksList.emplace_back( 0, 20 ); + aData.aColsWithUnequalMarksList.emplace_back( 10, 21 ); + aData.aColsWithUnequalMarksList.emplace_back( 20, 25 ); + aData.aColsWithUnequalMarksList.emplace_back( 20, 30 ); + aData.aColsWithUnequalMarksList.emplace_back( 24, 30 ); + aData.aColsWithUnequalMarksList.emplace_back( 30, 31 ); + aData.aColsWithUnequalMarksList.emplace_back( 30, 34 ); + aData.aColsWithUnequalMarksList.emplace_back( 30, 35 ); + aData.aColsWithUnequalMarksList.emplace_back( 35, 100 ); + + testMultiMark( aData ); +} + +void Test::testMultiMark_NegativeMarking() +{ + ScSheetLimits limits( ScSheetLimits::CreateDefault()); + MultiMarkTestData aData; + + // Create full row = 5 + MarkTestData aSingle1; + aSingle1.aRange = ScRange( 0, 5, 0, limits.MaxCol(), 5, 0 ); + aSingle1.bMark = true; + + // Create rectangle ( 10, 8, 25, 20 ) + MarkTestData aSingle2; + aSingle2.aRange = ScRange( 10, 8, 0, 25, 20, 0 ); + aSingle2.bMark = true; + + // Create full row = 12 + MarkTestData aSingle3; + aSingle3.aRange = ScRange( 0, 12, 0, limits.MaxCol(), 12, 0 ); + aSingle3.bMark = true; + + // Create deselection rectangle ( 17, 5, 20, 5 ) + MarkTestData aSingle4; + aSingle4.aRange = ScRange( 17, 5, 0, 20, 5, 0 ); + aSingle4.bMark = false; + + aSingle4.aInsideAddresses.emplace_back( 6, 5, 0 ); + aSingle4.aInsideAddresses.emplace_back( 30, 5, 0 ); + aSingle4.aInsideAddresses.emplace_back( 6, 12, 0 ); + aSingle4.aInsideAddresses.emplace_back( 30, 12, 0 ); + aSingle4.aInsideAddresses.emplace_back( 13, 14, 0 ); + aSingle4.aInsideAddresses.emplace_back( 16, 12, 0 ); + + aSingle4.aOutsideAddresses.emplace_back( 5, 2, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 18, 5, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 17, 5, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 20, 5, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 18, 7, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 5, 10, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 30, 10, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 5, 14, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 30, 14, 0 ); + aSingle4.aOutsideAddresses.emplace_back( 18, 25, 0 ); + + aSingle4.aRowsWithFullMarks.push_back( 12 ); + + aSingle4.aRowsWithoutFullMarks.push_back( 5 ); + + aSingle4.aRangesWithFullMarks.emplace_back( 5, 5, 0, 16, 5, 0 ); + aSingle4.aRangesWithFullMarks.emplace_back( 21, 5, 0, 30, 5, 0 ); + aSingle4.aRangesWithFullMarks.emplace_back( 5, 12, 0, 9, 12, 0 ); + aSingle4.aRangesWithFullMarks.emplace_back( 26, 12, 0, 30, 12, 0 ); + aSingle4.aRangesWithFullMarks.emplace_back( 10, 8, 0, 25, 20, 0 ); + + aSingle4.aRangesWithoutFullMarks.emplace_back( 10, 5, 0, 25, 5, 0 ); + + aSingle4.aNextMarked.emplace_back( 18, 7, 0, 0, -1, 0 ); // up fail + aSingle4.aNextMarked.emplace_back( 18, 4, 0, 1, 8, 0 ); // down ok + + // Create deselection rectangle ( 15, 10, 18, 14 ) + MarkTestData aSingle5; + aSingle5.aRange = ScRange( 15, 10, 0, 18, 14, 0 ); + aSingle5.bMark = false; + + aSingle5.aInsideAddresses.emplace_back( 6, 5, 0 ); + aSingle5.aInsideAddresses.emplace_back( 30, 5, 0 ); + aSingle5.aInsideAddresses.emplace_back( 6, 12, 0 ); + aSingle5.aInsideAddresses.emplace_back( 30, 12, 0 ); + aSingle5.aInsideAddresses.emplace_back( 13, 14, 0 ); + + aSingle5.aOutsideAddresses = aSingle4.aOutsideAddresses; + aSingle5.aOutsideAddresses.emplace_back( 17, 12, 0 ); + aSingle5.aOutsideAddresses.emplace_back( 15, 10, 0 ); + aSingle5.aOutsideAddresses.emplace_back( 18, 10, 0 ); + aSingle5.aOutsideAddresses.emplace_back( 15, 14, 0 ); + aSingle5.aOutsideAddresses.emplace_back( 18, 14, 0 ); + + aSingle5.aRowsWithoutFullMarks.push_back( 12 ); + aSingle5.aRowsWithoutFullMarks.push_back( 5 ); + + aSingle5.aRangesWithoutFullMarks.emplace_back( 10, 8, 0, 25, 20, 0 ); + + aSingle5.aNextMarked = aSingle4.aNextMarked; + aSingle5.aNextMarked.emplace_back( 17, 12, 0, 0, 9, 0 ); // up ok + aSingle5.aNextMarked.emplace_back( 17, 12, 0, 1, 15, 0 ); // down ok + + // Add the rectangle data to aData + aData.aMarks.push_back( aSingle1 ); + aData.aMarks.push_back( aSingle2 ); + aData.aMarks.push_back( aSingle3 ); + aData.aMarks.push_back( aSingle4 ); + aData.aMarks.push_back( aSingle5 ); + + aData.aSelectionCover = ScRange( 0, 4, 0, limits.MaxCol(), 21, 0 ); + aData.aLeftEnvelope.push_back( ScRange( 9, 8, 0, 9, 11, 0 ) ); + aData.aLeftEnvelope.push_back( ScRange( 9, 13, 0, 9, 20, 0 ) ); + aData.aLeftEnvelope.push_back( ScRange( 18, 10, 0, 18, 14, 0 ) ); + aData.aLeftEnvelope.push_back( ScRange( 20, 5, 0, 20, 5, 0 ) ); + + aData.aRightEnvelope.push_back( ScRange( 17, 5, 0, 17, 5, 0 ) ); + aData.aRightEnvelope.push_back( ScRange( 15, 10, 0, 15, 14, 0 ) ); + aData.aRightEnvelope.push_back( ScRange( 26, 8, 0, 26, 11, 0 ) ); + aData.aRightEnvelope.push_back( ScRange( 26, 13, 0, 26, 20, 0 ) ); + + aData.aTopEnvelope.push_back( ScRange( 0, 4, 0, 16, 4, 0 ) ); + aData.aTopEnvelope.push_back( ScRange( 21, 4, 0, limits.MaxCol(), 4, 0 ) ); + aData.aTopEnvelope.push_back( ScRange( 10, 7, 0, 25, 7, 0 ) ); + aData.aTopEnvelope.push_back( ScRange( 0, 11, 0, 9, 11, 0 ) ); + aData.aTopEnvelope.push_back( ScRange( 26, 11, 0, limits.MaxCol(), 11, 0 ) ); + aData.aTopEnvelope.push_back( ScRange( 15, 14, 0, 18, 14, 0 ) ); + + aData.aBottomEnvelope.push_back( ScRange( 0, 6, 0, 16, 6, 0 ) ); + aData.aBottomEnvelope.push_back( ScRange( 21, 6, 0, limits.MaxCol(), 6, 0 ) ); + aData.aBottomEnvelope.push_back( ScRange( 15, 10, 0, 18, 10, 0 ) ); + aData.aBottomEnvelope.push_back( ScRange( 0, 13, 0, 9, 13, 0 ) ); + aData.aBottomEnvelope.push_back( ScRange( 26, 13, 0, limits.MaxCol(), 13, 0 ) ); + aData.aBottomEnvelope.push_back( ScRange( 10, 21, 0, 25, 21, 0 ) ); + + aData.aColsWithOneMark.emplace_back( 19, 8, 0, 0, 20, 0 ); + aData.aColsWithOneMark.emplace_back( 20, 8, 0, 0, 20, 0 ); + + aData.aColsWithoutOneMark.push_back( 5 ); + aData.aColsWithoutOneMark.push_back( 10 ); + aData.aColsWithoutOneMark.push_back( 12 ); + aData.aColsWithoutOneMark.push_back( 16 ); + aData.aColsWithoutOneMark.push_back( 17 ); + aData.aColsWithoutOneMark.push_back( 24 ); + aData.aColsWithoutOneMark.push_back( 100 ); + + aData.aColsAllMarked.emplace_back( 10, 8, 0, 0, 20, 0 ); + aData.aColsAllMarked.emplace_back( 17, 8, 0, 0, 9, 0 ); + aData.aColsAllMarked.emplace_back( 20, 8, 0, 0, 20, 0 ); + aData.aColsAllMarked.emplace_back( 100, 5, 0, 0, 5, 0 ); + aData.aColsAllMarked.emplace_back( 100, 12, 0, 0, 12, 0 ); + + aData.aColsNotAllMarked.emplace_back( 5, 5, 0, 0, 12, 0 ); + aData.aColsNotAllMarked.emplace_back( 10, 5, 0, 0, 20, 0 ); + aData.aColsNotAllMarked.emplace_back( 15, 8, 0, 0, 20, 0 ); + aData.aColsNotAllMarked.emplace_back( 18, 8, 0, 0, 20, 0 ); + aData.aColsNotAllMarked.emplace_back( 25, 5, 0, 0, 20, 0 ); + + aData.aColsWithEqualMarksList.emplace_back( 0, 9 ); + aData.aColsWithEqualMarksList.emplace_back( 10, 14 ); + aData.aColsWithEqualMarksList.emplace_back( 15, 16 ); + aData.aColsWithEqualMarksList.emplace_back( 17, 18 ); + aData.aColsWithEqualMarksList.emplace_back( 19, 20 ); + aData.aColsWithEqualMarksList.emplace_back( 21, 25 ); + aData.aColsWithEqualMarksList.emplace_back( 26, 100 ); + aData.aColsWithEqualMarksList.emplace_back( 0, 100 ); + + aData.aColsWithUnequalMarksList.emplace_back( 0, 10 ); + aData.aColsWithUnequalMarksList.emplace_back( 10, 15 ); + aData.aColsWithUnequalMarksList.emplace_back( 15, 17 ); + aData.aColsWithUnequalMarksList.emplace_back( 17, 19 ); + aData.aColsWithUnequalMarksList.emplace_back( 19, 21 ); + aData.aColsWithUnequalMarksList.emplace_back( 21, 26 ); + + testMultiMark( aData ); +} + +void Test::testInsertTabBeforeSelected() +{ + ScMarkData aMark(ScSheetLimits::CreateDefault()); + aMark.SelectOneTable(0); + aMark.InsertTab(0); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetSelectCount()); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetFirstSelected()); +} + +void Test::testInsertTabAfterSelected() +{ + ScMarkData aMark(ScSheetLimits::CreateDefault()); + aMark.SelectOneTable(0); + aMark.InsertTab(1); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetSelectCount()); + CPPUNIT_ASSERT_EQUAL(SCTAB(0), aMark.GetFirstSelected()); +} + +void Test::testDeleteTabBeforeSelected() +{ + ScMarkData aMark(ScSheetLimits::CreateDefault()); + aMark.SelectOneTable(1); + aMark.DeleteTab(0); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetSelectCount()); + CPPUNIT_ASSERT_EQUAL(SCTAB(0), aMark.GetFirstSelected()); +} + +void Test::testDeleteTabAfterSelected() +{ + ScMarkData aMark(ScSheetLimits::CreateDefault()); + aMark.SelectOneTable(0); + aMark.DeleteTab(1); + CPPUNIT_ASSERT_EQUAL(SCTAB(1), aMark.GetSelectCount()); + CPPUNIT_ASSERT_EQUAL(SCTAB(0), aMark.GetFirstSelected()); +} + +void Test::testScMarkArraySearch_check(const ScMarkArray & ar, SCROW nRow, bool expectStatus, SCSIZE nIndexExpect) +{ + SCSIZE nIndex = 0; + bool status = ar.Search(nRow, nIndex); + CPPUNIT_ASSERT_EQUAL(expectStatus, status); + CPPUNIT_ASSERT_EQUAL(nIndexExpect, nIndex); +} + +void Test::testScMarkArraySearch() +{ + ScSheetLimits limits( ScSheetLimits::CreateDefault()); + // empty + { + ScMarkArray ar(limits); + testScMarkArraySearch_check(ar, -1, true, 0); + testScMarkArraySearch_check(ar, 100, true, 0); + } + + // one range + { + ScMarkArray ar(limits); + ar.SetMarkArea(10, 20, true); + + // 0-9,10-20,21+ + + testScMarkArraySearch_check(ar, -100, true, 0); + testScMarkArraySearch_check(ar, -1, true, 0); + + testScMarkArraySearch_check(ar, 0, true, 0); + testScMarkArraySearch_check(ar, 5, true, 0); + testScMarkArraySearch_check(ar, 9, true, 0); + testScMarkArraySearch_check(ar, 10, true, 1); + testScMarkArraySearch_check(ar, 11, true, 1); + testScMarkArraySearch_check(ar, 19, true, 1); + testScMarkArraySearch_check(ar, 20, true, 1); + testScMarkArraySearch_check(ar, 21, true, 2); + testScMarkArraySearch_check(ar, 22, true, 2); + } + + // three ranges + { + ScMarkArray ar(limits); + ar.SetMarkArea(10, 20, true); + ar.SetMarkArea(21, 30, true); + ar.SetMarkArea(50, 100, true); + + // 0-9,10-30,31-49,50-100,101+ + + testScMarkArraySearch_check(ar, -100, true, 0); + testScMarkArraySearch_check(ar, -1, true, 0); + + testScMarkArraySearch_check(ar, 5, true, 0); + testScMarkArraySearch_check(ar, 15, true, 1); + testScMarkArraySearch_check(ar, 25, true, 1); + testScMarkArraySearch_check(ar, 35, true, 2); + testScMarkArraySearch_check(ar, 55, true, 3); + testScMarkArraySearch_check(ar, 20, true, 1); + testScMarkArraySearch_check(ar, 21, true, 1); + } + + // three single-row ranges + { + ScMarkArray ar(limits); + ar.SetMarkArea(4, 4, true); + ar.SetMarkArea(6, 6, true); + ar.SetMarkArea(8, 8, true); + + testScMarkArraySearch_check(ar, -100, true, 0); + testScMarkArraySearch_check(ar, -1, true, 0); + + testScMarkArraySearch_check(ar, 3, true, 0); + testScMarkArraySearch_check(ar, 4, true, 1); + testScMarkArraySearch_check(ar, 5, true, 2); + testScMarkArraySearch_check(ar, 6, true, 3); + testScMarkArraySearch_check(ar, 7, true, 4); + testScMarkArraySearch_check(ar, 8, true, 5); + testScMarkArraySearch_check(ar, 9, true, 6); + testScMarkArraySearch_check(ar, 10, true, 6); + } + + // one range + { + ScMarkArray ar(limits); + ar.SetMarkArea(10, limits.MaxRow(), true); + + // 0-10,11+ + + testScMarkArraySearch_check(ar, -100, true, 0); + testScMarkArraySearch_check(ar, -1, true, 0); + + testScMarkArraySearch_check(ar, 0, true, 0); + testScMarkArraySearch_check(ar, 5, true, 0); + testScMarkArraySearch_check(ar, 9, true, 0); + testScMarkArraySearch_check(ar, 10, true, 1); + testScMarkArraySearch_check(ar, 11, true, 1); + testScMarkArraySearch_check(ar, 12, true, 1); + testScMarkArraySearch_check(ar, 200, true, 1); + testScMarkArraySearch_check(ar, limits.MaxRow(), true, 1); + } +} + +void Test::testIsAllMarked() +{ + ScSheetLimits limits( ScSheetLimits::CreateDefault()); + ScMarkData mark(limits); + ScRange range1( ScAddress( 5, 10, 0 ), ScAddress( 15, 20, 0 )); + ScRange range2( ScAddress( 2, 2, 0 ), ScAddress( 25, 30, 0 )); + CPPUNIT_ASSERT( !mark.IsAllMarked( range1 )); + CPPUNIT_ASSERT( !mark.IsAllMarked( range2 )); + mark.MarkToMulti(); + CPPUNIT_ASSERT( !mark.IsAllMarked( range1 )); + CPPUNIT_ASSERT( !mark.IsAllMarked( range2 )); + + mark.ResetMark(); + mark.SetMarkArea( range1 ); + CPPUNIT_ASSERT( mark.IsAllMarked( range1 )); + CPPUNIT_ASSERT( !mark.IsAllMarked( range2 )); + mark.MarkToMulti(); + CPPUNIT_ASSERT( mark.IsAllMarked( range1 )); + CPPUNIT_ASSERT( !mark.IsAllMarked( range2 )); + + mark.ResetMark(); + mark.SetMarkArea( range2 ); + CPPUNIT_ASSERT( mark.IsAllMarked( range1 )); + CPPUNIT_ASSERT( mark.IsAllMarked( range2 )); + mark.MarkToMulti(); + CPPUNIT_ASSERT( mark.IsAllMarked( range1 )); + CPPUNIT_ASSERT( mark.IsAllMarked( range2 )); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Test); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |