1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/** @file testDocument.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 "ScintillaTypes.h"
#include "ILoader.h"
#include "ILexer.h"
#include "Debugging.h"
#include "CharacterCategoryMap.h"
#include "Position.h"
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "CellBuffer.h"
#include "CharClassify.h"
#include "Decoration.h"
#include "CaseFolder.h"
#include "Document.h"
#include "catch.hpp"
using namespace Scintilla;
using namespace Scintilla::Internal;
// Test Document.
struct DocPlus {
Document document;
DocPlus(std::string_view svInitial, int codePage) : document(DocumentOption::Default) {
document.SetDBCSCodePage(codePage);
if (codePage == CpUtf8) {
document.SetCaseFolder(std::make_unique<CaseFolderUnicode>());
} else {
// This case folder will not handle many DBCS cases. Scintilla uses platform-specific code for DBCS
// case folding which can not easily be inserted in platform-independent tests.
std::unique_ptr<CaseFolderTable> pcft = std::make_unique<CaseFolderTable>();
pcft->StandardASCII();
document.SetCaseFolder(std::move(pcft));
}
document.InsertString(0, svInitial.data(), svInitial.length());
}
};
TEST_CASE("Document") {
const char sText[] = "Scintilla";
const Sci::Position sLength = static_cast<Sci::Position>(strlen(sText));
SECTION("InsertOneLine") {
DocPlus doc("", 0);
const Sci::Position length = doc.document.InsertString(0, sText, sLength);
REQUIRE(sLength == doc.document.Length());
REQUIRE(length == sLength);
REQUIRE(1 == doc.document.LinesTotal());
REQUIRE(0 == doc.document.LineStart(0));
REQUIRE(0 == doc.document.LineFromPosition(0));
REQUIRE(sLength == doc.document.LineStart(1));
REQUIRE(0 == doc.document.LineFromPosition(static_cast<int>(sLength)));
REQUIRE(doc.document.CanUndo());
REQUIRE(!doc.document.CanRedo());
}
SECTION("SearchInUTF8") {
DocPlus doc("ab\xCE\x93" "d", CpUtf8); // a b gamma d
std::string finding = "b";
Sci::Position lengthFinding = finding.length();
Sci::Position location = doc.document.FindText(0, doc.document.Length(), finding.c_str(), FindOption::MatchCase, &lengthFinding);
REQUIRE(location == 1);
location = doc.document.FindText(doc.document.Length(), 0, finding.c_str(), FindOption::MatchCase, &lengthFinding);
REQUIRE(location == 1);
}
SECTION("SearchInShiftJIS") {
// {CJK UNIFIED IDEOGRAPH-9955} is two bytes: {0xE9, 'b'} in Shift-JIS
// The 'b' can be incorrectly matched by the search string 'b' when the search
// does not iterate the text correctly.
DocPlus doc("ab\xe9" "b ", 932); // a b {CJK UNIFIED IDEOGRAPH-9955} {space}
std::string finding = "b";
// Search forwards
Sci::Position lengthFinding = finding.length();
Sci::Position location = doc.document.FindText(0, doc.document.Length(), finding.c_str(), FindOption::MatchCase, &lengthFinding);
REQUIRE(location == 1);
// Search backwards
lengthFinding = finding.length();
location = doc.document.FindText(doc.document.Length(), 0, finding.c_str(), FindOption::MatchCase, &lengthFinding);
REQUIRE(location == 1);
}
SECTION("GetCharacterAndWidth") {
Document doc(DocumentOption::Default);
doc.SetDBCSCodePage(932);
REQUIRE(doc.CodePage() == 932);
const Sci::Position length = doc.InsertString(0, "\x84\xff=", 3);
REQUIRE(3 == length);
REQUIRE(3 == doc.Length());
Sci::Position width = 0;
int ch = doc.GetCharacterAndWidth(0, &width);
REQUIRE(width == 1);
REQUIRE(ch == 0x84);
width = 0;
ch = doc.GetCharacterAndWidth(1, &width);
REQUIRE(width == 1);
REQUIRE(ch == 0xff);
width = 0;
ch = doc.GetCharacterAndWidth(2, &width);
REQUIRE(width == 1);
REQUIRE(ch == '=');
}
SECTION("CheckTrailBytes") {
Document doc(DocumentOption::Default);
const int pages[] = { 932, 936, 949, 950, 1361 };
for (const int page : pages) {
doc.SetDBCSCodePage(page);
for (int byteVal = 0; byteVal < 0x100; byteVal++) {
char ch = static_cast<char>(byteVal);
REQUIRE(doc.IsDBCSTrailByteNoExcept(ch) != doc.IsDBCSTrailByteInvalid(ch));
}
}
}
}
|