diff options
-rw-r--r-- | test/unit/README | 14 | ||||
-rw-r--r-- | test/unit/SciTE.properties | 4 | ||||
-rw-r--r-- | test/unit/makefile | 62 | ||||
-rw-r--r-- | test/unit/testContractionState.cxx | 125 | ||||
-rw-r--r-- | test/unit/testPartitioning.cxx | 208 | ||||
-rw-r--r-- | test/unit/testRunStyles.cxx | 167 | ||||
-rw-r--r-- | test/unit/testSplitVector.cxx | 220 | ||||
-rw-r--r-- | test/unit/unitTest.cxx | 50 |
8 files changed, 850 insertions, 0 deletions
diff --git a/test/unit/README b/test/unit/README new file mode 100644 index 000000000..0d70fe71f --- /dev/null +++ b/test/unit/README @@ -0,0 +1,14 @@ +The test/unit directory contains unit tests for Scintilla data structures. + +The tests can be run on Windows or Linux using g++ and GNU make. +The Google Test framework is used. +http://code.google.com/p/googletest/ + +Google test must be installed first. +On Linux, install the google test packages libgtest-dev and libgtest0. +On Windows download Google test and install it as a peer to the directory +containing scintilla. The makefile assumes it is in ../../../../gtest-1.5.0. + +To run the tests: +make +./unitTest diff --git a/test/unit/SciTE.properties b/test/unit/SciTE.properties new file mode 100644 index 000000000..8cc762e96 --- /dev/null +++ b/test/unit/SciTE.properties @@ -0,0 +1,4 @@ +if PLAT_WIN + make.command=mingw32-make +command.go.*.cxx=./unitTest +command.go.needs.$(file.patterns.cplusplus)=$(make.command) diff --git a/test/unit/makefile b/test/unit/makefile new file mode 100644 index 000000000..6a4ec8747 --- /dev/null +++ b/test/unit/makefile @@ -0,0 +1,62 @@ +# Build all the unit tests +# Should be run using mingw32-make on Windows + +.SUFFIXES: .cxx + +GTEST_DIR = ../../../../gtest-1.5.0 + +ifdef windir + +DEL = del /q +# Find Google Test headers. +CPPFLAGS += -I$(GTEST_DIR)/include +GTEST_ALL = gtest-all.o +LINKFLAGS = $(CPPFLAGS) $(CXXFLAGS) + +else + +DEL = rm -f +CPPFLAGS = $(shell gtest-config --cppflags) +CXXFLAGS = $(shell gtest-config --cxxflags) +LINKFLAGS = $(shell gtest-config --ldflags --libs) + +endif + +#vpath %.cxx ../src ../lexlib ../lexers +vpath %.cxx ../../src + + +INCLUDEDIRS = -I ../../include -I ../../src -I../../lexlib + + +# Find headers of test code. +CPPFLAGS += $(INCLUDEDIRS) + +CXXFLAGS += -g -Wall -Wextra -Wno-unused-function +#~ CXXFLAGS += -g -Wall + +CASES:=$(addsuffix .o,$(basename $(notdir $(wildcard test*.cxx)))) +TESTEDOBJS=ContractionState.o RunStyles.o + +TESTS=unitTest + +GTEST_HEADERS=$(GTEST_DIR)/include/gtest/*.h $(GTEST_DIR)/include/gtest/internal/*.h + +all: $(TESTS) + +clean: + $(DEL) $(TESTS) *.a *.o *.exe + +# Usually you shouldn't tweak such internal variables, indicated by a +# trailing _. +GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) + +gtest-all.o: $(GTEST_SRCS_) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -I$(GTEST_DIR) -c \ + $(GTEST_DIR)/src/gtest-all.cc + +.cxx.o: + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< + +unitTest: $(CASES) $(TESTEDOBJS) unitTest.o $(GTEST_ALL) + $(CXX) $(LINKFLAGS) $^ -o $@ diff --git a/test/unit/testContractionState.cxx b/test/unit/testContractionState.cxx new file mode 100644 index 000000000..96a7bbf8a --- /dev/null +++ b/test/unit/testContractionState.cxx @@ -0,0 +1,125 @@ +// Unit Tests for Scintilla internal data structures + +#include <string.h> + +#include "Platform.h" + +#include "SplitVector.h" +#include "Partitioning.h" +#include "RunStyles.h" +#include "ContractionState.h" + +#include <gtest/gtest.h> + +// Test ContractionState. + +class ContractionStateTest : public ::testing::Test { +protected: + virtual void SetUp() { + pcs = new ContractionState(); + } + + virtual void TearDown() { + delete pcs; + pcs = 0; + } + + ContractionState *pcs; +}; + +TEST_F(ContractionStateTest, IsEmptyInitially) { + EXPECT_EQ(1, pcs->LinesInDoc()); + EXPECT_EQ(1, pcs->LinesDisplayed()); + EXPECT_EQ(0, pcs->DisplayFromDoc(0)); + EXPECT_EQ(0, pcs->DocFromDisplay(0)); +} + +TEST_F(ContractionStateTest, OneLine) { + pcs->InsertLine(0); + EXPECT_EQ(2, pcs->LinesInDoc()); + EXPECT_EQ(2, pcs->LinesDisplayed()); + EXPECT_EQ(0, pcs->DisplayFromDoc(0)); + EXPECT_EQ(0, pcs->DocFromDisplay(0)); + EXPECT_EQ(1, pcs->DisplayFromDoc(1)); + EXPECT_EQ(1, pcs->DocFromDisplay(1)); +} + +TEST_F(ContractionStateTest, InsertionThenDeletions) { + pcs->InsertLines(0,4); + pcs->DeleteLine(1); + + EXPECT_EQ(4, pcs->LinesInDoc()); + EXPECT_EQ(4, pcs->LinesDisplayed()); + for (int l=0;l<4;l++) { + EXPECT_EQ(l, pcs->DisplayFromDoc(l)); + EXPECT_EQ(l, pcs->DocFromDisplay(l)); + } + + pcs->DeleteLines(0,2); + EXPECT_EQ(2, pcs->LinesInDoc()); + EXPECT_EQ(2, pcs->LinesDisplayed()); + for (int l=0;l<2;l++) { + EXPECT_EQ(l, pcs->DisplayFromDoc(l)); + EXPECT_EQ(l, pcs->DocFromDisplay(l)); + } +} + +TEST_F(ContractionStateTest, ShowHide) { + pcs->InsertLines(0,4); + EXPECT_EQ(true, pcs->GetVisible(0)); + EXPECT_EQ(true, pcs->GetVisible(1)); + EXPECT_EQ(true, pcs->GetVisible(2)); + EXPECT_EQ(5, pcs->LinesDisplayed()); + + pcs->SetVisible(1, 1, false); + EXPECT_EQ(true, pcs->GetVisible(0)); + EXPECT_EQ(0, pcs->GetVisible(1)); + EXPECT_EQ(true, pcs->GetVisible(2)); + EXPECT_EQ(4, pcs->LinesDisplayed()); + + pcs->SetVisible(1, 2, true); + for (int l=0;l<4;l++) { + EXPECT_EQ(true, pcs->GetVisible(0)); + } + + pcs->SetVisible(1, 1, false); + EXPECT_EQ(0, pcs->GetVisible(1)); + pcs->ShowAll(); + for (int l=0;l<4;l++) { + EXPECT_EQ(true, pcs->GetVisible(0)); + } +} + +TEST_F(ContractionStateTest, Contracting) { + pcs->InsertLines(0,4); + for (int l=0;l<4;l++) { + EXPECT_EQ(true, pcs->GetExpanded(l)); + } + + pcs->SetExpanded(2, false); + EXPECT_EQ(true, pcs->GetExpanded(1)); + EXPECT_EQ(0, pcs->GetExpanded(2)); + EXPECT_EQ(true, pcs->GetExpanded(3)); + + EXPECT_EQ(2, pcs->ContractedNext(0)); + EXPECT_EQ(2, pcs->ContractedNext(1)); + EXPECT_EQ(2, pcs->ContractedNext(2)); + EXPECT_EQ(-1, pcs->ContractedNext(3)); + + pcs->SetExpanded(2, true); + EXPECT_EQ(true, pcs->GetExpanded(1)); + EXPECT_EQ(true, pcs->GetExpanded(2)); + EXPECT_EQ(true, pcs->GetExpanded(3)); +} + +TEST_F(ContractionStateTest, ChangeHeight) { + pcs->InsertLines(0,4); + for (int l=0;l<4;l++) { + EXPECT_EQ(1, pcs->GetHeight(l)); + } + + pcs->SetHeight(1, 2); + EXPECT_EQ(1, pcs->GetHeight(0)); + EXPECT_EQ(2, pcs->GetHeight(1)); + EXPECT_EQ(1, pcs->GetHeight(2)); +} diff --git a/test/unit/testPartitioning.cxx b/test/unit/testPartitioning.cxx new file mode 100644 index 000000000..7eff5d9c9 --- /dev/null +++ b/test/unit/testPartitioning.cxx @@ -0,0 +1,208 @@ +// Unit Tests for Scintilla internal data structures + +#include <string.h> + +#include "Platform.h" + +#include "SplitVector.h" +#include "Partitioning.h" + +#include <gtest/gtest.h> + +const int growSize = 4; + +const int lengthTestArray = 8; +static const int testArray[lengthTestArray] = {3, 4, 5, 6, 7, 8, 9, 10}; + +// Test SplitVectorWithRangeAdd. + +class SplitVectorWithRangeAddTest : public ::testing::Test { +protected: + virtual void SetUp() { + psvwra = new SplitVectorWithRangeAdd(growSize); + } + + virtual void TearDown() { + delete psvwra; + psvwra = 0; + } + + SplitVectorWithRangeAdd *psvwra; +}; + +TEST_F(SplitVectorWithRangeAddTest, IsEmptyInitially) { + EXPECT_EQ(0, psvwra->Length()); +} + +TEST_F(SplitVectorWithRangeAddTest, IncrementExceptEnds) { + psvwra->InsertFromArray(0, testArray, 0, lengthTestArray); + psvwra->RangeAddDelta(1, lengthTestArray-1, 1); + for (int i=0; i<psvwra->Length(); i++) { + if ((i == 0) || (i == lengthTestArray-1)) + EXPECT_EQ(i+3, psvwra->ValueAt(i)); + else + EXPECT_EQ(i+4, psvwra->ValueAt(i)); + } +} + +// Test Partitioning. + +class PartitioningTest : public ::testing::Test { +protected: + virtual void SetUp() { + pp = new Partitioning(growSize); + } + + virtual void TearDown() { + delete pp; + pp = 0; + } + + Partitioning *pp; +}; + +TEST_F(PartitioningTest, IsEmptyInitially) { + EXPECT_EQ(1, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(pp->Partitions())); + EXPECT_EQ(0, pp->PartitionFromPosition(0)); +} + +TEST_F(PartitioningTest, SimpleInsert) { + pp->InsertText(0, 1); + EXPECT_EQ(1, pp->Partitions()); + EXPECT_EQ(1, pp->PositionFromPartition(pp->Partitions())); +} + +TEST_F(PartitioningTest, TwoPartitions) { + pp->InsertText(0, 2); + pp->InsertPartition(1, 1); + EXPECT_EQ(2, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(0)); + EXPECT_EQ(1, pp->PositionFromPartition(1)); + EXPECT_EQ(2, pp->PositionFromPartition(2)); +} + +TEST_F(PartitioningTest, MoveStart) { + pp->InsertText(0, 3); + pp->InsertPartition(1, 2); + pp->SetPartitionStartPosition(1,1); + EXPECT_EQ(2, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(0)); + EXPECT_EQ(1, pp->PositionFromPartition(1)); + EXPECT_EQ(3, pp->PositionFromPartition(2)); +} + +TEST_F(PartitioningTest, InsertAgain) { + pp->InsertText(0, 3); + pp->InsertPartition(1, 2); + pp->InsertText(0,3); + pp->InsertText(1,2); + EXPECT_EQ(2, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(0)); + EXPECT_EQ(5, pp->PositionFromPartition(1)); + EXPECT_EQ(8, pp->PositionFromPartition(2)); +} + +TEST_F(PartitioningTest, InsertReversed) { + pp->InsertText(0, 3); + pp->InsertPartition(1, 2); + pp->InsertText(1,2); + pp->InsertText(0,3); + EXPECT_EQ(2, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(0)); + EXPECT_EQ(5, pp->PositionFromPartition(1)); + EXPECT_EQ(8, pp->PositionFromPartition(2)); +} + +TEST_F(PartitioningTest, InverseSearch) { + pp->InsertText(0, 3); + pp->InsertPartition(1, 2); + pp->SetPartitionStartPosition(1,1); + + EXPECT_EQ(2, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(0)); + EXPECT_EQ(1, pp->PositionFromPartition(1)); + EXPECT_EQ(3, pp->PositionFromPartition(2)); + + EXPECT_EQ(0, pp->PartitionFromPosition(0)); + EXPECT_EQ(1, pp->PartitionFromPosition(1)); + EXPECT_EQ(1, pp->PartitionFromPosition(2)); + + EXPECT_EQ(1, pp->PartitionFromPosition(3)); +} + +TEST_F(PartitioningTest, DeletePartition) { + pp->InsertText(0, 2); + pp->InsertPartition(1, 1); + pp->RemovePartition(1); + EXPECT_EQ(1, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(0)); + EXPECT_EQ(2, pp->PositionFromPartition(1)); +} + +TEST_F(PartitioningTest, DeleteAll) { + pp->InsertText(0, 3); + pp->InsertPartition(1, 2); + pp->SetPartitionStartPosition(1,1); + pp->DeleteAll(); + // Back to initial state + EXPECT_EQ(1, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(pp->Partitions())); +} + +TEST_F(PartitioningTest, TestBackwards) { + pp->InsertText(0, 10); + pp->InsertPartition(1, 3); + pp->InsertPartition(2, 6); + pp->InsertPartition(3, 9); + pp->InsertText(2,4); + pp->InsertText(1,2); + pp->InsertText(0,3); + EXPECT_EQ(4, pp->Partitions()); + EXPECT_EQ(0, pp->PositionFromPartition(0)); + EXPECT_EQ(6, pp->PositionFromPartition(1)); + EXPECT_EQ(11, pp->PositionFromPartition(2)); + EXPECT_EQ(18, pp->PositionFromPartition(3)); + EXPECT_EQ(19, pp->PositionFromPartition(4)); +} + +TEST_F(PartitioningTest, TestMany) { + // Provoke backstep call + pp->InsertText(0, 42); + for (int i=0; i<20; i++) { + pp->InsertPartition(i+1, (i+1) * 2); + } + for (int i=20; i>0; i--) { + pp->InsertText(i,2); + } + EXPECT_EQ(21, pp->Partitions()); + for (int i=1; i<20; i++) { + EXPECT_EQ(i*4 - 2, pp->PositionFromPartition(i)); + EXPECT_EQ(i, pp->PartitionFromPosition(i*4 - 2)); + } + pp->InsertText(19,2); + EXPECT_EQ(3, pp->PartitionFromPosition(10)); + pp->InsertText(0,2); + pp->InsertText(0,-2); + pp->RemovePartition(1); + EXPECT_EQ(0, pp->PositionFromPartition(0)); + EXPECT_EQ(6, pp->PositionFromPartition(1)); + EXPECT_EQ(10, pp->PositionFromPartition(2)); + pp->RemovePartition(10); + EXPECT_EQ(46, pp->PositionFromPartition(10)); + EXPECT_EQ(10, pp->PartitionFromPosition(46)); + EXPECT_EQ(50, pp->PositionFromPartition(11)); + EXPECT_EQ(11, pp->PartitionFromPosition(50)); +} + +#if !PLAT_WIN +// Omit death tests on Windows where they trigger a system "unitTest.exe has stopped working" popup. +TEST_F(PartitioningTest, OutOfRangeDeathTest) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + pp->InsertText(0, 2); + pp->InsertPartition(1, 1); + EXPECT_EQ(2, pp->Partitions()); + ASSERT_DEATH(pp->PositionFromPartition(-1), "Assertion"); + ASSERT_DEATH(pp->PositionFromPartition(3), "Assertion"); +} +#endif diff --git a/test/unit/testRunStyles.cxx b/test/unit/testRunStyles.cxx new file mode 100644 index 000000000..d5bf1bb08 --- /dev/null +++ b/test/unit/testRunStyles.cxx @@ -0,0 +1,167 @@ +// Unit Tests for Scintilla internal data structures + +#include <string.h> + +#include "Platform.h" + +#include "SplitVector.h" +#include "Partitioning.h" +#include "RunStyles.h" + +#include <gtest/gtest.h> + +// Test RunStyles. + +class RunStylesTest : public ::testing::Test { +protected: + virtual void SetUp() { + prs = new RunStyles(); + } + + virtual void TearDown() { + delete prs; + prs = 0; + } + + RunStyles *prs; +}; + +TEST_F(RunStylesTest, IsEmptyInitially) { + EXPECT_EQ(0, prs->Length()); +} + +TEST_F(RunStylesTest, SimpleInsert) { + prs->InsertSpace(0, 1); + EXPECT_EQ(1, prs->Length()); + EXPECT_EQ(0, prs->ValueAt(0)); + EXPECT_EQ(1, prs->FindNextChange(0, prs->Length())); + EXPECT_EQ(2, prs->FindNextChange(1, prs->Length())); +} + +TEST_F(RunStylesTest, TwoRuns) { + prs->InsertSpace(0, 2); + EXPECT_EQ(2, prs->Length()); + prs->SetValueAt(0, 2); + EXPECT_EQ(2, prs->ValueAt(0)); + EXPECT_EQ(0, prs->ValueAt(1)); + EXPECT_EQ(1, prs->FindNextChange(0, prs->Length())); + EXPECT_EQ(2, prs->FindNextChange(1, prs->Length())); + EXPECT_EQ(3, prs->FindNextChange(2, prs->Length())); +} + +TEST_F(RunStylesTest, LongerRuns) { + prs->InsertSpace(0, 5); + prs->SetValueAt(0, 3); + prs->SetValueAt(1, 3); + EXPECT_EQ(3, prs->ValueAt(0)); + EXPECT_EQ(3, prs->ValueAt(1)); + EXPECT_EQ(0, prs->ValueAt(2)); + + EXPECT_EQ(0, prs->StartRun(0)); + EXPECT_EQ(2, prs->EndRun(0)); + + EXPECT_EQ(0, prs->StartRun(1)); + EXPECT_EQ(2, prs->EndRun(1)); + + EXPECT_EQ(2, prs->StartRun(2)); + EXPECT_EQ(5, prs->EndRun(2)); + + EXPECT_EQ(2, prs->StartRun(3)); + EXPECT_EQ(5, prs->EndRun(3)); + + EXPECT_EQ(2, prs->StartRun(4)); + EXPECT_EQ(5, prs->EndRun(4)); + + // At end + EXPECT_EQ(2, prs->StartRun(5)); + EXPECT_EQ(5, prs->EndRun(5)); + + // After end is same as end + EXPECT_EQ(2, prs->StartRun(6)); + EXPECT_EQ(5, prs->EndRun(6)); + + EXPECT_EQ(2, prs->FindNextChange(0, prs->Length())); + EXPECT_EQ(5, prs->FindNextChange(2, prs->Length())); + EXPECT_EQ(6, prs->FindNextChange(5, prs->Length())); +} + +TEST_F(RunStylesTest, FillRange) { + prs->InsertSpace(0, 5); + int startFill = 1; + int lengthFill = 3; + EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); + EXPECT_EQ(1, startFill); + EXPECT_EQ(3, lengthFill); + + EXPECT_EQ(0, prs->ValueAt(0)); + EXPECT_EQ(99, prs->ValueAt(1)); + EXPECT_EQ(99, prs->ValueAt(2)); + EXPECT_EQ(99, prs->ValueAt(3)); + EXPECT_EQ(0, prs->ValueAt(4)); + + EXPECT_EQ(0, prs->StartRun(0)); + EXPECT_EQ(1, prs->EndRun(0)); + + EXPECT_EQ(1, prs->StartRun(1)); + EXPECT_EQ(4, prs->EndRun(1)); +} + +TEST_F(RunStylesTest, FillRangeAlreadyFilled) { + prs->InsertSpace(0, 5); + int startFill = 1; + int lengthFill = 3; + EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); + EXPECT_EQ(1, startFill); + EXPECT_EQ(3, lengthFill); + + int startFill2 = 2; + int lengthFill2 = 1; + // Compiler warnings if 'false' used instead of '0' as expected value: + EXPECT_EQ(0, prs->FillRange(startFill2, 99, lengthFill2)); + EXPECT_EQ(2, startFill2); + EXPECT_EQ(1, lengthFill2); +} + +TEST_F(RunStylesTest, FillRangeAlreadyPartFilled) { + prs->InsertSpace(0, 5); + int startFill = 1; + int lengthFill = 2; + EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); + EXPECT_EQ(1, startFill); + EXPECT_EQ(2, lengthFill); + + int startFill2 = 2; + int lengthFill2 = 2; + EXPECT_EQ(true, prs->FillRange(startFill2, 99, lengthFill2)); + EXPECT_EQ(3, startFill2); + EXPECT_EQ(1, lengthFill2); +} + +TEST_F(RunStylesTest, DeleteRange) { + prs->InsertSpace(0, 5); + prs->SetValueAt(0, 3); + prs->SetValueAt(1, 3); + prs->DeleteRange(1, 1); + EXPECT_EQ(4, prs->Length()); + EXPECT_EQ(3, prs->ValueAt(0)); + EXPECT_EQ(0, prs->ValueAt(1)); + + EXPECT_EQ(0, prs->StartRun(0)); + EXPECT_EQ(1, prs->EndRun(0)); + + EXPECT_EQ(1, prs->StartRun(1)); + EXPECT_EQ(4, prs->EndRun(1)); + + EXPECT_EQ(1, prs->StartRun(2)); + EXPECT_EQ(4, prs->EndRun(2)); +} + +TEST_F(RunStylesTest, DeleteAll) { + prs->InsertSpace(0, 5); + prs->SetValueAt(0, 3); + prs->SetValueAt(1, 3); + prs->DeleteAll(); + EXPECT_EQ(0, prs->Length()); + EXPECT_EQ(0, prs->ValueAt(0)); +} + diff --git a/test/unit/testSplitVector.cxx b/test/unit/testSplitVector.cxx new file mode 100644 index 000000000..b5d9a1d36 --- /dev/null +++ b/test/unit/testSplitVector.cxx @@ -0,0 +1,220 @@ +// Unit Tests for Scintilla internal data structures + +#include <string.h> + +#include "Platform.h" + +#include "SplitVector.h" + +#include <gtest/gtest.h> + +// Test SplitVector. + +class SplitVectorTest : public ::testing::Test { +protected: + virtual void SetUp() { + psv = new SplitVector<int>; + } + + virtual void TearDown() { + delete psv; + psv = 0; + } + + SplitVector<int> *psv; +}; + +const int lengthTestArray = 4; +static const int testArray[4] = {3, 4, 5, 6}; + +TEST_F(SplitVectorTest, IsEmptyInitially) { + EXPECT_EQ(0, psv->Length()); +} + +TEST_F(SplitVectorTest, InsertOne) { + psv->InsertValue(0, 10, 0); + psv->Insert(5, 3); + EXPECT_EQ(11, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ((i == 5) ? 3 : 0, psv->ValueAt(i)); + } +} + +TEST_F(SplitVectorTest, Insertion) { + psv->InsertValue(0, 10, 0); + EXPECT_EQ(10, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ(0, psv->ValueAt(i)); + } +} + +TEST_F(SplitVectorTest, EnsureLength) { + psv->EnsureLength(4); + EXPECT_EQ(4, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ(0, psv->ValueAt(i)); + } +} + +TEST_F(SplitVectorTest, InsertFromArray) { + psv->InsertFromArray(0, testArray, 0, lengthTestArray); + EXPECT_EQ(lengthTestArray, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ(i+3, psv->ValueAt(i)); + } +} + +TEST_F(SplitVectorTest, SetValue) { + psv->InsertValue(0, 10, 0); + psv->SetValueAt(5, 3); + EXPECT_EQ(10, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ((i == 5) ? 3 : 0, psv->ValueAt(i)); + } + // Move the gap + psv->InsertValue(7, 1, 17); + EXPECT_EQ(17, psv->ValueAt(7)); + EXPECT_EQ(0, psv->ValueAt(8)); + // Set after the gap + psv->SetValueAt(8, 19); + EXPECT_EQ(19, psv->ValueAt(8)); +} + +TEST_F(SplitVectorTest, Indexing) { + psv->InsertValue(0, 10, 0); + psv->SetValueAt(5, 3); + EXPECT_EQ(10, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ((i == 5) ? 3 : 0, (*psv)[i]); + } +} + +TEST_F(SplitVectorTest, Fill) { + psv->InsertValue(0, 10, 0); + EXPECT_EQ(10, psv->Length()); + psv->InsertValue(7, 1, 1); + EXPECT_EQ(11, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ((i == 7) ? 1 : 0, psv->ValueAt(i)); + } +} + +TEST_F(SplitVectorTest, DeleteOne) { + psv->InsertFromArray(0, testArray, 0, lengthTestArray); + psv->Delete(2); + EXPECT_EQ(lengthTestArray-1, psv->Length()); + EXPECT_EQ(3, (*psv)[0]); + EXPECT_EQ(4, (*psv)[1]); + EXPECT_EQ(6, (*psv)[2]); +} + +TEST_F(SplitVectorTest, DeleteRange) { + psv->InsertValue(0, 10, 0); + EXPECT_EQ(10, psv->Length()); + psv->InsertValue(7, 1, 1); + EXPECT_EQ(11, psv->Length()); + psv->DeleteRange(2, 3); + EXPECT_EQ(8, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ((i == 4) ? 1 : 0, psv->ValueAt(i)); + } +} + +TEST_F(SplitVectorTest, DeleteAll) { + psv->InsertValue(0, 10, 0); + psv->InsertValue(7, 1, 1); + psv->DeleteRange(2, 3); + psv->DeleteAll(); + EXPECT_EQ(0, psv->Length()); +} + +TEST_F(SplitVectorTest, GetRange) { + psv->InsertValue(0, 10, 0); + psv->InsertValue(7, 1, 1); + int retrieveArray[11] = {0}; + psv->GetRange(retrieveArray, 0, 11); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ((i==7) ? 1 : 0, retrieveArray[i]); + } +} + +TEST_F(SplitVectorTest, GetRangeOverGap) { + psv->InsertFromArray(0, testArray, 0, lengthTestArray); + EXPECT_EQ(lengthTestArray, psv->Length()); + int retrieveArray[lengthTestArray] = {0}; + psv->GetRange(retrieveArray, 0, lengthTestArray); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ(i+3, retrieveArray[i]); + } +} + +TEST_F(SplitVectorTest, ReplaceUp) { + // Replace each element by inserting and then deleting the displaced element + // This should perform many moves + const int testLength=105; + psv->EnsureLength(testLength); + for (int i=0; i<testLength; i++) + psv->SetValueAt(i, i+2); + EXPECT_EQ(testLength, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + psv->InsertValue(i, 1, i+9); + psv->Delete(i+1); + } + for (int i=0; i<psv->Length(); i++) + EXPECT_EQ(i+9, psv->ValueAt(i)); +} + +TEST_F(SplitVectorTest, ReplaceDown) { + // From the end, replace each element by inserting and then deleting the displaced element + // This should perform many moves + const int testLength=24; + psv->EnsureLength(testLength); + for (int i=0; i<testLength; i++) + psv->SetValueAt(i, i+12); + EXPECT_EQ(testLength, psv->Length()); + for (int i=psv->Length()-1; i>=0; i--) { + psv->InsertValue(i, 1, i+5); + psv->Delete(i+1); + } + for (int i=0; i<psv->Length(); i++) + EXPECT_EQ(i+5, psv->ValueAt(i)); +} + +TEST_F(SplitVectorTest, BufferPointer) { + psv->InsertFromArray(0, testArray, 0, lengthTestArray); + int *retrievePointer = psv->BufferPointer(); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ(i+3, retrievePointer[i]); + } +} + +TEST_F(SplitVectorTest, DeleteBackAndForth) { + psv->InsertValue(0, 10, 87); + for (int i=0; i<10; i+=2) { + int len = 10 - i; + EXPECT_EQ(len, psv->Length()); + for (int i=0; i<psv->Length(); i++) { + EXPECT_EQ(87, psv->ValueAt(i)); + } + psv->Delete(len-1); + psv->Delete(0); + } +} + +TEST_F(SplitVectorTest, GrowSize) { + psv->SetGrowSize(5); + EXPECT_EQ(5, psv->GetGrowSize()); +} + +TEST_F(SplitVectorTest, OutsideBounds) { + psv->InsertValue(0, 10, 87); + EXPECT_EQ(0, psv->ValueAt(-1)); + EXPECT_EQ(0, psv->ValueAt(10)); + + /* Could be a death test as this asserts: + psv->SetValueAt(-1,98); + psv->SetValueAt(10,99); + EXPECT_EQ(0, psv->ValueAt(-1)); + EXPECT_EQ(0, psv->ValueAt(10)); + */ +} diff --git a/test/unit/unitTest.cxx b/test/unit/unitTest.cxx new file mode 100644 index 000000000..e1bb7bad2 --- /dev/null +++ b/test/unit/unitTest.cxx @@ -0,0 +1,50 @@ +// Unit Tests for Scintilla internal data structures + +/* + Currently tested: + SplitVector + Partitioning + ContractionState + + To do: + RunStyles + Decoration + DecorationList + PerLine * + CellBuffer * + Range + StyledText + CaseFolder ... + Document + RESearch + Selection + UniConversion + Style + + lexlib: + Accessor + LexAccessor + CharacterSet + OptionSet + PropSetSimple + StyleContext + WordList +*/ + +#include <stdio.h> + +#include "Platform.h" + +#include <gtest/gtest.h> + +// Needed for PLATFORM_ASSERT in code being tested + +void Platform::Assert(const char *c, const char *file, int line) { + fprintf(stderr, "Assertion [%s] failed at %s %d\n", c, file, line); + abort(); +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} |