/** @file testPartitioning.cxx ** Unit Tests for Scintilla internal data structures **/ #include #include #include #include #include #include #include #include #include "Debugging.h" #include "Position.h" #include "SplitVector.h" #include "Partitioning.h" #include "catch.hpp" using namespace Scintilla::Internal; constexpr int growSize = 4; constexpr int lengthTestArray = 8; static const int testArray[lengthTestArray] = {3, 4, 5, 6, 7, 8, 9, 10}; // Test SplitVectorWithRangeAdd. TEST_CASE("SplitVectorWithRangeAdd") { SplitVectorWithRangeAdd svwra(growSize); SECTION("IsEmptyInitially") { REQUIRE(0 == svwra.Length()); } SECTION("IncrementExceptEnds") { svwra.InsertFromArray(0, testArray, 0, lengthTestArray); svwra.RangeAddDelta(1, lengthTestArray-1, 1); for (int i=0; i part(growSize); SECTION("IsEmptyInitially") { REQUIRE(1 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(part.Partitions())); REQUIRE(0 == part.PartitionFromPosition(0)); } SECTION("SimpleInsert") { part.InsertText(0, 1); REQUIRE(1 == part.Partitions()); REQUIRE(1 == part.PositionFromPartition(part.Partitions())); } SECTION("TwoPartitions") { part.InsertText(0, 2); part.InsertPartition(1, 1); REQUIRE(2 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(1 == part.PositionFromPartition(1)); REQUIRE(2 == part.PositionFromPartition(2)); } SECTION("MoveStart") { part.InsertText(0, 3); part.InsertPartition(1, 2); part.SetPartitionStartPosition(1,1); REQUIRE(2 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(1 == part.PositionFromPartition(1)); REQUIRE(3 == part.PositionFromPartition(2)); } SECTION("InsertAgain") { part.InsertText(0, 3); part.InsertPartition(1, 2); part.InsertText(0,3); part.InsertText(1,2); REQUIRE(2 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(5 == part.PositionFromPartition(1)); REQUIRE(8 == part.PositionFromPartition(2)); } SECTION("InsertMultiple") { part.InsertText(0, 10); const Sci::Position positions[] { 2, 5, 7 }; part.InsertPartitions(1, positions, std::size(positions)); REQUIRE(4 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(2 == part.PositionFromPartition(1)); REQUIRE(5 == part.PositionFromPartition(2)); REQUIRE(7 == part.PositionFromPartition(3)); REQUIRE(10 == part.PositionFromPartition(4)); } SECTION("InsertMultipleWithCast") { part.InsertText(0, 9); REQUIRE(1 == part.Partitions()); const ptrdiff_t positionsp[]{ 2, 4, 6, 8 }; part.InsertPartitionsWithCast(1, positionsp, std::size(positionsp)); REQUIRE(5 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(2 == part.PositionFromPartition(1)); REQUIRE(4 == part.PositionFromPartition(2)); REQUIRE(6 == part.PositionFromPartition(3)); REQUIRE(8 == part.PositionFromPartition(4)); REQUIRE(9 == part.PositionFromPartition(5)); } SECTION("InsertReversed") { part.InsertText(0, 3); part.InsertPartition(1, 2); part.InsertText(1,2); part.InsertText(0,3); REQUIRE(2 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(5 == part.PositionFromPartition(1)); REQUIRE(8 == part.PositionFromPartition(2)); } SECTION("InverseSearch") { part.InsertText(0, 3); part.InsertPartition(1, 2); part.SetPartitionStartPosition(1,1); REQUIRE(2 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(1 == part.PositionFromPartition(1)); REQUIRE(3 == part.PositionFromPartition(2)); REQUIRE(0 == part.PartitionFromPosition(0)); REQUIRE(1 == part.PartitionFromPosition(1)); REQUIRE(1 == part.PartitionFromPosition(2)); REQUIRE(1 == part.PartitionFromPosition(3)); } SECTION("DeletePartition") { part.InsertText(0, 2); part.InsertPartition(1, 1); part.RemovePartition(1); REQUIRE(1 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(2 == part.PositionFromPartition(1)); } SECTION("DeleteAll") { part.InsertText(0, 3); part.InsertPartition(1, 2); part.SetPartitionStartPosition(1,1); part.DeleteAll(); // Back to initial state REQUIRE(1 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(part.Partitions())); } SECTION("TestBackwards") { part.InsertText(0, 10); part.InsertPartition(1, 3); part.InsertPartition(2, 6); part.InsertPartition(3, 9); part.InsertText(2,4); part.InsertText(1,2); part.InsertText(0,3); REQUIRE(4 == part.Partitions()); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(6 == part.PositionFromPartition(1)); REQUIRE(11 == part.PositionFromPartition(2)); REQUIRE(18 == part.PositionFromPartition(3)); REQUIRE(19 == part.PositionFromPartition(4)); } SECTION("TestMany") { // Provoke backstep call part.InsertText(0, 42); for (int i=0; i<20; i++) { part.InsertPartition(i+1, (i+1) * 2); } for (int i=20; i>0; i--) { part.InsertText(i,2); } REQUIRE(21 == part.Partitions()); for (int i=1; i<20; i++) { REQUIRE((i*4 - 2) == part.PositionFromPartition(i)); REQUIRE(i == part.PartitionFromPosition(i*4 - 2)); } part.InsertText(19,2); REQUIRE(3 == part.PartitionFromPosition(10)); part.InsertText(0,2); part.InsertText(0,-2); part.RemovePartition(1); REQUIRE(0 == part.PositionFromPartition(0)); REQUIRE(6 == part.PositionFromPartition(1)); REQUIRE(10 == part.PositionFromPartition(2)); part.RemovePartition(10); REQUIRE(46 == part.PositionFromPartition(10)); REQUIRE(10 == part.PartitionFromPosition(46)); REQUIRE(50 == part.PositionFromPartition(11)); REQUIRE(11 == part.PartitionFromPosition(50)); } }