notepad-plus-plus/scintilla/test/unit/testPartitioning.cxx

228 lines
6.2 KiB
C++

/** @file testPartitioning.cxx
** Unit Tests for Scintilla internal data structures
**/
#include <cstddef>
#include <cstring>
#include <stdexcept>
#include <string_view>
#include <vector>
#include <optional>
#include <algorithm>
#include <memory>
#include "Debugging.h"
#include "Position.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "catch.hpp"
using namespace Scintilla::Internal;
constexpr int lengthTestArray = 8;
static const int testArray[lengthTestArray] = {3, 4, 5, 6, 7, 8, 9, 10};
// Test Partitioning.
TEST_CASE("CompileCopying Partitioning") {
// These are compile-time tests to check that basic copy and move
// operations are defined correctly.
SECTION("CopyingMoving") {
Partitioning<int> s;
Partitioning<int> s2;
// Copy constructor
Partitioning<int> sa(s);
// Copy assignment
Partitioning<int> sb;
sb = s;
// Move constructor
Partitioning<int> sc(std::move(s));
// Move assignment
Partitioning<int> sd;
sd = (std::move(s2));
}
}
TEST_CASE("Partitioning") {
Partitioning<Sci::Position> part;
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));
part.Check();
}
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));
part.Check();
}
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));
part.Check();
}
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));
part.Check();
}
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));
part.Check();
}
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));
part.Check();
}
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));
part.Check();
}
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));
part.Check();
}
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));
part.Check();
}
}